强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

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 [email protected] \
  --non-interactive

申请多域名证书

sudo certbot certonly --standalone \
  -d example.com \
  -d www.example.com \
  -d api.example.com \
  --agree-tos \
  --email [email protected] \
  --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 [email protected]
--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 [email protected]

# 测试成功后,删除 staging 证书
sudo certbot delete --cert-name example.com

# 再使用 production 环境正式申请
sudo certbot certonly --standalone \
  -d example.com \
  --agree-tos \
  --email [email protected]

验证 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="[email protected]"

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 最佳实践

  1. 首次使用 staging: 先用 --staging 测试,确认无误后再正式申请
  2. 配合 pre/post-hook: 使用 --pre-hook--post-hook 自动管理 Web 服务器
  3. 不要长时间占用 80 端口: Standalone 服务器仅在验证期间运行,不需要长期运行
  4. 记录申请日志: 保留 /var/log/letsencrypt/letsencrypt.log 便于排错
  5. dry-run 测试续期: 定期使用 --dry-run 测试续期是否正常
# 测试续期是否正常
sudo certbot renew --dry-run

注意事项

  1. 端口 80 必须可达: Standalone 模式依赖 80 端口接收 Let’s Encrypt 的验证请求
  2. 验证期间有短暂停机: 如果已有 Web 服务器运行在 80 端口,需要临时停止
  3. 不适合 CDN 后端: 如果站点在 CDN 后面,验证请求可能到达 CDN 而非你的服务器
  4. IPv6 支持: Certbot 默认同时监听 IPv4 和 IPv6,确保两者都可达

扩展阅读