我的 SSL 证书配置正确吗?
简短回答:当证书受信任(证书链完整)、覆盖你使用的所有域名(带 www 和不带 www)、在到期前很早就自动续期、只启用 TLS 1.2 和 1.3、所有 http:// 请求都重定向到 https://,并且设置了 HSTS 时,才算配置正确。浏览器里的锁形图标只能证明第一点。
快速步骤
- 检查证书链是否受信任. 分别在手机和电脑上用无痕窗口打开网站,不应出现任何警告。
- 检查域名. 如果你同时使用 yourdomain.com 和 www.yourdomain.com,证书必须同时包含两者。
- 检查有效期和续期. 查看 notAfter,并测试自动续期是否正常。
- 检查 TLS 版本. 只允许 TLS 1.2 和 TLS 1.3。
- 检查重定向. http:// 必须永久重定向到 https://。
- 检查 HSTS. 当 HTTPS 在所有地方都正常后,发送 Strict-Transport-Security。
代码和配置保持英文。
1. 受信任且完整的证书链
服务器还必须发送中间证书。缺少中间证书时,网站往往在电脑浏览器上能用,但在手机和 API 客户端上会失败。
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com -showcerts </dev/null 2>/dev/null | grep -E 's:|i:|Verify return'查找 Verify return code: 0 (ok)。在 nginx 中,ssl_certificate 应指向完整证书链文件(Let’s Encrypt 用 fullchain.pem,而不是 cert.pem)。
2. 覆盖所有域名
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com </dev/null 2>/dev/null \
| openssl x509 -noout -ext subjectAltName3. 有效期与自动续期
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com </dev/null 2>/dev/null \
| openssl x509 -noout -enddate
sudo certbot renew --dry-run # if you use certbot证书距到期不足 21 天时,HackGrade 标记为中风险;不足 14 天时为高风险;一旦过期或不受信任则为严重。
4. 仅启用 TLS 1.2 和 1.3
ssl_protocols TLSv1.2 TLSv1.3;SSLProtocol -all +TLSv1.2 +TLSv1.3测试旧版本是否被拒绝(该命令应当连接失败):
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com -tls1_1 </dev/null5. HTTP 重定向到 HTTPS
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$host$request_uri;
}RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]6. HSTS
当所有页面和子域名都能通过 HTTPS 访问后,添加 Strict-Transport-Security。请先阅读HSTS 指南 (英文):从较短的 max-age 开始,再逐步提高。然后修复所有混合内容 (英文)。
常见问题
免费证书(Let’s Encrypt)比付费证书更不安全吗?
不会。加密强度相同。付费证书的区别在于验证类型、技术支持和保险,而不是加密效果。
为什么我的网站只在部分手机上显示警告?
通常是缺少中间证书。请使用完整证书链文件配置服务器。
还应该支持 TLS 1.0 或 1.1 吗?
不应该。两者都已被废弃(RFC 8996),现代浏览器也已移除对它们的支持。