ssl_prefer_server_ciphers 控制 TLS 握手时密码套件选择的主导权归属:开启(on)由服务端按 ssl_ciphers 顺序优先匹配,关闭(off)则按客户端 ClientHello 顺序优先匹配;其本身不定义算法优先级,而是决定协商主导方。

ssl_prefer_server_ciphers 的作用不是设置“加密算法优先级”,而是决定 TLS 握手时由谁来主导密码套件的选择 —— 是客户端,还是服务端(即 Nginx)。
它控制的是协商主导权,不是算法排序本身
SSL/TLS 握手过程中,客户端会在 ClientHello 中带上自己支持的密码套件列表(按客户端认为的安全性/兼容性排序);服务器收到后,有两种策略:
- 默认行为(ssl_prefer_server_ciphers off):Nginx 从客户端提供的列表中,按客户端顺序第一个匹配自己也支持的套件,直接采用 —— 客户端说了算。
- 启用后(ssl_prefer_server_ciphers on):Nginx 忽略客户端顺序,转而从自己配置的 ssl_ciphers 列表中,按服务端定义的顺序,找第一个客户端也支持的套件 —— 服务端说了算。
所以真正决定“哪些算法可用、谁优先”的是 ssl_ciphers 的写法,而 ssl_prefer_server_ciphers 决定了这个列表由哪一方来驱动匹配过程。
为什么推荐开启(on)?
关闭该选项容易导致老旧或不安全的客户端(比如旧版 IE、Android 4.x)把弱套件排在前面,Nginx 被迫选用它们,从而降低整体安全性。开启后,只要你的 ssl_ciphers 排序合理(强算法靠前、弱算法靠后或直接剔除),就能确保即使客户端支持 RC4 或 SHA1,也不会被选中。
- 例如:
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:!aNULL:!MD5; - 若客户端同时支持
ECDHE-RSA-AES128-GCM-SHA256和已废弃的RC4-SHA,且把后者排第一 —— 开启ssl_prefer_server_ciphers on就能跳过 RC4,选到前面那个安全套件。
配合 ssl_ciphers 才有意义
单独设 ssl_prefer_server_ciphers on 但 ssl_ciphers 写得混乱(比如把弱算法放前面,或包含已被禁用的套件),反而可能引入风险。实际配置中必须同步做到:
- 精简明确:只保留当前主流浏览器和客户端广泛支持的现代套件(如基于 ECDHE、AES-GCM、ChaCha20-Poly1305 的)
-
顺序合理:最强、最兼容的放最前,逐步降级,末尾用
!xxx显式禁用已知问题算法(如!SSLv3、!EXPORT、!RC4) -
协议对齐:搭配
ssl_protocols TLSv1.2 TLSv1.3,避免低版本协议拖累套件选择
现代部署中的实际建议
截至 2026 年,主流环境(包括微信小程序、iOS/Android 新版本、Chrome/Firefox 最新版)均全面支持 TLS 1.3 和现代 AEAD 套件。此时:
-
ssl_prefer_server_ciphers on是强烈推荐开启的,它是服务端掌握安全主动权的基础开关 - 更关键的是
ssl_ciphers内容 —— 可直接采用 Mozilla 推荐的 Intermediate 或 Modern 配置,并定期核对更新 - TLS 1.3 下该指令影响变小(因 1.3 协议已硬性限定套件范围,且不支持协商降级),但仍建议保持开启以覆盖 TLS 1.2 兼容场景


















