TLS 协议安全加固是 HTTPS 站点抵御协议层攻击的关键环节,核心在于禁用旧版协议与弱加密算法。本文面向 Nginx 运维人员,讲解如何通过 ssl_protocols、ssl_ciphers 等参数彻底禁用 TLS 1.0/1.1 与 RC4、3DES 弱套件,并给出 OpenSSL 实测验证方法,满足等保与 PCI DSS 对传输加密的合规要求。
适用场景
- 站点安全扫描报告提示「支持 TLS 1.0/1.1」「使用弱密码套件」
- 需要满足等保 2.0、PCI DSS、密评等合规检查项
- HTTPS 站点希望支持前向保密(Forward Secrecy)并优化握手性能
- Nginx 反代背后的业务对传输安全有明确要求
前置条件
- Nginx 1.18 及以上版本(老版本部分参数不支持)
- OpenSSL 1.1.1 及以上(支持 TLS 1.3)
- 已配置合法的 SSL 证书,站点通过 HTTPS 正常访问
原理说明
TLS 握手时客户端与服务端协商协议版本和密码套件(Cipher Suite),协商结果取双方支持列表的交集。若服务端仍开放 TLS 1.0/1.1,攻击者可利用 BEAST、POODLE(SSLv3)、Lucky13 等已知攻击降级破解;RC4 存在系统性偏差攻击,3DES 受 SWEET32(CVE-2016-2183)生日攻击影响,64 位块密码在 32GB 数据内即可发生碰撞泄露信息。加固思路是:仅保留 TLS 1.2/1.3,密码套件列表只包含支持前向保密(ECDHE)的强套件,并关闭有泄漏风险的会话票据。
操作步骤
步骤一:检查当前 TLS 配置
# 查看现有 ssl 相关指令
nginx -T 2>/dev/null | grep -E "ssl_protocols|ssl_ciphers|ssl_session"
# 查看 OpenSSL 版本(须 ≥ 1.1.1 才支持 TLS 1.3)
openssl version
步骤二:编写强 TLS 配置(Mozilla Intermediate 标准)
# 在 server 块中追加,或放入 ssl.conf 后 include
ssl_protocols TLSv1.2 TLSv1.3;
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 on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
# 启用 HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
要点说明:ssl_protocols TLSv1.2 TLSv1.3 明确排除 TLSv1/TLSv1.1;ssl_ciphers 中全部为 GCM/CHACHA20 认证加密套件,均为 ECDHE/DHE 前向保密套件;ssl_session_tickets off 关闭无状态票据,避免票据密钥被窃取后的会话解密风险。
步骤三:测试并重载配置
nginx -t
systemctl reload nginx # 或 nginx -s reload
配置验证
# 1. TLS 1.0/1.1 必须失败(no protocols available 或 handshake failure)
openssl s_client -connect your-domain.com:443 -tls1 -brief 2>&1 | head -2
openssl s_client -connect your-domain.com:443 -tls1_1 -brief 2>&1 | head -2
# 2. TLS 1.2 / 1.3 必须成功
openssl s_client -connect your-domain.com:443 -tls1_2 -brief &1 | grep -E "Protocol|Cipher"
openssl s_client -connect your-domain.com:443 -tls1_3 -brief &1 | grep -E "Protocol|Cipher"
# 3. 查看当前协商的密码套件与证书链
echo | openssl s_client -connect your-domain.com:443 2>/dev/null | grep -E "New, TLS|Cipher is"
常见问题
Q1:禁用 TLS 1.0/1.1 后,IE 等老浏览器无法访问怎么办?
Windows 7 的 IE11 及主流国产浏览器均已支持 TLS 1.2,实际影响面极小。若确有老终端(如 Windows XP 内网设备),可对特定 location 或监听端口单独放开 TLSv1,其余流量保持强配置,不建议全局回退。
Q2:为什么建议关闭 ssl_session_tickets?
TLS 会话票据依赖服务端密钥加密,一旦票据密钥泄露(如被植入后门或日志泄露),攻击者可解密任意历史会话。无状态票据的密钥轮换也常被忽视。对安全要求高的站点建议关闭;若开启,务必通过 ssl_session_ticket_key 定期轮换密钥并妥善保管。
Q3:套件列表是否越长越好?
不是。套件列表越长,握手协商开销越大,且一旦混入弱套件会被协商选中。建议仅保留上述 GCM/CHACHA20 前向保密套件;如需兼容 Windows XP/老安卓,才额外追加 ECDHE-RSA-AES128-SHA(AES-CBC),并知晓其性能与安全权衡。
总结
TLS 协议安全加固的核心是「只留强项、明确排除」:协议版本仅保留 TLS 1.2/1.3,密码套件仅保留前向保密强套件,关闭会话票据,配合 HSTS 与 OCSP Stapling。按上述步骤配置后用 openssl s_client 逐项验证,即可通过主流安全扫描工具的传输安全检测,满足等保与 PCI DSS 合规要求。