Certbot 证书自动化教程 / 第 3 章:Standalone 模式
第 3 章:Standalone 模式
3.1 Standalone 模式概述
Standalone(独立)模式是 Certbot 最简单的验证方式。Certbot 自身启动一个临时的 HTTP 服务器监听 80 端口,用于完成 ACME HTTP-01 验证挑战。
工作原理
┌───────────────────────┐
│ Certbot 进程 │
│ │
│ 临时 HTTP 服务器 │
│ (监听 80 端口) │
│ │
│ /.well-known/ │
│ acme-challenge/ │
│ └── <token> │
└───────────┬───────────┘
│
│ Let's Encrypt 服务器请求验证
│ GET http://example.com/.well-known/acme-challenge/<token>
│
▼
验证通过 → 签发证书
适用场景
| 场景 | 是否适合 | 原因 |
|---|---|---|
| 首次申请证书 | ✅ 非常适合 | 无需现有 Web 服务器 |
| 服务器尚未部署 | ✅ 非常适合 | Certbot 自带 HTTP 服务器 |
| Nginx/Apache 未运行 | ✅ 适合 | 不依赖现有服务 |
| Nginx/Apache 正在运行 | ❌ 不适合 | 80 端口冲突 |
| 防火墙封锁 80 端口 | ❌ 不适合 | 无法接收验证请求 |
3.2 基本使用
前提条件
# 确认 80 端口未被占用
sudo ss -tlnp | grep :80
# 如果 Nginx 或 Apache 正在运行,需要先停止
sudo systemctl stop nginx
# 或
sudo systemctl stop apache2
# 确认防火墙允许 80 端口
sudo ufw allow 80/tcp
申请单域名证书
sudo certbot certonly --standalone \
-d example.com \
--agree-tos \
--email admin@example.com \
--non-interactive
申请多域名证书
sudo certbot certonly --standalone \
-d example.com \
-d www.example.com \
-d api.example.com \
--agree-tos \
--email admin@example.com \
--non-interactive
交互式申请
# 不加 --non-interactive 参数,Certbot 会交互式引导
sudo certbot certonly --standalone
# 运行后会提示:
# 1. 输入邮箱地址
# 2. 同意服务条款
# 3. 选择要申请证书的域名
# 4. 输入域名(如 example.com)
命令参数详解
| 参数 | 说明 | 示例 |
|---|---|---|
certonly | 仅获取证书,不安装 | - |
--standalone | 使用独立模式 | - |
-d | 指定域名 | -d example.com |
--agree-tos | 同意服务条款 | - |
--email | 注册邮箱 | --email admin@example.com |
--non-interactive | 非交互模式 | - |
--staging | 使用测试环境 | - |
--http-01-port | 指定监听端口 | --http-01-port 8080 |
--dry-run | 模拟运行(不实际申请) | - |
3.3 端口配置
默认端口
Standalone 模式默认使用 80 端口。这是 Let’s Encrypt HTTP-01 验证的标准端口。
自定义端口(不推荐)
# 使用非标准端口(需要在服务器前端做端口转发)
sudo certbot certonly --standalone \
-d example.com \
--http-01-port 8080
警告: Let’s Encrypt 服务器始终向 80 端口发起验证请求。使用非标准端口时,需要在前端路由器或负载均衡器上配置端口转发(80 → 8080),否则验证会失败。
端口冲突处理
# 查看占用 80 端口的进程
sudo lsof -i :80
# 或者
sudo ss -tlnp | grep :80
# 常见的 80 端口占用者
# - nginx
# - apache2 / httpd
# - caddy
# - 其他 web 服务
临时停止 Nginx/Apache
# 临时停止 Nginx
sudo systemctl stop nginx
# 申请证书
sudo certbot certonly --standalone -d example.com
# 申请完成后重启 Nginx
sudo systemctl start nginx
使用 Hook 自动处理
# 使用 pre-hook 和 post-hook 自动停止/启动 Web 服务器
sudo certbot certonly --standalone \
-d example.com \
--pre-hook "systemctl stop nginx" \
--post-hook "systemctl start nginx"
3.4 高级用法
指定证书存储路径
# 使用 --cert-path 指定输出路径
sudo certbot certonly --standalone \
-d example.com \
--cert-path /etc/ssl/certs/example.com.crt \
--key-path /etc/ssl/private/example.com.key \
--fullchain-path /etc/ssl/certs/example.com.fullchain.pem \
--chain-path /etc/ssl/certs/example.com.chain.pem
使用 RSA 密钥
# 默认使用 EC 密钥,如需 RSA 密钥
sudo certbot certonly --standalone \
-d example.com \
--key-type rsa \
--rsa-key-size 4096
使用 EC 密钥
# 使用 ECDSA 密钥(默认,推荐)
sudo certbot certonly --standalone \
-d example.com \
--key-type ecdsa \
--elliptic-curve secp384r1
Dry Run 测试
# 模拟申请,不实际签发证书
sudo certbot certonly --standalone \
-d example.com \
--dry-run
# 输出示例:
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Processing /etc/letsencrypt/renewal/example.com.conf
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Simulating a certificate request for example.com
# The dry run was successful.
提示: 在生产环境申请证书前,务必先使用
--dry-run测试,避免消耗速率限制。
3.5 使用 Staging 环境
# 使用 staging 环境测试
sudo certbot certonly --standalone \
--staging \
-d example.com \
--agree-tos \
--email admin@example.com
# 测试成功后,删除 staging 证书
sudo certbot delete --cert-name example.com
# 再使用 production 环境正式申请
sudo certbot certonly --standalone \
-d example.com \
--agree-tos \
--email admin@example.com
验证 staging 证书
# 查看 staging 证书
sudo certbot certificates --cert-name example.com
# staging 证书的签发者通常是:
# "Fake LE Intermediate X1" 或类似名称
3.6 证书申请完整流程示例
场景:为新服务器首次申请证书
#!/bin/bash
# file: request-cert.sh
# 描述:Standalone 模式申请证书的完整流程
DOMAIN="example.com"
EMAIL="admin@example.com"
echo "=== Step 1: 环境检查 ==="
# 检查 80 端口
if ss -tlnp | grep -q ":80 "; then
echo "错误: 80 端口已被占用"
ss -tlnp | grep ":80 "
exit 1
fi
# 检查域名解析
RESOLVED_IP=$(dig +short "$DOMAIN" A | head -1)
SERVER_IP=$(curl -s ifconfig.me)
if [ "$RESOLVED_IP" != "$SERVER_IP" ]; then
echo "警告: 域名 $DOMAIN 解析到 $RESOLVED_IP,本机 IP 为 $SERVER_IP"
read -p "是否继续? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
echo "=== Step 2: 申请证书 ==="
sudo certbot certonly --standalone \
-d "$DOMAIN" \
--agree-tos \
--email "$EMAIL" \
--non-interactive
if [ $? -eq 0 ]; then
echo "=== 证书申请成功 ==="
sudo certbot certificates --cert-name "$DOMAIN"
else
echo "=== 证书申请失败 ==="
echo "查看日志: /var/log/letsencrypt/letsencrypt.log"
exit 1
fi
3.7 验证过程排错
常见错误及解决方案
错误 1:端口占用
Problem binding to port 80: Could not bind to IPv4 or IPv6.
解决方案:
# 找到占用 80 端口的进程
sudo lsof -i :80
# 停止该进程
sudo systemctl stop nginx
错误 2:防火墙阻止
Timeout during connect (likely firewall problem).
解决方案:
# 检查防火墙规则
sudo ufw status
# 允许 80 端口
sudo ufw allow 80/tcp
错误 3:域名解析不正确
DNS problem: NXDOMAIN looking up A for example.com
解决方案:
# 检查域名解析
dig +short example.com A
# 确认域名已正确指向服务器 IP
错误 4:速率限制
Too many certificates already issued for example.com
解决方案:
# 使用 --staging 测试
sudo certbot certonly --standalone --staging -d example.com
# 等待限制重置(通常一周)
3.8 Standalone 与其他模式对比
| 特性 | Standalone | Webroot | Nginx 插件 | DNS 验证 |
|---|---|---|---|---|
| 需要 80 端口 | ✅ | ✅ | ✅ | ❌ |
| 需要 Web 服务器 | ❌ | ✅ | ✅ | ❌ |
| 停机时间 | 短暂 | 无 | 无 | 无 |
| 通配符支持 | ❌ | ❌ | ❌ | ✅ |
| 自动配置服务器 | ❌ | ❌ | ✅ | ❌ |
| 复杂度 | 低 | 中 | 低 | 高 |
| 适用场景 | 首次申请 | 已有 Web 服务器 | Nginx 用户 | 通配符 |
3.9 最佳实践
- 首次使用 staging: 先用
--staging测试,确认无误后再正式申请 - 配合 pre/post-hook: 使用
--pre-hook和--post-hook自动管理 Web 服务器 - 不要长时间占用 80 端口: Standalone 服务器仅在验证期间运行,不需要长期运行
- 记录申请日志: 保留
/var/log/letsencrypt/letsencrypt.log便于排错 - dry-run 测试续期: 定期使用
--dry-run测试续期是否正常
# 测试续期是否正常
sudo certbot renew --dry-run
注意事项
- 端口 80 必须可达: Standalone 模式依赖 80 端口接收 Let’s Encrypt 的验证请求
- 验证期间有短暂停机: 如果已有 Web 服务器运行在 80 端口,需要临时停止
- 不适合 CDN 后端: 如果站点在 CDN 后面,验证请求可能到达 CDN 而非你的服务器
- IPv6 支持: Certbot 默认同时监听 IPv4 和 IPv6,确保两者都可达