开启 ssl_prefer_server_ciphers on 是让 Nginx 在 TLS 1.2 握手中落实安全策略的必要前提,它将加密套件选择权从客户端收归服务端,使 Nginx 严格按 ssl_ciphers 从左到右匹配首个客户端支持的强套件,但必须配合精简排序的 cipher 列表、禁用 TLSv1.0/1.1、指定安全椭圆曲线及实测验证才真正生效。

开启 ssl_prefer_server_ciphers on 是让 Nginx 在 TLS 1.2 握手中真正落实安全策略的必要前提,但它本身不提升安全性,只决定“谁来选加密套件”——不开启,服务端就无法主导选择,再强的配置也可能被客户端弱偏好覆盖。
它解决的核心问题:默认协商太被动
默认情况下(off),Nginx 会从客户端发来的加密套件列表中,挑第一个双方都支持的套件。而很多旧设备、中间代理甚至恶意节点,会在列表开头塞入 RC4、3DES、SHA1 等已被淘汰的算法。只要你的 ssl_ciphers 里还保留这些项(哪怕排在末尾),就可能被选中。
- 开启后,Nginx 不再看客户端排序,而是严格按你写的
ssl_ciphers从左到右匹配 - 相当于设了一道“服务端优先门禁”,把选择权收回来
- 这是对抗协议降级攻击的第一道控制点
为什么单开这个指令没用
它只是开关,不是安全补丁。没有配套措施,开启等于白开:
-
ssl_ciphers必须精简且排序合理:开头放 ECDHE+AES-GCM 或 ChaCha20-Poly1305 类前向保密(PFS)+ AEAD 套件 -
ssl_protocols必须限定为TLSv1.2 TLSv1.3,明确禁用 TLSv1.0/1.1 -
ssl_ecdh_curve应指定安全曲线如secp384r1:prime256v1,避免密钥交换退化到非 PFS 的 RSA
必须显式启用,且位置不能错
该指令默认是 off,不写就等于没配。尤其要注意:
- 必须写在
server块内,和ssl_certificate、ssl_ciphers同级;仅在http块全局设置,容易被某个server块遗漏或被include文件覆盖 - 反向代理场景下,它只影响「客户端 → Nginx」这一段,和
proxy_ssl_*参数无关 - 对 TLSv1.3 无效(协议已硬编码套件),但必须保留,确保 TLSv1.2 行为受控
验证是否真生效
配置完不能只靠语法检查,得实测:
- 用 OpenSSL 强制走 TLSv1.2 连接:
openssl s_client -connect yourdomain.com:443 -tls1_2 - 观察输出中的
Cipher行,确认实际协商结果落在你ssl_ciphers列表的前段,且不含 RC4、3DES、SHA1 等禁用项 - 可配合 SSL Labs 测试 查看评级与详细套件支持情况


















