Certbot + Nginx 签发 Let's Encrypt SSL 证书全过程记录
日期: 2026-08-11
服务器: 阿里云 CentOS
Nginx: 源码编译安装(v1.30.2),路径 /usr/local/nginx/
域名: domain-a.cn(已备案)、domain-b.com(备案中)
一、环境背景
- Nginx 为源码编译安装,非 yum 安装,二进制在
/usr/local/nginx/sbin/nginx,配置在/usr/local/nginx/conf/ - 站点配置放在
/usr/local/nginx/conf/vhost/*.conf - Certbot 通过 yum(EPEL 源)安装,版本 1.11.0
二、完整过程与错误记录
错误 1:nginx 插件缺失
现象:
Discovered plugins: PluginsRegistry(PluginEntryPoint#manual, PluginEntryPoint#null,
PluginEntryPoint#standalone, PluginEntryPoint#webroot)
No candidate plugin
Selected authenticator None and installer None
原因: yum 安装的 certbot 没有附带 nginx 插件。
解决:
sudo yum install -y epel-release
sudo yum install -y python3-certbot-nginx
错误 2:pip 安装 certbot 时 cryptography 编译失败
现象:
Command "python setup.py egg_info" failed with error code 1
in /tmp/pip-build-ffjky510/cryptography/
原因: 缺少编译依赖,且 pip/setuptools 版本过旧(CentOS 7 Python 3.6)。
解决:
sudo yum install -y gcc openssl-devel libffi-devel python3-devel
sudo pip3 install --upgrade pip setuptools wheel
sudo pip3 install certbot certbot-nginx
备注:最终未采用 pip 方式,改用 yum 安装 EPEL 源的
python3-certbot-nginx包。
错误 3:snap 安装 certbot 失败
现象:
error: too early for operation, device not yet seeded or device model not acknowledged
原因: CentOS 上 snapd 初始化未完成。
尝试:
sudo systemctl restart snapd
sudo systemctl restart snapd.seeded
sleep 5
snap changes
备注:snap 在 CentOS 上兼容性不佳,最终放弃 snap,回退到 yum 安装方式。
错误 4:certbot 找不到 nginx 二进制
现象:
NoInstallationError("Could not find a usable 'nginx' binary. Ensure nginx exists,
the binary is executable, and your PATH is set correctly.")
原因: Nginx 源码编译安装在 /usr/local/nginx/sbin/nginx,不在系统 PATH 中。
解决:
sudo ln -sf /usr/local/nginx/sbin/nginx /usr/sbin/nginx
错误 5:certbot 找不到 nginx 配置文件
现象:
nginx: [emerg] open() "/etc/nginx/nginx.conf" failed (2: No such file or directory)
nginx: configuration file /etc/nginx/nginx.conf test failed
原因: certbot 默认在 /etc/nginx/ 下查找配置,而实际配置在 /usr/local/nginx/conf/。
解决:
sudo ln -sf /usr/local/nginx/conf /etc/nginx
错误 6:ACME 验证返回 403(nginx 配置拦截)
现象:
Detail: xx.xx.xx.xx: Invalid response from
http://domain-b.com/.well-known/acme-challenge/xxx: 403
原因: nginx vhost 配置中有以下安全规则:
location ~ /\. {
deny all;
}
该正则 ~ /\. 匹配所有 / 后以 . 开头的路径,包括 /.well-known/acme-challenge/,导致验证请求被 403 拒绝。
解决:
# 删除拦截规则
sed -i '/location ~ \/\\\. {/,/}/d' /usr/local/nginx/conf/vhost/voxtalkbox.conf
# 重载 nginx
/usr/local/nginx/sbin/nginx -t && /usr/local/nginx/sbin/nginx -s reload
签发完成后,改用排除 .well-known 的写法加回去:
location ~ /\.(?!well-known) {
deny all;
access_log off;
log_not_found off;
}
错误 7:ACME 验证仍然 403(域名未备案)
现象: 删除 nginx 拦截规则后,domain-b.com 仍然返回 403。
原因: 域名 domain-b.com 尚未完成 ICP 备案,阿里云会拦截未备案域名通过 80/443 端口的 HTTP 请求。Let's Encrypt 的 HTTP-01 验证无法通过。
解决:
- 方案 A(推荐):等备案通过后再用
certbot --nginx签发 - 方案 B:改用 DNS-01 验证(不依赖 HTTP 访问):
certbot certonly --manual --preferred-challenges dns -d domain-b.com -d www.domain-b.com执行后手动添加 TXT 记录到 DNS 解析,验证通过即可签发。
成功:domain-a.cn 证书签发
domain-a.cn 已完成备案,80 端口可正常访问,直接执行:
certbot --nginx -d domain-a.cn -d www.domain-a.cn
输出:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/domain-a.cn/fullchain.pem
Key is saved at: /etc/letsencrypt/live/domain-a.cn/privkey.pem
This certificate expires on 2026-11-09.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
Successfully deployed certificate for domain-a.cn to /usr/local/nginx/conf/vhost/domain-a.cn.conf
Successfully deployed certificate for www.domain-a.cn to /usr/local/nginx/conf/vhost/domain-a.cn.conf
重载 nginx 生效:
/usr/local/nginx/sbin/nginx -t && /usr/local/nginx/sbin/nginx -s reload
三、自动续期配置
Certbot 已自动配置定时续期任务。由于 nginx 为源码编译安装,需确保续期后自动重载 nginx:
# 验证自动续期
certbot renew --dry-run
# 添加续期后重载 nginx 的 hook
# 编辑 /etc/letsencrypt/renewal/domain-a.cn.conf,在 [renewalparams] 下添加:
# renew_hook = /usr/local/nginx/sbin/nginx -s reload
四、新增二级域名签发证书
方式一:扩展现有证书(推荐)
certbot --nginx -d domain-a.cn -d www.domain-a.cn -d 新域名.domain-a.cn
选择 expand (E),将新域名加入已有证书。
方式二:单独签发
certbot --nginx -d 新域名.domain-a.cn
前提条件:
- 新域名 DNS 已解析到服务器 IP
- nginx vhost 已配置该域名的 server 块
- 域名已完成 ICP 备案,80 端口可正常访问
五、关键经验总结
| 序号 | 问题 | 根因 | 解决方案 |
|---|---|---|---|
| 1 | nginx 插件缺失 | yum 未装插件 | yum install python3-certbot-nginx |
| 2 | cryptography 编译失败 | 缺编译依赖 | 装 gcc/openssl-devel/libffi-devel/python3-devel |
| 3 | snap 初始化失败 | CentOS snapd 兼容性差 | 放弃 snap,用 yum |
| 4 | 找不到 nginx 二进制 | 源码安装不在 PATH | ln -sf /usr/local/nginx/sbin/nginx /usr/sbin/nginx |
| 5 | 找不到 nginx 配置 | 配置路径非标准 | ln -sf /usr/local/nginx/conf /etc/nginx |
| 6 | ACME 验证 403 | location ~ /\. 拦截 .well-known | 删除或改用 ~ /\.(?!well-known) |
| 7 | ACME 验证仍 403 | 域名未备案,云厂商拦截 | 等 DNS-01 验证或等备案通过 |