如何为基于nginx的web站点申请免费的 Let's Encrypt 证书?如何续签证书?

作为 Nginx 管理员,为站点申请和续签 Let's Encrypt 证书最标准、最自动化的方式是使用 Certbot 工具。它不仅能自动申请证书,还能自动修改 Nginx 配置文件并设置定时任务进行续签。

以下是基于 Ubuntu/Debian 和 CentOS/RHEL 系统的完整操作指南。

第一阶段:申请证书

1,前置准备

在开始之前,请确保:

  • 域名解析正确:你的域名(例如 bandianxiang.com)必须已经解析到当前服务器的公网 IP。

  • 端口开放:服务器的防火墙(如 ufw, firewalld 或云服务商的安全组)必须开放 80 端口 (HTTP),因为 Let's Encrypt 需要通过 HTTP 配置来验证域名所有权。

  • Nginx 已运行:Nginx 服务必须正在运行,且配置了该域名的 server_name。

  • 如果要为 bandianxiang.comwww.bandianxiang.com 申请证书,请确保DNS中已经配置了 @ 和 www 的A记录。

2,安装 Certbot 及 Nginx 插件

Ubuntu / Debian 系统:

sudo apt update
sudo apt install certbot python3-certbot-nginx -y

CentOS / RHEL / Rocky Linux 系统:

# 启用 EPEL 源 (如果尚未启用)
sudo yum install epel-release -y

# 安装 certbot 和 nginx 插件
sudo yum install certbot python3-certbot-nginx -y

3,执行自动申请命令

这是最简单的方法,Certbot 会自动扫描你的 Nginx 配置,识别域名,修改配置文件以添加 SSL 支持,并重新加载 Nginx。

# 将 yourdomain.com 替换为你的实际域名
# 如果需要多个域名(如带 www),用 -d 指定多次,如:-d bandianxiang.com -d www.bandianxiang.com
sudo certbot --nginx -d bandianxiang.com -d www.bandianxiang.com

交互过程说明:

1,输入邮箱:用于接收证书过期警告(重要)。

2,同意服务条款:输入 A 或 Y。

3,是否共享邮箱给 EFF:选 Y 或 N 均可。

4,重定向选项:Certbot 会询问是否将 HTTP 流量重定向到 HTTPS。

  • 选择 1 (No redirect):仅开启 HTTPS,HTTP 保持不变。

  • 选择 2 (Redirect):推荐。自动配置 Nginx,将所有 HTTP 请求 301 重定向到 HTTPS。

4,验证结果

命令执行成功后,你会看到类似 Congratulations! 的提示。

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for bandianxiang.com and www.bandianxiang.com

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/bandianxiang.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/bandianxiang.com/privkey.pem
This certificate expires on 2026-06-05.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

Deploying certificate
Successfully deployed certificate for bandianxiang.com to /etc/nginx/conf.d/bandianxiang.conf
Successfully deployed certificate for www.bandianxiang.com to /etc/nginx/conf.d/bandianxiang.conf
Congratulations! You have successfully enabled HTTPS on https://bandianxiang.com and https://www.bandianxiang.com
  • 检查配置文件:Certbot 通常会在 /etc/nginx/sites-enabled/ 或 /etc/nginx/conf.d/ 下生成或修改对应的 .conf 文件,添加了 ssl_certificate 和 ssl_certificate_key 路径。

  • 测试 Nginx 配置:

sudo nginx -t

重载 Nginx(如果 Certbot 没有自动完成):

sudo systemctl reload nginx

浏览器访问:访问 https://bandianxiang.com,查看锁形图标是否正常。

第二阶段:证书续签 (Renew)

Let's Encrypt 证书的有效期仅为 90 天。为了安全,建议每 60 天自动续签一次。Certbot 在安装时通常会自动创建一个 systemd timer 或 cron job 来处理此事。

1,手动测试续签

在部署自动任务前,先手动运行一次续签命令进行测试(使用 --dry-run 模拟运行,不会消耗限额):

sudo certbot renew --dry-run

如果输出 Congratulations, all renewals succeeded,说明自动续签机制正常。

Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/bandianxiang.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Account registered.
Simulating renewal of an existing certificate for bandianxiang.com and www.bandianxiang.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/bandianxiang.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

如果去掉 --dry-run 直接运行 sudo certbot renew,它会检查所有即将过期(<30天)的证书并进行更新。如果证书还没到期,直接运行此命令通常不会做任何事。

2,确认自动续签任务已启用

对于 Ubuntu 18.04+ / Debian 9+ (使用 Systemd Timer):

Certbot 默认安装一个 systemd timer。检查状态:

sudo systemctl status certbot.timer

如果显示 active (waiting),说明自动任务已开启。如果没有开启,执行:

sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

对于 CentOS / 旧版系统 (使用 Cron):

检查 crontab:

sudo cat /etc/crontab | grep certbot
# 或者
sudo crontab -l

你应该能看到类似这样的行(每天运行两次):

0 0,12 * * * root python -m certbot -q renew

3,续签后自动重载 Nginx (关键步骤)

默认的续签命令只更新证书文件,不会自动重载 Nginx。如果 Nginx 不重载,它将继续使用旧的证书直到下次手动重启。

我们需要修改 Certbot 的钩子配置,让它在续签成功后自动执行 nginx -s reload 或执行 sudo systemctl reload nginx

方法 A:修改全局配置文件 (推荐)

编辑 /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh (如果目录不存在则创建):

# 创建目录
sudo mkdir -p /etc/letsencrypt/renewal-hooks/post
# 在 /etc/letsencrypt/renewal-hooks/post 目录下创建 reload-nginx.sh 文件
sudo touch reload-nginx.sh

使用 vim reload-nginx.sh 命令在 reload-nginx.sh 里写入以下内容:

# !/bin/bash
echo "Reloading nginx after certificate renewal..."
sudo systemctl reload nginx

赋予执行权限:

sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh

原理:Certbot 在 renew 命令成功结束后,会自动执行 /etc/letsencrypt/renewal-hooks/post/ 目录下的所有可执行脚本。

方法 B:直接在 Crontab/Systemd 中修改命令

如果你不想用钩子脚本,也可以修改自动任务的执行命令,加上 --post-hook 参数: Cron 示例:

0 0,12 * * * root python -m certbot -q renew --post-hook "systemctl reload nginx"

Systemd Timer: 需要 override 配置文件,较麻烦,推荐使用方法 A。

常见问题排查 (Troubleshooting)

1,错误:Failed authorization procedure (Connection refused)

原因:80 端口被防火墙阻挡,或者 Nginx 没有监听 80 端口。

解决:检查云服务器安全组是否放行 TCP 80;检查 Nginx 配置是否有 listen 80;。

2,错误:Too many requests (Rate limit exceeded)

原因:短时间内申请次数过多。

解决:Let's Encrypt 有严格的频率限制。如果是测试环境,请使用 Staging 环境测试:

sudo certbot --nginx -d yourdomain.com --staging

测试通过后,再去掉 --staging 参数正式申请。

3,如何彻底删除证书?

如果你想移除某个域名的证书:

sudo certbot delete --cert-name yourdomain.com

注意,使用以上命令会删除配置文件中的 SSL 相关配置,记得手动清理 Nginx 配置中残留的 ssl_certificate 行,否则 Nginx 重启会失败。

通过以上步骤,你的 Nginx 站点将拥有自动维护的免费 HTTPS 证书,无需人工干预就能长期稳定运行了。

我的笔记