开启 ssl_prefer_server_ciphers on 是让 Nginx 以自身配置的加密套件顺序为准,但必须配合合理、明确的 ssl_ciphers(如 ECDHE+AEAD 套件)和 ssl_protocols TLSv1.2 TLSv1.3 才能真正提升安全性。

开启 ssl_prefer_server_ciphers on 是让 Nginx 在 TLS 握手时以自身配置的加密套件顺序为准,而不是迁就客户端提出的弱选项。但它本身不提升安全等级,只起“执行开关”作用——真正起效的前提是服务端配置本身合理、完整。
必须和 ssl_ciphers 明确配合
单独写 ssl_prefer_server_ciphers on; 没有意义。它只是告诉 Nginx “按我写的顺序来选”,但若 ssl_ciphers 里还混着 RC4、3DES、SHA1 签名或非前向保密(non-PFS)套件,客户端照样可能协商出不安全组合。
- 推荐直接列出强套件,避免模糊表达如
HIGH或!aNULL:!MD5,它们无法排除 SHA1 签名或 RSA 密钥交换等隐患 - 优先使用 ECDHE + AEAD 组合:AES-GCM 或 ChaCha20-Poly1305,全部禁用 CBC 模式
- 示例有效配置:
ssl_ciphers 'TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
协议版本要同步收紧
TLS 版本控制和加密套件控制是两层独立防线。即使套件再强,若允许 TLSv1.0 或 TLSv1.1,攻击者仍可降级到存在已知漏洞的旧协议。
- 明确限定仅支持 TLSv1.2 和 TLSv1.3:
ssl_protocols TLSv1.2 TLSv1.3; - 不要写
TLSv1,它等价于 TLSv1.0,已被主流浏览器弃用且不安全 - TLSv1.3 不受
ssl_ciphers和ssl_prefer_server_ciphers影响,但该指令对 TLSv1.2 仍关键,所以必须保留
注意 TLS 1.3 与 1.2 的套件逻辑差异
TLS 1.3 彻底重构了密钥交换机制,ssl_ciphers 中任何带 ECDHE-RSA-AES256-GCM-SHA384 这类命名的套件都不被识别——它们属于 TLS 1.2。Nginx 不会报错,但只支持 TLS 1.3 的客户端可能 fallback 或握手失败。
- TLS 1.2 下:
ssl_ciphers是协商列表,顺序即优先级 - TLS 1.3 下:
ssl_ciphers仅用于过滤,真正生效的是五种硬编码组合,必须显式以TLS13-开头 - 双段式写法最稳妥:把 TLS 1.3 套件放最前,TLS 1.2 套件紧随其后,中间不混用
补充关键协同配置
光靠 cipher 和 prefer 指令还不够,还需配套设置才能让强策略真正落地。
- 启用前向保密需指定椭圆曲线:
ssl_ecdh_curve secp384r1:prime256v1;(兼顾安全性与兼容性) - 避免旧客户端拖累整体安全水位:若需兼容 Android 4.4.2 或 Java 7u25,可将兼容套件追加在
ssl_ciphers末尾,确保强套件始终优先 - 禁用不安全算法要彻底:移除 NULL、EXPORT、ANONYMOUS、MD5、SHA1(签名中除外)、DES、3DES、RC4


















