现在打开浏览器访问一个没有 HTTPS 的网站,地址栏会直接标红提示不安全,搜索引擎也在搜索结果的权重上明显偏向 HTTPS 站点。对个人站长来说,给网站加上 HTTPS 已经不是可选项,而是必修课。Let's Encrypt 提供的免费证书可以无限期使用,只需要三个月手动续期一次,配合 certbot 的自动续期功能,几乎是一劳永逸。这篇文章把我从申请到自动续期再到踩坑修复的完整过程写出来,全部基于 Nginx 环境实测。
一、为什么要上 HTTPS
HTTPS 对个人站长的价值有三点。第一是安全:数据在浏览器和服务器之间加密传输,用户在网站上提交的任何信息都不会被中间人窃取,这也是浏览器厂商把 HTTP 站点标记为不安全的根本原因。第二是信任:绿锁标识和"连接是安全的"提示能明显提升访客对网站的信任度,对广告点击率、注册转化率都有正面影响。第三是 SEO:Google 和百度都明确把 HTTPS 作为排名因素,而且 HTTP/2 强制要求 HTTPS 才能启用,而 HTTP/2 的多路复用特性对页面加载速度的提升非常明显。
我的一个站点从 HTTP 切到 HTTPS 之后,搜索引擎抓取频率明显提高,收录速度比之前快了不少。虽然没法严格证明是 HTTPS 单独起的作用,但切换之后没有出现任何降权或者收录回退的问题,这个方向是安全的。
二、申请前的准备工作
申请 Let's Encrypt 证书之前,先确认三件事:
第一,域名已经解析到服务器,并且 HTTP 访问正常。证书签发需要验证你对域名的控制权,最常见的是 HTTP-01 验证方式,Let's Encrypt 会通过你的域名访问一个临时文件,能访问到才证明域名是你的。
第二,服务器 80 端口对外开放。签发时的验证请求走的是 80 端口,如果 80 被防火墙挡住或者被安全组拦截,签发必然失败。这也是很多新手卡住的第一道坎。
第三,确定域名解析方式。如果域名在国内服务器上且已经备案,直接 A 记录解析即可;如果域名指向海外服务器,还要注意服务器必须能正常访问 Let's Encrypt 的验证服务器,某些被墙的网络环境下需要先解决网络连通性问题。
三、安装 certbot 并签发证书
certbot 是 Let's Encrypt 官方推荐的客户端工具。Debian/Ubuntu 系统安装很简单:
apt update
apt install -y certbot python3-certbot-nginxCentOS 7/8 用:
yum install -y certbot python3-certbot-nginx安装完成后,如果 Nginx 配置已经写好,可以直接用 Nginx 插件签发,certbot 会自动修改 Nginx 配置并帮你启用 HTTPS:
certbot --nginx -d www.example.com -d example.com --email you@example.com --agree-tos --no-eff-email如果不希望 certbot 改动 Nginx 配置,只想拿到证书文件自己配,用 webroot 方式:
certbot certonly --webroot -w /var/www/html -d www.example.com -d example.com签发成功后,证书文件保存在 /etc/letsencrypt/live/www.example.com/ 目录下,其中 fullchain.pem 是证书链文件,privkey.pem 是私钥文件。这两个文件就是 Nginx 配置里要用到的。
验证签发结果:
certbot certificates这个命令会列出所有已签发的证书、域名列表和到期时间,以后排查证书问题全靠它。
四、Nginx 配置 HTTPS
拿到证书后,在 Nginx 的 server 配置块里加上 SSL 相关配置:
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
root /var/www/html;
index index.html index.php;
# 其余站点配置照旧
}
# HTTP 强制跳转 HTTPS
server {
listen 80;
server_name www.example.com example.com;
return 301 https://$host$request_uri;
}配置完成后执行 nginx -t 检查语法,然后 systemctl reload nginx 重载。这里注意一个细节:不要把老的 80 端口配置和新配置写冲突,我习惯把 80 端口的 server 块单独写成跳转,逻辑清晰也不容易出错。
如果网站用了 CDN,比如 Cloudflare,证书配置思路会不一样:要么在源站用 Let's Encrypt 证书配合 Cloudflare 的 Full 模式,要么直接用 Cloudflare 自己的边缘证书配合 Flexible 模式。两种方式都能让访客看到 HTTPS,但源站到 CDN 之间的链路安全性不同,建议用 Full 模式保证全程加密。
五、自动续期:三个月不操心
Let's Encrypt 证书有效期只有 90 天,手动续期太痛苦,好在 certbot 自带续期机制。先测试续期是否正常:
certbot renew --dry-run如果 dry-run 输出 Congratulations,说明续期流程通畅。certbot 安装时通常会自动创建续期定时任务:Debian/Ubuntu 上是一个 systemd timer,CentOS 上是 cron 任务。检查一下:
systemctl list-timers | grep certbot
# 或者
crontab -l | grep certbot如果系统里没有自动续期任务,自己加一条最稳妥:
# 每天凌晨 3 点检查一次,到期前 30 天内才会真正续期
0 3 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx"这里的关键是 --deploy-hook 参数:证书续期成功后才执行重载 Nginx,让新证书立即生效。很多站长续期成功了但网站用的还是旧证书,就是因为漏了重载这一步。
续期成功后,检查一下证书到期时间是否真的更新了:
openssl x509 -enddate -noout -in /etc/letsencrypt/live/www.example.com/fullchain.pem六、常见问题排查
问题一:签发时报"Invalid response from http://domain/.well-known/acme-challenge/xxx"。最常见的原因是 80 端口没开放、防火墙拦截了验证请求,或者 Nginx 把 .well-known 路径重定向到了别的地方。逐一排查:先 curl http://域名/.well-known/acme-challenge/test 看能不能访问,再检查安全组和系统防火墙。
问题二:证书到期了但自动续期没生效。先手动跑 certbot renew 看报错信息,常见原因包括 DNS 解析变更、服务器时间不准(时间偏差超过几分钟会导致验证失败)、或者证书目录权限被改坏了。
问题三:续期成功但浏览器还是提示证书过期。八成是 Nginx 没重载,执行 systemctl reload nginx;如果还不行,检查是不是有 CDN 缓存了旧证书,或者服务器上跑了多个站点共用了一个证书路径。
问题四:HTTPS 页面里混着 HTTP 资源,浏览器提示"不安全的内容"。网站里引用的图片、JS、CSS 如果是 http:// 开头的绝对地址就会触发这个警告,把 WordPress 后台的站点地址改成 https:// 之后,再检查主题和文章里的硬编码地址,全部替换成 https 或者改成相对路径。
问题五:证书文件权限不对导致 Nginx 无法读取。Nginx 的 worker 进程需要能读到 privkey.pem,一般保持 Let's Encrypt 默认权限即可,不要手动去 chmod 644 私钥文件,那样反而会引发安全风险。
问题六:一个证书要覆盖多个子域名,比如 www、m、api 都想用同一个证书。签发时把域名全部写在 -d 参数后面即可,certbot 会自动把多个域名放进同一个证书的 SAN(主题备用名称)字段里:
certbot certonly --nginx -d example.com -d www.example.com -d m.example.com -d api.example.com证书签发数量有速率限制,一个域名一周最多申请 50 张,正常使用完全够,但别反复撤销重新签,万一触发限制就要等一周。
HTTPS 配好之后还可以顺手把 HSTS 加上,让浏览器强制走 HTTPS:在 Nginx 的 443 server 块里加一行 add_header Strict-Transport-Security "max-age=31536000" always;。注意 HSTS 有生效期,一旦下发,浏览器在一年内都会强制跳转 HTTPS,所以一定要确认 HTTPS 完全稳定之后再开启,否则中途撤掉证书会让老访客直接打不开网站。
另外建议大家把证书到期时间写进自己的服务器监控脚本里,比如用 openssl x509 -enddate 检查剩余天数,不足 30 天就发邮件提醒自己。虽然 certbot 自动续期基本不会出问题,但多一道保险总是好的,毕竟证书过期导致的网站事故,一天就能让流量和用户信任全丢光,这个教训我是亲眼见过的,希望大家不要重蹈覆辙。证书虽免费,管理不能省心。
给网站配上 HTTPS 之后,记得去搜索引擎的站长工具里把站点地址更新成 https 版本,提交一次 sitemap,等待重新抓取。如果之前 HTTP 版本的页面已经被收录,记得在 Nginx 里把 80 端口统一 301 跳转到 HTTPS,保证老链接的权重完整过渡到新地址,避免收录流失。整个流程走通之后,HTTPS 证书这件事就再也不用操心了,三个月自动续期,服务器稳定运行就行。