使用 Certbot 为 Nginx 自动申请 HTTPS 证书并配置自动续签

1. 适用场景

本文适用于以下部署环境:

复制代码
Linux 服务器
Nginx
Django / Java / Node.js 等后端服务
域名已解析到服务器

示例域名统一使用:

复制代码
domain.com
www.domain.com

如果需要通配符域名部署证书,如*.domain.com,建议使用acme.sh,详细步骤参考acme自动续签


2. 申请证书前的检查

2.1 确认域名解析正确

复制代码
dig domain.com +short
dig www.domain.com +short
curl -4 ifconfig.me

如果三个结果都是同一个服务器公网 IP,说明域名解析正常。


2.2 确认 Nginx 配置正常

复制代码
nginx -t

如果 Nginx 配置本身有错误,Certbot 会失败。


2.3 确认 80 和 443 端口已放行

本机防火墙放行:

复制代码
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

如果是云服务器,还需要在云平台安全组中放行:

复制代码
TCP 80
TCP 443

3. 安装 Certbot

CentOS / RHEL 系统:

复制代码
dnf install -y epel-release
dnf install -y certbot python3-certbot-nginx

查看版本:

复制代码
certbot --version

4. 自动申请证书并配置 Nginx

执行:

复制代码
sudo certbot --nginx -d domain.com -d www.domain.com

过程中会要求输入邮箱、同意协议:

复制代码
Enter email address: 输入邮箱
Do you agree? Y
Share email with EFF? N

成功后,Certbot 会自动在 Nginx 配置中加入 HTTPS 证书配置,例如:

复制代码
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;

并自动配置 HTTP 跳转 HTTPS。

5. Nginx 配置示例

以 Django + uWSGI 为例:

复制代码
server {
    listen 443 ssl;
    server_name domain.com www.domain.com;

    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location /static/ {
        alias /home/project/static/;
    }

    location /media/ {
        alias /home/project/media/;
    }

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/run/uwsgi/project.sock;
    }
}

server {
    listen 80;
    server_name domain.com www.domain.com;
    return 301 https://$host$request_uri;
}

修改后检查并重载 Nginx:

复制代码
nginx -t
systemctl reload nginx

6. 查看证书状态

复制代码
certbot certificates

可以看到证书域名、到期时间、证书路径等信息。


7. 测试 HTTPS 是否生效

复制代码
curl -I http://domain.com
curl -I https://domain.com
curl -I https://www.domain.com

正常情况下:

复制代码
http://domain.com 会跳转到 https://domain.com
https://domain.com 可以正常访问

8. 自动续签

Certbot 默认会配置自动续签任务。可以用下面命令测试:

复制代码
sudo certbot renew --dry-run

如果显示成功,说明自动续签流程正常。

查看系统定时任务:

复制代码
systemctl list-timers | grep certbot

如果希望证书续签后自动重新加载 Nginx,可以添加 hook:

复制代码
mkdir -p /etc/letsencrypt/renewal-hooks/deploy
vim /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

写入:

复制代码
#!/bin/bash
systemctl reload nginx

赋予执行权限:

复制代码
chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

9. 常见问题

9.1 Nginx 报证书文件不存在

错误类似:

复制代码
No such file or directory: /etc/letsencrypt/live/domain.com/fullchain.pem

原因是 Nginx 配置里提前写了证书路径,但证书还没有申请成功。

处理方法:先注释掉 HTTPS 证书配置,只保留 80 端口配置,等证书申请成功后再加回去。


9.2 Certbot 验证超时

错误类似:

复制代码
Timeout during connect

一般是以下原因:

复制代码
域名没有解析到当前服务器
80 端口没有放行
Nginx 没有监听 80 端口
云服务器安全组没有放行 80

排查:

复制代码
dig domain.com +short
curl -4 ifconfig.me
ss -lntp | grep ':80'
nginx -t

9.3 Certbot Python 依赖错误

如果出现类似:

复制代码
AttributeError: module 'lib' has no attribute 'X509_get_notAfter'

通常是系统 Certbot 和 pip 安装的 Python 依赖冲突。

可以检查:

复制代码
rpm -qa | grep -E "certbot|pyOpenSSL|cryptography"
python3 -m pip show pyOpenSSL cryptography certbot

如果发现 pyOpenSSL 或 cryptography 来自 /usr/local/,建议卸载 pip 全局包:

复制代码
python3 -m pip uninstall -y pyOpenSSL cryptography

然后重新安装系统包:

复制代码
dnf reinstall -y python3-pyOpenSSL python3-cryptography certbot python3-certbot python3-certbot-nginx

10. 总结

常用流程如下:

复制代码
dig domain.com +short
dig www.domain.com +short
nginx -t
sudo certbot --nginx -d domain.com -d www.domain.com
certbot certificates
sudo certbot renew --dry-run
systemctl reload nginx

简单来说:

复制代码
先确认域名解析和 80 端口正常
再用 Certbot 申请证书
申请成功后检查 HTTPS
最后测试自动续签

对于普通网站,直接使用:

复制代码
sudo certbot --nginx -d domain.com -d www.domain.com

即可完成证书申请、Nginx 配置和后续自动续签。

相关推荐
虎头金猫6 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
还是大剑师兰特6 天前
解决nginx错误:http://localhost:7000正常,http://localhost:7000/map 报错404
nginx·大剑师
AI职业加油站6 天前
AI智能体应用工程师证书:政策红利下的职业新风口
大数据·运维·人工智能·学习·职场发展
此冬歌咏6 天前
K8s 节点故障实战:优雅驱逐 31 秒,硬故障 331 秒,以及那个永远 Pending 的 Pod
运维·k8s
xing-xing6 天前
Docker容器中Nginx站点根目录网页配置访问
nginx·docker
-梅6 天前
linux(8) 软硬链接
linux·运维·服务器
张洛闻Eren6 天前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github
其实防守也摸鱼6 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
布裘6 天前
【银河麒麟】V4桌面图标消失,右击鼠标没反应排查
运维·银河麒麟·桌面环境
懂软件的胡子个哥6 天前
微信机器人为什么需要“回复候选”而不是所有 AI 内容直接发送
运维·微信·自动化·wechatapi·个人微信号二次开发