前言
自从 Chrome 浏览器把不带 HTTPS 的网站标记为"不安全"之后,全站 HTTPS 就不再是可选项,而是每个站长的基本功了。HTTPS 除了能消除浏览器的安全警告、保护访客数据不被中间人窃取之外,对 SEO 也有实实在在的好处:Google 官方早就确认 HTTPS 是排名因素之一,百度也在逐步提升 HTTPS 站点的权重。更重要的是,只有上了 HTTPS 才能启用 HTTP/2 和 HTTP/3,网站加载速度还能再快一截。本文以 Nginx + Let's Encrypt 免费证书为例,手把手教你把网站完整迁移到 HTTPS。
一、准备工作
在动手之前,先确认三件事。第一,域名解析要指向服务器 IP,可以在本地执行 nslookup 或 dig 命令验证 A 记录是否生效;第二,服务器上要安装好 Nginx,并且 80 端口能正常访问,因为后面申请证书时需要用到 80 端口的验证流程;第三,确认服务器防火墙放行了 80 和 443 端口,否则申请或访问都会失败。这三项都满足之后,就可以开始安装了。
二、安装 Certbot 客户端
Let's Encrypt 证书的申请需要借助 ACME 客户端,最常用的是 Certbot。Debian/Ubuntu 系统直接通过 apt 安装:
apt update
apt install -y certbot python3-certbot-nginxCentOS/RHEL 系统则需要先启用 EPEL 源,然后执行 yum install -y certbot python3-certbot-nginx。安装完成后,可以用 certbot --version 检查是否安装成功。
三、申请免费证书
Certbot 提供了 Nginx 插件,可以自动修改 Nginx 配置并完成证书申请,对新手最友好。执行下面的命令,把域名换成你自己的:
certbot --nginx -d example.com -d www.example.com第一次运行时会引导你输入邮箱地址(用于证书过期提醒)、同意服务条款,并询问是否将 HTTP 请求自动重定向到 HTTPS,这里选择重定向即可。申请成功后,证书文件会保存在 /etc/letsencrypt/live/example.com/ 目录下,其中 fullchain.pem 是完整证书链,privkey.pem 是私钥,这两个文件在 Nginx 配置里要用到。Let's Encrypt 证书的有效期是 90 天,所以自动续期是必须配置的,这一点后面单独讲。
如果你不想让 Certbot 改动 Nginx 配置,也可以只用 webroot 模式申请证书,证书申请下来后自己手动配置 Nginx,适合对配置有洁癖的站长:
certbot certonly --webroot -w /var/www/html -d example.com -d www.example.com四、Nginx 配置 HTTPS
证书拿到手之后,就是配置 Nginx 了。在网站的 server 配置块中,增加一个监听 443 端口的 server,并指定证书路径:
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/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.php index.html;
# ... 其他原有配置
}同时把原来监听 80 端口的 server 改成 301 跳转,把所有 HTTP 流量引导到 HTTPS:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}配置里的 listen 443 ssl http2 表示同时开启 HTTP/2,多路复用特性可以显著减少页面资源加载时间。改完配置后先执行 nginx -t 检查语法,确认无误再执行 systemctl reload nginx 让配置生效。用浏览器访问 https://example.com,看到地址栏的小锁头图标,就说明 HTTPS 配置成功了。
五、配置证书自动续期
Let's Encrypt 证书只有 90 天有效期,手动续期不现实,必须交给定时任务。Certbot 安装时会自动创建续期用的 systemd timer,但为了保险起见,建议再加一条 crontab 任务,每天凌晨检查一次:
crontab -e
# 每天凌晨 3 点检查并续期,续期成功后重载 Nginx
0 3 * * * certbot renew --quiet --renew-hook "systemctl reload nginx"certbot renew 命令会自动检查所有已申请的证书,只在证书剩余有效期不足 30 天时才真正续期,平时执行几乎不消耗资源。配置好之后,可以先手动跑一次演练,验证续期流程是否通畅:
certbot renew --dry-run如果输出 Congratulations 或类似的成功提示,说明自动续期链路没有问题,之后就可以高枕无忧了。这里再补充几个小提醒:一是 certbot 的续期日志会记录在 /var/log/letsencrypt/ 目录下,遇到续期失败可以来这里查原因;二是申请时填写的邮箱务必真实有效,证书即将到期或续期异常时,Let's Encrypt 会发邮件提醒,这是最后一道保险;三是如果服务器换了 IP 或者域名解析有变动,续期验证可能会失败,需要及时检查 DNS 配置,确保验证所用的 80 端口或 DNS 记录始终可用。
六、旧链接 301 与资源路径批量替换
网站从 HTTP 迁移到 HTTPS,还有一个容易被忽略的工作:旧链接的处理。如果之前网站在搜索引擎里已经积累了收录,迁移之后要确保所有旧的 HTTP 链接都能 301 跳转到对应的 HTTPS 地址,把权重传递过去,否则收录会流失。前面配置的 return 301 https://$host$request_uri 已经完成了这一步,Nginx 会自动把完整的请求路径带上,旧链接一个都不会丢。如果是 WordPress 等带固定链接的 CMS,还要登录后台把"站点地址"从 http:// 改成 https://,并在数据库中批量替换内容里的旧域名,比如用 WP-CLI 或 SQL 语句把所有 http://example.com 替换成 https://example.com,否则文章正文里引用的图片、链接依然是 HTTP,浏览器会报混合内容警告。
另外,如果网站接了 CDN,迁移 HTTPS 时要注意证书的同步:CDN 节点和源站都要配置证书,或者在 CDN 控制台开启"回源跟随"并把源站证书配好,避免出现浏览器访问 CDN 域名时证书不一致的情况。还有一个小细节:百度站长平台、Google Search Console 里都支持提交"HTTPS 验证"和站点改版规则,迁移完成后建议去提交一下,让搜索引擎尽快知道你的站点已经全部切到 HTTPS 了,这对保持甚至提升搜索排名很有帮助。
七、进阶配置:HSTS 与 OCSP Stapling
基础配置完成之后,还有两个值得加上的进阶项。第一个是 HSTS(HTTP Strict Transport Security),它告诉浏览器:这个网站只能用 HTTPS 访问,连第一次的 HTTP 请求都不允许。在 HTTPS 的 server 块里加一行响应头即可:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;加了 HSTS 之后,浏览器会强制使用 HTTPS,彻底杜绝降级攻击。不过要提醒一句:一定要确认全站 HTTPS 稳定运行之后再开启,否则一旦配置错误,浏览器会拒绝访问你的网站,而且这个策略要等 max-age 过期才能解除。
第二个是 OCSP Stapling。浏览器验证证书是否被吊销时,默认会去访问 CA 的 OCSP 服务器,这一步会拖慢首次访问速度。开启 OCSP Stapling 后,由 Nginx 定期去获取 OCSP 响应并缓存在本地,浏览器就不用再额外请求了:
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 1.1.1.1 valid=300s;八、常见问题排查
最后整理几个常见的坑。第一,申请证书时报 DNS 验证失败,多半是域名解析还没生效,或者用了境外 DNS 解析但服务器在国内,等解析生效再重试;第二,证书申请成功但网站打不开,检查防火墙是否放行了 443 端口,以及 Nginx 是否真的加载了证书文件(注意证书目录权限,Nginx 的 worker 进程要有读取权限);第三,网站出现"混合内容"警告,说明页面里还有 http:// 开头的图片、脚本或样式资源,需要把网站后台的站点地址和所有资源引用都改成 https://;第四,用了 CDN 的话,记得回源也要走 HTTPS,并且在 CDN 控制台同步上传证书,否则浏览器看到的证书和源站不一致。把这些问题都处理掉,全站 HTTPS 就真正大功告成了。
九、总结
全站 HTTPS 部署并不复杂:装 Certbot、申请证书、配 Nginx、设自动续期,四个步骤半小时内就能完成,而且 Let's Encrypt 证书完全免费。迁移 HTTPS 之后,网站更安全、浏览器不再警告、SEO 有加成、还能用上 HTTP/2 加速,一举多得。还没有上 HTTPS 的站长,今天就可以动手把这件事办了。