文章资讯 / 云服务器 / SSL证书免费申请:Let's Encrypt配合Certbot自动续期,Nginx部署配置代码

SSL证书免费申请:Let's Encrypt配合Certbot自动续期,Nginx部署配置代码

发布时间: 分类:云服务器 作者:188mi 来源:互联网 阅读:184

SSL 证书免费申请最省事的路径:Let's Encrypt 签发,Certbot 自动续期,Nginx 加载证书并强制 HTTPS 跳转。下面按清单逐项给出命令、配置与排查顺序。

清单 1:动手前先确认这三项

域名解析已经指向本机。 在终端执行 dig example.com A +short、dig www.example.com A +short,返回的 IP 必须是你这台服务器的公网 IP。解析没生效就签发,验证请求会打到别处,报错多半是 Invalid response 或 Timeout during connect。

80 端口对外可用。 HTTP-01 验证默认走 80 端口,云厂商安全组、firewalld、ufw 三层都要放行。快速判断:curl -I http://example.com 返回 200/301/404 都算通,连接被拒就是被拦。如果 80 端口被封(部分机房要求备案后才开放),改用 DNS-01 验证,签发时加 --preferred-challenges dns,按提示在域名商处添加 TXT 记录。

Nginx 配置能回滚。 先把站点配置备份一份,例如 cp example.conf example.conf.bak。Certbot 的 nginx 插件会直接改写站点文件,改坏了得能一键还原。nginx -t 通过后再 systemctl reload nginx,不要用 restart。

清单 2:装 Certbot 的两种主流方式

方式 A,snap 安装,官方推荐,版本较新。

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
certbot --version

snap 版自带定时续期单元,装完基本不用另配续期。CentOS/Rocky、Ubuntu 22.04 之后都适用。

方式 B,系统包管理器安装。

sudo apt update && sudo apt install certbot python3-certbot-nginx
sudo dnf install certbot python3-certbot-nginx

包管理器里的版本可能偏旧,但与系统集成更好,定时任务由 certbot.timer 提供。拿不准装哪个,打开 certbot.eff.org,选你的系统和 Web 服务器,页面会直接生成对应命令,照抄即可。

清单 3:签发证书,按场景选参数

场景一,机器上已有 Nginx 站点配置。 用 nginx 插件最省事,它会自动读 server_name、申请证书并写好 HTTPS 配置:

sudo certbot --nginx -d example.com -d www.example.com

首次运行要填邮箱(用于到期提醒)并同意条款。想跳过交互加 --non-interactive --agree-tos -m you@example.com。

场景二,Nginx 跑在容器里,或配置由其他工具生成。 用 webroot 模式,把验证文件落到站点根目录:

sudo certbot certonly --webroot -w /var/www/html -d example.com

先在 Nginx 里让 /.well-known/acme-challenge/ 可被公开访问,再执行签发。

签发成功后证书在 /etc/letsencrypt/live/example.com/ 下:fullchain.pem 给 ssl_certificate,privkey.pem 给 ssl_certificate_key。这两个路径是软链,续期后自动指向新文件,配置里直接写它们,不要把证书复制到别处。

清单 4:Nginx 的 HTTPS 配置要点

在站点 server 块里补齐下面几项:

  • listen 443 ssl http2; 和 listen [::]:443 ssl http2;
  • ssl_certificate / ssl_certificate_key 指向上面两个 pem
  • ssl_protocols TLSv1.2 TLSv1.3;,关掉 TLSv1/1.1
  • ssl_ciphers HIGH:!aNULL:!MD5;,或直接用 Mozilla 的 intermediate 推荐值
  • ssl_session_cache shared:SSL:10m; 减少重复握手开销
  • 80 端口单独一个 server 块做跳转:return 301 https://$host$request_uri;
  • 需要 OCSP stapling 时加 ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
  • HSTS 先设短时长观察:add_header Strict-Transport-Security "max-age=86400" always; 确认站点没有 http 资源后再逐步调大

改完 nginx -t 验证语法,再 systemctl reload nginx。用 curl -I https://example.com 看状态码,用 openssl s_client -connect example.com:443 -servername example.com 看证书链是否完整。

清单 5:让续期真正自动跑起来

据 Let's Encrypt 官方文档,证书有效期约 90 天,续期窗口在到期前三十天内,所以必须自动化,否则某天早上站点会直接报证书过期。

  • 确认定时器存在:systemctl list-timers | grep -i certbot,snap 用户看 snap.certbot.renew.timer,apt 用户看 certbot.timer。没有就手动建 cron:0 3 * * * /usr/bin/certbot renew --quiet --deploy-hook "systemctl reload nginx"
  • 跑一次模拟续期:sudo certbot renew --dry-run,走完整验证流程但不消耗真实额度,报错信息更容易定位
  • 加部署钩子:Nginx 不会自动读新证书,续期后必须 reload。可在 /etc/letsencrypt/renewal/example.com.conf 的 [renewalparams] 段加 renew_hook = systemctl reload nginx,或用命令行的 --deploy-hook。nginx 插件签发的证书通常已内置钩子,自己再确认一遍更稳妥
  • 看日志:结果写在 /var/log/letsencrypt/letsencrypt.log,失败原因多半是 80 端口被改、DNS 记录被删、验证路径被重写规则拦掉

清单 6:出问题时的排查顺序

  1. dig 看解析,不对就先改 DNS 并等 TTL 过期
  2. curl -I http://域名/.well-known/acme-challenge/测试文件,404 是 root 路径写错,403 查目录权限
  3. nginx -t 修语法错,别急着 reload
  4. certbot certificates 看证书是否存在、到期时间和绑定域名
  5. journalctl -u nginx --since "10 min ago" 看重载失败与读取权限问题
  6. 浏览器控制台仍报混合内容,说明页面模板里还硬编码了 http 资源地址,改模板而不是改证书

证书目录默认权限已够 Nginx 读取,若报 permission denied,先查 /etc/letsencrypt/live 与 archive 的属主,别图省事 chmod 777。证书类型选 RSA 还是 ECDSA、是否购买商业证书做兜底,按自己业务的兼容要求定,费用以各平台页面为准。

相关工具与阅读