申请 HTTPS 证书之前,我做了挺足的心理建设:当年听说这东西要生成 CSR、验证域名、每年手动续期,还要花钱买,感觉是地狱难度。结果 certbot --nginx 一行命令,五分钟搞定,我坐在屏幕前有种"就这?“的空虚——比去 DMV 排队办 Real ID 顺利多了。

这篇把我当时走的完整流程记下来,包括自动续期怎么验证。Let’s Encrypt 的证书免费,有效期 90 天,靠自动续期续命,设好之后基本不用管。

动手前确认两件事

第一,域名已经解析到我的 VPS,在 Cloudflare 那边是灰云状态(先别开小黄云代理,申请完再开——开了代理,certbot 的域名验证偶尔会抽风,我吃过这个亏)。

第二,Nginx 正在跑,80 端口能正常访问。certbot 的 --nginx 模式会往你的 Nginx 配置里自动加证书相关的段,所以 Nginx 必须是正常工作的状态。

安装 certbot

sudo apt install certbot python3-certbot-nginx -y

python3-certbot-nginx 是 Nginx 插件,让 certbot 能自动读写 Nginx 配置。装完不用配,直接用。

一行命令申请证书

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

把主域名和 www 一起写上,一张证书管两个,省得以后麻烦。运行后它会问几个问题:填邮箱(证书快过期或出问题时通知你,别乱填)、同意服务条款、要不要把 HTTP 自动跳转到 HTTPS(选 yes,省得自己写跳转)。

几分钟后,看到 “Congratulations!” 就成了。certbot 已经自动干了三件事:下载证书、改 Nginx 配置加上 443 和证书路径、设置 80 跳 443。你可以看一眼它改的配置,确认一下:

sudo nginx -t
sudo systemctl reload nginx

证书文件存在 /etc/letsencrypt/live/opusmia.com/ 下面,fullchain.pem 和 privkey.pem 两个最关键。知道它们在哪就行,平时不用碰——certbot 全权打理。续期的时候它会自动换新文件、重载 Nginx,一条龙服务。

顺手看一眼 certbot 改过的 Nginx 配置也挺长见识:443 的 server 块里多了 ssl_certificate 两行,还加了 include /etc/letsencrypt/options-ssl-nginx.conf,里面是 Mozilla 推荐的加密套件配置。你不用背这些,但知道"证书相关的安全参数有人帮我调好了”,心里踏实。

然后浏览器打开 https://opusmia.com,小锁头出现了。那一刻的成就感,大概相当于自己换好了汽车雨刮——小事,但踏实。

自动续期:装完就忘的前提

Let’s Encrypt 证书只有 90 天有效期,手动续四次一年,谁也记不住。好在 certbot 安装时已经顺手建了一个 systemd timer,每天会试着续期。先确认这个 timer 在跑:

sudo systemctl status certbot.timer

看到 active 就行。然后是最关键的一步:模拟续期,验证整条链路是通的:

sudo certbot renew --dry-run

--dry-run 是演习模式,不会真的换证书,但会完整走一遍验证流程。如果这里报错,别拖,当场修——等 90 天后真过期了再修,网站就得裸奔。我当时演习一次通过,心里一块石头落地。

另外,申请时填的邮箱别乱填。证书到期前、续期失败时,Let’s Encrypt 会往这个邮箱发提醒。这是最后一道人工防线,相当于烟雾报警器的备用电池,平时用不上,关键时刻能救命。

顺手加个保险:每月手动看一眼证书有效期,权当体检:

sudo certbot certificates

输出里会写每个域名的过期时间。配合自动续期,正常情况下你永远不需要手动干预。

我踩过的一个小坑

第一次申请时,我的域名在 Cloudflare 开着小黄云(代理模式),certbot 的 HTTP 验证走代理绕了一圈,结果失败了。关掉代理切回灰云(DNS only),等 DNS 生效几分钟,再跑一次命令,一次通过。申请完证书,再把小黄云打开,不影响。

所以顺序是:灰云申请证书 → 验证通过 → 再开代理。这个顺序我记在了备忘录里,续期是走的同样的验证路径,不用再关代理(续期用的是已有的验证方式,一般没问题,但 --dry-run 演习时如果开了代理报错,你就知道该查哪儿了)。

一句话总结

证书这件事,一年就折腾两回:申请一次,演习验证一次。certbot --nginx 申请,certbot renew --dry-run 验续期,timer 保证自动执行。设好之后就忘掉它,让它自己续命——你的精力应该留给写文章,不是记证书过期日。