nginx的ssl/tls安全等级由ssl_protocols、ssl_ciphers、证书链完整性、ocsp stapling和私钥权限五项共同决定,缺一不可;任一缺失均可能导致等保不通过或sslscan暴露漏洞。

直接说结论:Nginx 的 SSL/TLS 安全等级不是靠“开个开关”决定的,而是由 ssl_protocols、ssl_ciphers、证书链完整性、OCSP Stapling 和权限控制这五项共同落地的。漏掉任意一项,都可能被等保测评打回,或在 sslscan 扫描中暴露出 TLSv1.1 回退、弱密钥交换、证书链断裂等问题。
ssl_protocols 必须显式写全,不能依赖“默认”
Nginx 不会自动补全你没写的协议版本。哪怕你用的是 1.21.6 + OpenSSL 1.1.1w,只要配置里只写了 ssl_protocols TLSv1.2;,TLSv1.3 就不会启用——不报错、不警告、也不协商。
- 正确写法:
ssl_protocols TLSv1.2 TLSv1.3;(顺序无关,但建议把TLSv1.3放后面) - 绝对不要写
TLSv1或TLSv1.1:它们已被 NIST 和 CISA 明确弃用,留着等于主动扩大攻击面 - 该指令必须放在
server块内(443 端口),不能只写在http块顶层——否则子块会继承空值或旧值 - 验证方式:
openssl s_client -connect example.com:443 -tls1_3 -servername example.com 2>/dev/null | grep "Protocol",应输出Protocol : TLSv1.3
ssl_ciphers 要禁用非前向保密套件,且必须配 ssl_prefer_server_ciphers on
只设 ssl_ciphers 不够,客户端仍可能协商出服务端不希望的弱算法。关键在 ssl_prefer_server_ciphers on 强制服务端主导排序。
宝塔Linux面板11.8.1为官网当前正式版,新增AI建站能力并经过宝塔网站工程师深度调教,开放自定义AI功能API,同时对WAF进行界面重构和深度优化,提升拦截能力与运维效率。
- 推荐用 Mozilla Intermediate 配置(兼顾兼容性):
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305; - 必须剔除:
RC4、3DES、MD5、SHA1、SSLv2、SSLv3相关套件 -
ssl_ecdh_curve secp384r1;可选但建议加上,避免某些客户端 fallback 到不安全曲线 - 测试命令:
nmap --script ssl-enum-ciphers -p 443 example.com,确认输出中无TLS_RSA_开头或含SHA1的条目
证书链不完整 = 浏览器直接报 NET::ERR_CERT_AUTHORITY_INVALID
Let’s Encrypt 的 fullchain.pem 是域名证书 + 中间证书拼接体,而很多自签或商业证书只给了单个 .crt 文件——Nginx 不会自动补中间链。
- 检查方法:
openssl crl2pkcs7 -nocrl -certfile /etc/nginx/ssl/example.com.crt | openssl pkcs7 -print_certs -noout,应至少输出两段证书(域名证书 + 中间 CA) - 修复方式:把中间证书追加到域名证书后面,保存为
fullchain.pem,然后在配置中用ssl_certificate /path/to/fullchain.pem; - 私钥权限必须是
600:chmod 600 /etc/nginx/ssl/example.com.key,否则 Nginx 启动失败并报PEM_read_bio_PrivateKey() failed - 别用
cat domain.crt ca-bundle.crt > fullchain.pem拼接:确保中间证书是 PEM 格式、无 BOM、无 DOS 换行(file -i fullchain.pem应显示us-ascii)
OCSP Stapling 不只是“锦上添花”,它是 TLSv1.3 下连接建立的关键环节
TLSv1.3 默认启用 0-RTT,但 Safari/iOS 客户端在未收到 OCSP 响应时,会阻塞握手、重试甚至弹证书警告——这不是配置错误,而是协议行为。
- 必须三行配齐:
ssl_stapling on;、ssl_stapling_verify on;、ssl_trusted_certificate /etc/letsencrypt/live/example.com/fullchain.pem; -
ssl_trusted_certificate必须指向包含根 CA 和中间 CA 的 PEM 文件,不能只指域名证书 - 验证是否生效:
openssl s_client -connect example.com:443 -status -servername example.com 2>&1 | grep -A 17 "OCSP response",看到OCSP Response Status: successful (0x0)才算成功 - 如果用自建 CA 或私有 PKI,需额外配置
ssl_stapling_responder指向你的 OCSP 响应服务器地址
最容易被忽略的点:所有这些配置都只在 server 块生效,且必须配合 listen 443 ssl http2;。哪怕 ssl_protocols 写对了,如果漏了 ssl 关键字,Nginx 就当普通 HTTP 端口处理,加密完全不触发。










