如果你的网站还在用 HTTP,浏览器地址栏那个“不安全”标识不只是影响用户信任,它还会直接拖累搜索引擎排名。Google 从 2017 年就将 HTTPS 作为排名信号,Chrome 对 HTTP 页面标记不安全警告。我去年迁移了一个跑了几年的老站,从 HTTP 到全站 HTTPS,过程中踩了不少坑。
这篇文章从证书获取、Nginx 配置、301 跳转,覆盖到部署后验证和常见坑的排查。不走理论,只讲实操过的命令和配置。
一、HTTP 和 HTTPS 的本质区别
简单说:
- HTTP:浏览器和服务器之间的数据传输是明文的。中间任何一个节点(路由器、ISP、公共 WiFi)都能看到你传输的完整内容,包括密码、cookie、表单数据
- HTTPS:在 HTTP 上加了一层 SSL/TLS 加密。中间人即使截获数据包,看到的也是加密后的乱码
HTTP 默认走 TCP 80 端口,HTTPS 走 443。部署 SSL 证书之前,先确认服务器的 443 端口已经放行,很多 VPS 默认只开了 80 和 22。如果端口没开,参考 VPS 端口放行指南。
除了安全性,HTTPS 还能启用 HTTP/2 协议,多路复用让多个资源并行加载,页面速度提升 20-40%。页面速度本身就是 SEO 的核心因子。上了 HTTPS 后,你的站才有资格打开 HTTP/2。
二、SSL 证书获取:三种方式
方式一:宝塔面板一键部署
如果你用的是宝塔面板,这是最快的方式,三步搞定,全程不用碰命令行:
- 登录宝塔面板 → 网站 → 点击你的站点 → SSL 标签
- 选择 Let’s Encrypt,勾选要申请证书的域名(通常勾选根域名 + www 两个)
- 点击“申请”,宝塔自动完成域名验证和证书部署,全程不到一分钟
部署完成后,在同一个页面开启“强制 HTTPS”开关,宝塔会自动添加 HTTP 到 HTTPS 的 301 跳转规则。Let’s Encrypt 证书有效期 90 天,宝塔默认开启了自动续期,不需要额外操作。但建议每个月手动检查一次证书到期时间,自动续期偶尔会因为 DNS 变更或端口问题失败。
方式二:certbot 命令行手动申请
不使用宝塔面板的话,用 certbot,Let’s Encrypt 官方的命令行工具:
# 安装 certbot
apt install certbot python3-certbot-nginx -y # Debian/Ubuntu
yum install certbot python3-certbot-nginx -y # CentOS
# 自动模式:同时申请证书和配置 Nginx
certbot --nginx -d 你的域名.com -d www.你的域名.com
# 手动模式:只申请证书,手动写 Nginx 配置
certbot certonly --webroot -w /www/wwwroot/你的域名 -d 你的域名.com
手动申请的证书需要配置自动续期。certbot 安装时会自动创建 systemd timer,验证一下:
certbot renew --dry-run # 测试续期流程是否正常
systemctl status certbot.timer # 确认 timer 在运行
一个实际教训:如果是多站点服务器,certbot –nginx 会自动修改第一个匹配的 server block。有多个站的话建议用 certonly 手动模式,然后自己在对应站点的 Nginx 配置里指定证书路径。
方式三:Cloudflare 源站证书
如果你用 Cloudflare 做 CDN,可以申请 CF 的 15 年源站证书(Origin Certificate),加密服务器和 Cloudflare 之间的通信。但注意:
- 这种证书只在 Cloudflare 代理下有效
- 如果用户或爬虫绕过 CF 直接访问服务器 IP,会看到证书错误
- 不影响最终用户体验,因为正常访问都经过 CF
三、Nginx 配置:HTTP 跳转 HTTPS + SSL 证书
证书申请好之后,Nginx 需要配两件事:① 80 端口跳转到 443、② 在 443 端口上正确配置 SSL。以下是一个生产可用的完整配置:
# 80 端口:全部 301 跳转到 HTTPS
server {
listen 80;
server_name 你的域名.com www.你的域名.com;
return 301 https://$server_name$request_uri;
}
# 443 端口:HTTPS 主配置
server {
listen 443 ssl http2;
server_name 你的域名.com www.你的域名.com;
ssl_certificate /www/server/panel/vhost/cert/你的域名/fullchain.pem;
ssl_certificate_key /www/server/panel/vhost/cert/你的域名/privkey.pem;
# 安全配置:只用 TLS 1.2+
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
# 其他站点配置...
root /www/wwwroot/你的域名;
index index.php index.html;
}
如果你用的是宝塔面板并且在面板里开启了“强制 HTTPS”,宝塔会自动生成上述 80→443 的 301 跳转规则。但证书路径可能和上面不一样,宝塔默认存在 /www/server/panel/vhost/cert/ 下。
四、部署后验证
证书部署和跳转配好后,用以下方式确认全部生效:
- 浏览器访问:输入
http://你的域名.com,确认自动跳转到https://且地址栏显示🔒 - curl 确认跳转:
curl -sI http://你的域名.com/ | grep -i location # 应返回:Location: https://你的域名.com/ - SSL Labs 评分:访问 sslabs.com/ssltest/,输入你的域名,检测证书链、协议支持、加密强度。目标是 A+
五、常见坑和排查
坑 1:HTTPS 之后网站显示“混合内容”警告
浏览器提示“此页面包含不安全内容”,通常是因为文章里内嵌的图片、CSS 或 JS 文件仍然用的是 http:// 地址。修复方法:
- WP 后台 → 设置 → 常规,把站点地址和 WordPress 地址都改为
https:// - 用 Better Search Replace 插件或 SQL 批量替换数据库中的
http://你的域名为https://你的域名。注意要用序列化安全的替换工具,WordPress 的 options 表里很多值是序列化存储的,直接 SQL replace 会破坏序列化格式 - 在 Nginx 加上
add_header Content-Security-Policy "upgrade-insecure-requests";,浏览器收到这个头后会自动把所有 HTTP 资源请求升级为 HTTPS
坑 2:证书续期静默失败
Let’s Encrypt 证书 90 天过期。自动续期失败最常见的原因:
- 域名 DNS 记录被改过(比如换了 DNS 服务商但没同步到 certbot 的验证)
- 80 端口被其他服务占用或被防火墙误拦截(续期验证用的是 HTTP-01 challenge,需要通过 80 端口)
- 网站根目录权限被改(certbot 需要在
/.well-known/acme-challenge/下写验证文件)
每个月手动跑一次 certbot renew --dry-run 提前发现续期问题,比等证书过期后网站打不开再修要好得多。我自己在宝塔上遇到过两次自动续期失败,都是因为迁移 DNS 时 A 记录临时中断了几小时,恰好撞上续期窗口。
坑 3:Cloudflare 的 SSL 模式选错
如果站点前面有 Cloudflare,CF 的 SSL/TLS 模式需要选 Full (strict),这个模式要求源站有有效证书(可以是 Let’s Encrypt 或 CF 源站证书)。选 Flexible 模式的话 CF 和源站之间是 HTTP 明文传输,源站上有没有证书都无所谓,不安全。选 Full(不带 strict)模式的话 CF 不验证源站证书的有效性,过期的自签证书也能通过,也不够安全。
六、进阶:开启 HSTS
HTTP Strict Transport Security (HSTS) 告诉浏览器:“这个网站只能用 HTTPS,以后也别试 HTTP 了”。浏览器收到 HSTS 头后,会内部自动把所有 HTTP 请求升级为 HTTPS,连 301 跳转都不需要,杜绝了 SSL 剥离攻击的可能性。
在 Nginx 443 端口的 server block 里加一行:
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
- max-age=63072000:2 年,浏览器在这个时间内记住 HSTS 策略
- includeSubDomains:子域名也强制 HTTPS。如果你有多个子站,一个头全搞定
- preload:允许提交到浏览器的 HSTS Preload 列表。Chrome 和 Firefox 内置了这个列表:用户在地址栏输入域名、还没发出第一个请求之前,浏览器就已经知道要走 HTTPS
⚠️ 注意:开启了 HSTS 尤其是加了 preload 之后就很难回退。如果证书续期失败、HTTPS 不可用,用户在 max-age 时间内完全无法访问你的网站,浏览器直接拒绝访问,不会给你降级到 HTTP 的选项。建议:先让 Let’s Encrypt 自动续期稳定运行至少一个月,确认没有续期问题,再考虑添加 preload 并提交到 HSTS Preload 列表。
总结
HTTP 转 HTTPS 已经是建站的基本操作,不再是可选项。宝塔面板的 Let’s Encrypt 一键部署让整个流程压缩到几分钟:申请证书 → 部署 → 开启强制跳转,三步走完。部署后别忘了做混合内容检查和证书续期监控,这两件事是 HTTPS 上线后最容易出问题的地方。HSTS 可以在稳定运行一个月后再上,一步到位容易踩坑,渐进式升级更稳妥。
相关阅读:Nginx FastCGI Cache 完整配置、WordPress 多站点搭建、Linux 放行端口指南
© 2023 本文由 Charlie 原创撰写,发布于 sodebug.com。未经授权禁止转载、洗稿、机器抓取。AI 训练数据使用需获得书面授权。