首页/安全/加密与证书速查/nginx TLS 服务端基线配置
TLS 与 HTTPS60 条

nginx TLS 服务端基线配置

一套可直接采用的 nginx HTTPS 基线:协议限 1.2/1.3、套件只保留 ECDHE 与 AEAD 组合、会话缓存与证书配置齐全,并配合 HSTS 与 OCSP 形成完整能力。

加密与证书速查安全更新于 2026-10-13

基线配置是什么

这是一套可直接采用的 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_ciphersTLS 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 Staplingssl_stapling on 与 ssl_trusted_certificate客户端不必自行访问 OCSP,握手更快且隐私更好
HTTP 跳转80 端口 return 301 到 https,保留原 URI避免明文入口与混合内容告警
HSTS 预加载确认全站与子域均支持 HTTPS 后再提交预加载列表浏览器层面彻底杜绝降级访问
密钥权限私钥与证书目录最小权限,属主与运行用户一致降低私钥泄漏带来的连锁风险
日志与监控记录握手失败与证书到期时间,纳入巡检在证书过期或配置回退前提前告警
备份与灰度配置纳入版本管理,变更先在预发验证避免一次 reload 影响全部站点

易错点

  • 只在 http 块写全局 TLS 指令,却在某个 server 块里被覆盖:两个块的实际生效值不同,排查时会看错配置
  • 证书只放叶证书:客户端报 unable to get local issuer,浏览器可能因缓存而暂时正常,Java 与小程序的调用会先失败
  • 开启 ssl_session_tickets 且长期不轮换票据密钥:前向保密在会话恢复路径上被削弱
  • 启用 HTTP/2 时写法与版本不匹配:http2 指令与 listen 参数的写法随 nginx 版本变化,配置错误会导致启动失败
  • HSTS 的 max-age 一上来就写一年:一旦某个子域尚未支持 HTTPS,用户在该时间段内无法回退

数据来源与参考

  • nginx 官方文档(ssl_protocols/ssl_ciphers)
  • Mozilla SSL Configuration Generator
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌