
背景服务器上的域名证书过期了用certbot certificates一查发现是 Let’s Encrypt 签发的免费证书。本来以为一条certbot renew就能搞定结果接连踩了三个坑端口被 Nginx 占用、子域名 DNS 记录已删除、旧版 Certbot 不支持reconfigure命令。这篇文章完整记录了排查过程和最终方案希望能帮到遇到类似问题的朋友。环境说明系统Ubuntu腾讯云轻量服务器Web 服务Nginx部分站点通过 Docker 部署证书工具Certbot版本较旧0.40.0 左右证书域名xxx.com、www.xxx.com、rsvp.xxx.com均已脱敏第一步确认证书状态sudocertbot certificates输出显示有两张证书Certificate Name: hagent.xxx.com Expiry Date: 2026-12-07 (VALID: 48 days) Certificate Name: mytools.xxx.com Domains: mytools.xxx.com rsvp.xxx.com www.xxx.com Expiry Date: 2026-10-14 (INVALID: EXPIRED)问题定位在mytools.xxx.com这张证书已经过期。另外输出里有一行警告Cannot extract OCSP URI from /etc/letsencrypt/live/.../cert.pem这个警告可以忽略。Let’s Encrypt 正在逐步淘汰 OCSP 功能新证书不再包含 OCSP 地址Certbot 读不到就会报这个提示不影响签发和续期。第二步首次续期失败——80 端口被占用直接执行强制续期sudocertbot renew --cert-name mytools.xxx.com --force-renewal报错Plugins selected: Authenticator standalone, Installer None Problem binding to port 80: Could not bind to IPv4 or IPv6.原因当初申请证书时用的是standalone模式续期时 Certbot 需要自己临时占用 80 端口来响应 HTTP-01 验证。但服务器上 Nginx 正占着 80 端口Certbot 绑不上续期失败。第三步停 Nginx 仍失败——进程没真正停掉尝试停掉 Nginx 再续期sudosystemctl stop nginxsudocertbot renew --cert-name mytools.xxx.com --force-renewal依然报同样的端口占用错误。再启动 Nginx 时还报了Job for nginx.service failed because the control process exited with error code.用ss查端口占用sudoss-tlnp|grep:80发现 Nginx 进程其实还在LISTEN 0 511 0.0.0.0:80 users:((nginx,pid1152155,...),(nginx,pid1152154,...))原因systemd 状态和实际进程不一致systemctl stop没有真正杀掉 Nginx 进程。解决办法是直接对 PID 下手sudokill-9115215511521541151819再次确认端口已释放sudoss-tlnp|grep:80这次没有输出8099 和 8080 是 Docker 的端口不影响 80。端口释放后证书续期命令终于能往下走了。第四步续期再次失败——子域名 DNS 记录已删除端口问题解决后重新续期这次报错变了Challenge failed for domain rsvp.xxx.com Type: dns Detail: DNS problem: NXDOMAIN looking up A for rsvp.xxx.com原因rsvp.xxx.com这个子域名的 DNS 记录已经被删除Let’s Encrypt 无法解析到 IP验证自然失败。这里有两个选择补上 DNS 记录继续保留这个域名如果域名已经不用了从证书里剔除。本例中rsvp.xxx.com已经不再使用选择方案 2。第五步剔除无效域名重新签发证书先停 Nginx 释放 80 端口sudosystemctl stop nginxsudoss-tlnp|grep:80# 确认无输出然后用certonly重新签发只保留有效域名sudocertbot certonly--standalone--force-renewal\--cert-name mytools.xxx.com\-dmytools.xxx.com-dwww.xxx.comCertbot 会提示确认要移除rsvp.xxx.comYou are also removing previously included domain(s): - rsvp.xxx.com Did you intend to make this change? (U)pdate cert/(C)ancel:选U继续。签发成功后Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/mytools.xxx.com/fullchain.pem Your cert will expire on 2027-01-18.启动 Nginxsudosystemctl reset-failed nginxsudosystemctl start nginxsudosystemctl status nginx --no-pager确认active (running)后用certbot certificates复查域名列表只剩mytools.xxx.com和www.xxx.com状态VALID。第六步配置自动续期避免下次再踩坑证书续上了但如果自动续期还是用standalone模式下次定时任务触发时 Nginx 正占着 80 端口大概率会重蹈覆辙。所以要把续期方式改成Nginx 插件验证让 Certbot 通过正在运行的 Nginx 完成验证不再抢端口。1. 安装 Nginx 插件sudoaptinstallpython3-certbot-nginx-y2. 尝试reconfigure旧版本会失败sudocertbot reconfigure --cert-name mytools.xxx.com--authenticatornginx如果报错unrecognized arguments: reconfigure说明 Certbot 版本低于 2.3.0不支持这个子命令。改用下面的方式。3. 用certonly --nginx重新签发sudocertbot certonly--nginx\--cert-name mytools.xxx.com\-dmytools.xxx.com-dwww.xxx.com过程中选择2: Renew replace the cert。完成后检查续期配置sudogrepauthenticator /etc/letsencrypt/renewal/mytools.xxx.com.conf输出authenticator nginx就说明改成功了。4. 模拟测试自动续期sudocertbot renew --dry-run --cert-name mytools.xxx.com输出里出现new certificate deployed with reload of nginx server Congratulations, all renewals succeeded.说明续期流程完全正常而且续期成功后 Certbot 会自动 reload Nginx新证书自动生效。5. 确认定时器在运行systemctl list-timers|grepcertbot看到certbot.timer处于活跃状态即可。如果没有手动启用sudosystemctlenable--nowcertbot.timer关键经验总结standalone模式和 Nginx 抢 80 端口是续期失败的常见原因。长期方案是改用--nginx插件或webroot模式让 Certbot 借助现有 Web 服务完成验证。systemctl stop不一定真能停掉进程。遇到端口仍被占用时用ss -tlnp | grep :80查实际 PID必要时直接kill -9。证书里的域名必须都有有效 DNS 记录。过期或删除的子域名会导致整个证书续期失败及时从证书中剔除。旧版 Certbot 不支持reconfigure。用certonly --nginx重新签发同样能达到修改验证方式的目的。Cannot extract OCSP URI警告可以忽略是 Let’s Encrypt 淘汰 OCSP 后的正常现象。配置完成后一定要跑--dry-run模拟续期通过才算真正配好自动续期。附常用排查命令速查# 查看所有证书及状态sudocertbot certificates# 查看 80 端口占用sudoss-tlnp|grep:80# 查看某张证书的续期配置sudogrepauthenticator /etc/letsencrypt/renewal/证书名.conf# 模拟续期测试sudocertbot renew --dry-run --cert-name证书名# 查看 Certbot 定时器systemctl list-timers|grepcertbot