基线配置是什么
这是一套可直接采用的 nginx HTTPS 服务端基线:协议只留 TLS 1.2 与 1.3,套件只保留 ECDHE 与 AEAD 组合,会话缓存、证书链与 HSTS 一并配齐。目标是让默认配置就满足常见的合规扫描要求,而不是上线后再逐项补丁。
基本信息
| 适用版本 | nginx 1.20 及以上(http2 指令写法在 1.25.1 起有变化) |
|---|---|
| 协议 | ssl_protocols TLSv1.2 TLSv1.3,不启用 1.0/1.1 |
| 套件 | ssl_ciphers 只留 ECDHE 与 AES-GCM/CHACHA20 组合 |
| 会话 | ssl_session_cache shared:SSL:10m 与 ssl_session_timeout 1d |
| 证书 | ssl_certificate 指向全链文件,ssl_certificate_key 指向私钥 |
| 配套项 | HSTS、OCSP Stapling、HTTP 跳转 HTTPS |
| 参考基线 | Mozilla SSL Configuration Generator 的 intermediate 档 |
典型使用场景
- 新站点上线:直接采用基线,避免默认配置暴露弱套件
- 等保与扫描整改:按基线收敛协议与套件,满足扫描工具的合规判定
- 反向代理入口:统一在 nginx 层收口 TLS,后端走内网明文或再加密
- 多域名站点:结合 SNI 与多个 server 块,各自指定证书链
- 灰度迁移 TLS 1.3:基线同时保留 1.2,观察后再逐步收紧
nginx HTTPS server 片段
nginx HTTPS server 片段
server {
listen 443 ssl;
http2 on; # nginx 1.25.1+;旧版本写成 listen 443 ssl http2;
server_name example.com;
# 证书必须带中间证书,顺序为叶证书在前、中间证书在后
ssl_certificate /etc/nginx/ssl/example.com.fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 只启用 1.2 与 1.3,旧版本一律关闭
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off; # 关闭会话票据可避免票据密钥长期不轮换
add_header Strict-Transport-Security "max-age=31536000" always;
}关键指令读法
| 指令 | 作用 | 常见错误 |
|---|---|---|
| ssl_protocols | 允许的协议版本 | 漏写 1.3 导致无法协商新版本;写成 TLSv1 放开旧版本 |
| ssl_ciphers | TLS 1.2 可用套件,按服务端偏好排序 | 当成对 1.3 的限制;留下 CBC 与 3DES |
| ssl_prefer_server_ciphers | 是否以服务端顺序优先 | 与客户端兼容性冲突时误配导致老客户端握手失败 |
| ssl_session_cache/timeout | 会话复用缓存与有效期 | 缓存过小或超时过长,复用效果差或长期占用 |
| ssl_certificate | 证书链文件 | 只放叶证书导致链不完整(error 20) |
| add_header HSTS | 声明强制 HTTPS | 只在部分 location 生效,主站响应缺失 |
TLS 1.3 的套件由协议默认集合与 openssl 配置决定,不受 ssl_ciphers 影响。写 1.2 的套件白名单不会限制 1.3 的协商结果;需要控制 1.3 套件要使用对应版本的专用配置项。
上线前后检查清单
- nginx -t 通过后再 reload,避免配置错误导致服务中断
- 用 openssl s_client 分别以 1.2 与 1.3 测试,确认协商结果与预期一致
- 用 -showcerts 确认下发的证书链完整且顺序正确
- 确认私钥文件权限为 600 且属主与运行用户一致
- 确认 80 端口的跳转生效且不产生重定向循环
- 检查 http 块是否有全局指令被 server 块覆盖,实际生效值以 server 块为准
把 ssl_ciphers 当成唯一安全边界是不够的:最终协商结果还受系统 OpenSSL 版本、发行版加密策略(如 RHEL 的 crypto-policies)影响。整改完成后必须用外部扫描或 s_client 实测确认,而不是只看配置文件。
基线之外的加固项
| 加固项 | 配置要点 | 收益 |
|---|---|---|
| OCSP Stapling | ssl_stapling on 与 ssl_trusted_certificate | 客户端不必自行访问 OCSP,握手更快且隐私更好 |
| HTTP 跳转 | 80 端口 return 301 到 https,保留原 URI | 避免明文入口与混合内容告警 |
| HSTS 预加载 | 确认全站与子域均支持 HTTPS 后再提交预加载列表 | 浏览器层面彻底杜绝降级访问 |
| 密钥权限 | 私钥与证书目录最小权限,属主与运行用户一致 | 降低私钥泄漏带来的连锁风险 |
| 日志与监控 | 记录握手失败与证书到期时间,纳入巡检 | 在证书过期或配置回退前提前告警 |
| 备份与灰度 | 配置纳入版本管理,变更先在预发验证 | 避免一次 reload 影响全部站点 |