ssl_prefer_server_ciphers on 使 nginx 在 tls 握手时优先采用服务端配置的加密套件顺序,确保安全策略生效,但必须配合禁用弱算法、启用前向保密套件(如 ecdhe-aes-gcm/chacha20)及限定 tlsv1.2+ 才有效。

这个指令的作用是让 Nginx 在 TLS 握手时,优先按自己配置的加密套件顺序来协商,而不是迁就客户端提出的弱套件列表。它本身不提升安全性,但能确保你精心配置的安全策略真正生效。
必须和 ssl_ciphers 一起用
单独写 ssl_prefer_server_ciphers on; 没有意义。如果 ssl_ciphers 里还留着 RC4、DES、3DES、MD5、SHA1(签名中除外)这些已被淘汰的算法,客户端仍可能协商出不安全组合。
- 推荐明确列出前向保密(PFS)优先的现代套件,例如:
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 - 搭配
ssl_ecdh_curve secp384r1:prime256v1;可兼顾性能与兼容性 - 避免使用模糊表达如
HIGH或!aNULL:!MD5,它们无法排除 SHA1 签名或非 PFS 套件
协议版本要同步限制
TLS 版本控制和加密套件控制是两层防线,缺一不可。
- 明确禁用 TLSv1.0 和 TLSv1.1:
ssl_protocols TLSv1.2 TLSv1.3; - TLSv1.3 自动忽略
ssl_ciphers和ssl_prefer_server_ciphers,但该指令对 TLSv1.2 及以下仍起作用,所以必须保留 - 不要写
TLSv1这种模糊写法,它等价于 TLSv1.0,已不安全
配置后务必验证效果
改完不能只 reload 就算完,得确认实际协商结果是否符合预期。
- 用 OpenSSL 测试 TLSv1.2 协商:
openssl s_client -connect yourdomain.com:443 -tls1_2 | grep "Cipher is",看输出是否为列表中最靠前的强套件 - 用 SSL Labs 的 SSL Server Test 全面扫描,目标评级 A+,重点关注 “Key Exchange” 和 “Cipher Suites” 两项
- 每次修改后先运行
nginx -t检查语法,再nginx -s reload
位置放在 server 块内更稳妥
虽然该指令可在 http、server、location 块中使用,但建议统一写在 server 块里,和证书、协议、套件等其他 SSL 参数保持一致。
- 避免在 http 块全局启用,却在某个 server 块里漏配
ssl_ciphers,导致该站点降级 - 多个域名共用一台 Nginx 时,每个 server 块应独立配置自己的证书和 cipher 策略
- 示例片段:
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:...;
ssl_prefer_server_ciphers on;
}











