ssl_prefer_server_ciphers on 是执行开关,必须与显式配置的 ssl_ciphers 配合使用,优先采用服务端指定的强套件(如ecdhe-gcm、chacha20),禁用rc4/sha1等弱算法,并配合 ssl_protocols tlsv1.2 tlsv1.3 和 ssl_ecdh_curve 优化密钥交换。

开启 ssl_prefer_server_ciphers on 是让 Nginx 在 TLS 1.2 及更早版本握手时,按服务端配置的顺序选择加密套件,而不是迁就客户端的弱偏好。但它本身不提升安全等级——真正起作用的是你如何搭配 ssl_ciphers、协议限制和密钥交换参数。放在 http 块中可全局生效,但必须确保所有 server 块都继承或显式覆盖相关 SSL 指令,否则容易被遗漏导致策略失效。
必须与 ssl_ciphers 显式配合使用
单独写 ssl_prefer_server_ciphers on; 没有效果。它只是“执行开关”,而加密套件的实际内容和优先级全靠 ssl_ciphers 定义:
- 推荐直接用明确、现代、支持前向保密(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 - 禁用已淘汰算法:在套件末尾加
!RC4:!MD5:!SHA1:!DES:!3DES:!EXPORT:!aNULL:!eNULL等后缀强化过滤 - 避免模糊表达如
HIGH或!aNULL:!MD5,它们无法排除非 PFS 套件或 SHA1 签名组合
限定协议版本并禁用老旧 TLS
TLS 版本控制与加密套件控制是两道独立防线。即使套件再强,若允许 TLSv1.0 协商,仍可能降级到弱组合:
- 强制启用 TLSv1.2 和 TLSv1.3:
ssl_protocols TLSv1.2 TLSv1.3; - TLSv1.3 不受
ssl_ciphers和ssl_prefer_server_ciphers影响,但该指令对 TLSv1.2 握手仍关键,因此必须保留 - 不要写
TLSv1或TLSv1.1,它们等价于 TLSv1.0,已被主流浏览器弃用且存在已知漏洞
搭配 ECDH 曲线优化密钥交换性能
ECDHE 密钥交换的安全性和效率依赖于曲线选择,需兼顾现代设备性能与旧客户端兼容性:
- 设置
ssl_ecdh_curve secp384r1:prime256v1; -
secp384r1运算更快、安全性更高,适合主流环境 -
prime256v1兼容性更广,能覆盖部分老旧 Android 或嵌入式设备
配置位置与验证要点
这个参数虽小,但放错位置或漏验证等于白配:
- 建议统一写在
http块内,使所有server块默认继承;若某站点需差异化策略,应在对应server块中显式重写ssl_ciphers和ssl_prefer_server_ciphers - 避免在
http块开启,却在某个server中漏配ssl_ciphers,这会导致该站点回退到 Nginx 默认弱套件 - 验证是否生效:
openssl s_client -connect yourdomain.com:443 -tls1_2 | grep "Cipher is"
确认输出为预期强套件(如ECDHE-RSA-AES128-GCM-SHA256)
同时用 SSL Labs Test 全面评估,目标评级 A+











