第01章:AI写的Nginx配置能跑,但你的HTTPS评级只有B

第01章:AI写的Nginx配置能跑,但你的HTTPS评级只有B

“Nginx 配了 HTTPS,用户连接是加密的——但 Qualys SSL Labs 给了你 B,因为你允许了过时的 TLS 协议和弱密码套件。”


ℹ️ 版本说明:本章基于 Nginx 1.30.2(最新稳定版)、Ubuntu 26.04 LTSOpenSSL 3.3+certbot 2.x

1.1 AI默认会生成什么

你让 AI 帮你为域名配置 HTTPS,它通常给你:

server {
    listen 443 ssl;
    server_name example.com;
    
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    
    location / {
        proxy_pass http://127.0.0.1:8000;
    }
}

这个配置能工作,HTTPS 会生效。但如果你用 Qualys SSL Labs 测试,得到的评级可能是 B 甚至 C:

  • ssl_protocols TLSv1 TLSv1.1:TLS 1.0 和 1.1 已经在 2021 年被 IETF 正式废弃(RFC 8996),包含了已知攻击(BEAST、POODLE)
  • ssl_ciphers HIGH:!aNULL:!MD5:这是老式的 OpenSSL 过滤语法,可能包含弱密码套件
  • 没有 HSTS:浏览器不会强制 HTTPS,用户仍可能被降级到 HTTP
  • 没有 OCSP Stapling:每次 TLS 握手需要额外的证书吊销检查,增加延迟

1.2 AI通常遗漏的4个坑

⚠️ 坑1:允许了废弃的 TLS 协议

TLS 1.0 和 1.1 包含已知的安全漏洞(BEAST、POODLE),且 2026 年的所有现代浏览器都支持 TLS 1.2 和 1.3。

正确配置

ssl_protocols TLSv1.2 TLSv1.3;  # 只允许安全的版本

⚠️ 坑2:密码套件配置不够现代

ssl_ciphers HIGH:!aNULL:!MD5 是一个粗略的过滤,可能包含不够安全的密码套件。

Mozilla 推荐的 intermediate 配置(2026年)

ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;  # TLS 1.3 下客户端优先

⚠️ 坑3:没有 HSTS(HTTP Strict Transport Security)

没有 HSTS,用户第一次访问 http://example.com 时,你的服务器会 301 跳转到 HTTPS。但这第一次请求是通过 HTTP 发出的,攻击者可以在中间拦截(SSL Stripping 攻击)。

HSTS 的作用:浏览器记住"这个域名只能用 HTTPS",下次直接发 HTTPS 请求,不经过 HTTP 跳转。

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

⚠️ 坑4:没有 OCSP Stapling

每次 TLS 握手,浏览器可能需要向证书颁发机构(CA)查询证书是否已被吊销(OCSP 查询)。这增加了 50-100ms 的延迟,且依赖 CA 服务器的可用性。

OCSP Stapling:Nginx 定期从 CA 获取 OCSP 响应,并在 TLS 握手时直接提供给客户端,省去了客户端的 OCSP 查询。

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

1.3 更好的提示词

提示词 P01:生成 Qualys SSL Labs A+ 级别的 Nginx HTTPS 配置

使用时机:配置新的 HTTPS 站点,或升级已有配置达到最高安全评级

比默认多了什么

  • 只允许 TLS 1.2/1.3
  • Mozilla 推荐的密码套件
  • HSTS + OCSP Stapling
  • DH 参数
帮我生成 Nginx 1.30.x 的 HTTPS 配置,目标是通过 Qualys SSL Labs A+ 评级。

环境:Ubuntu 26.04 LTS + Nginx 1.30.2 + Let's Encrypt 证书(certbot)
域名:example.com(www.example.com 301 跳转到 example.com)

配置要求:
1. TLS 协议:只允许 TLS 1.2 和 TLS 1.3
2. 密码套件:使用 Mozilla SSL Configuration Generator 的 intermediate 方案(告诉我具体的密码套件字符串)
3. ECDH 和 DH 参数:
   - 启用 ECDHE(椭圆曲线 DH)
   - 生成 4096-bit DH 参数文件(openssl dhparam 命令 + nginx 配置)
4. HSTS:max-age=31536000; includeSubDomains(不要 preload,除非你解释 preload 的风险)
5. OCSP Stapling:启用 + 验证 + 配置 Google DNS 作为 resolver
6. 会话缓存:ssl_session_cache shared 和 ssl_session_timeout 配置
7. HTTP/2 支持(listen 443 ssl http2 在 Nginx 1.30 中的正确写法)

同时给我:
- 验证命令:如何用 openssl 命令验证本地配置
- Qualys SSL Labs 测试链接
- 常见的 A 和 A+ 的区别是什么

基于 Nginx 1.30.2 + OpenSSL 3.3+。

提示词 P02:从 HTTP 完整迁移到 HTTPS(不丢 SEO)

使用时机:已有 HTTP 站点,需要迁移到 HTTPS

比默认多了什么

  • 正确的 301 跳转
  • 保留原始 URL 路径
  • HSTS 渐进式部署
帮我完成 HTTP → HTTPS 迁移的 Nginx 配置,要求不影响 SEO。

站点类型:API 服务 + Web 前端(Vue.js 单页应用)

要求:
1. HTTP(80端口)的所有请求 301 永久跳转到 HTTPS
   - 保留完整的 URL 路径(/api/users → https://example.com/api/users)
   - 保留 query string(?page=1 不丢失)
2. HTTPS 配置:参考 P01 的 A+ 配置
3. HSTS 渐进式部署:
   - 第一阶段:max-age=86400(1天),先观察是否有问题
   - 确认无误后:max-age=31536000(1年)+ includeSubDomains
   - 为什么不建议立刻设置 preload?
4. www 和非 www 的处理:
   - www.example.com → example.com(301)
   - example.com 是主域名

同时告诉我:
- 如何验证所有 HTTP 请求都被正确重定向
- curl 测试命令(不跟随重定向,查看 301 响应头)

基于 Nginx 1.30.2。

提示词 P03:Let’s Encrypt 证书自动续期配置

使用时机:使用 certbot 申请证书,配置自动续期

比默认多了什么

  • 续期前测试 Nginx 配置
  • 续期后重载 Nginx
  • systemd timer 定期检查
帮我为 Nginx 1.30.x + certbot 配置证书自动续期。

当前配置:
- certbot --nginx 已经申请了 example.com 的证书
- 证书在 /etc/letsencrypt/live/example.com/

要求:
1. 创建续期前检查脚本(/usr/local/bin/cert-renew.sh):
   a. 运行 certbot renew --dry-run(先演习)
   b. 演习成功后运行真正的 certbot renew
   c. 续期成功后:nginx -t 验证配置,systemctl reload nginx
   d. 续期失败时:发 Webhook 告警(飞书)
   e. 记录操作日志到 /var/log/cert-renew.log

2. systemd timer(每天运行,凌晨3点):
   - 给我 cert-renew.service 和 cert-renew.timer 文件

3. 证书到期监控:
   - 如何检查证书剩余有效天数:openssl + certbot certificates
   - 当剩余天数 < 14 天时额外告警(即使 certbot 续期失败了也要知道)

4. 告诉我 certbot renew 的工作原理:它什么时候会真正续期,什么时候跳过?

基于 Ubuntu 26.04 LTS + certbot 2.x + Nginx 1.30.2。

1.4 验收清单

检查项 验证方法 AI辅助
只允许 TLS 1.2/1.3 openssl s_client -connect example.com:443 -tls1 应该失败 让 AI 修改 ssl_protocols
Qualys 评级 A+ https://www.ssllabs.com/ssltest/ 让 AI 对照报告修复问题
HSTS 已配置 curl -I https://example.com 有 HSTS 响应头 让 AI 添加 add_header HSTS
HTTP 跳转 HTTPS curl -I http://example.com 返回 301 让 AI 添加 return 301
OCSP Stapling openssl s_client -status -connect example.com:443 让 AI 添加 ssl_stapling on
证书自动续期已配置 systemctl status cert-renew.timer 用 P03 提示词配置续期

1.5 本章小结

如果你只记一件事:把 ssl_protocols 中的 TLSv1 TLSv1.1 去掉,只保留 TLSv1.2 TLSv1.3。这一行改动让你的 SSL 评级从 B 升到 A 的起点。

HTTPS 配置的三个层次

  1. 有 HTTPS(Qualys B):有证书、有加密,但允许旧协议
  2. 安全的 HTTPS(Qualys A):只有 TLS 1.2/1.3、现代密码套件、OCSP Stapling
  3. 强制 HTTPS(Qualys A+):加上 HSTS,浏览器记住只用 HTTPS,防止 SSL Stripping

从 B 升到 A+ 只需要修改几行配置——但 AI 不会主动帮你做,因为它不知道你的目标是 A+。

→ 第2章:AI配置了反向代理,但后端IP被泄露了