ssl_prefer_server_ciphers on仅移交套件选择权给服务端,兼容性取决于ssl_ciphers列表是否分层设计:前4项为ecdhe+aes-gcm/chacha20强套件,后2项为android 4.4/ie11兼容的aes128-sha256/sha,尾部!过滤确保无rc4/sha1/非pfs套件,并需配合ssl_protocols tlsv1.2 tlsv1.3和ssl_ecdh_curve secp256r1:prime256v1协同生效。

ssl_prefer_server_ciphers on 本身不优化兼容性,它只把加密套件选择权交给服务端——真正影响兼容性的,是你配置的 ssl_ciphers 列表是否兼顾现代安全与旧客户端支持。盲目开启却配错套件,反而会断掉部分 Android 4.4、Java 7 或老旧嵌入式设备的连接。
以下是在保障安全前提下,合理放宽兼容性的关键配置要点:
明确兼容目标,再反推 cipher 排序
不要追求“全兼容”,先确认必须支持的最低客户端(例如:Android 4.4、IE 11、Java 8u31),再选能覆盖它们的最小强套件集合。常见兼容性锚点:
- Android 4.4+、IE 11(Win7)、Java 8u31:需保留
ECDHE-RSA-AES128-SHA(虽无 AEAD,但支持 PFS 和 SHA256 签名) - iOS 9+、Chrome 41+、Firefox 33+:完全支持
ECDHE+AES-GCM和CHACHA20 - 不建议兼容:Windows XP / IE6–8、Android
ssl_ciphers 要分层排序,兼顾安全与兜底
把强套件放前,兼容性套件放后,并用 ! 后缀主动剔除中间风险项(如 SHA1 签名、非 PFS 套件):
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:!RC4:!MD5:!SHA1:!DES:!3DES:!EXPORT:!aNULL:!eNULL:!DSS";
说明:
- 前 4 项是首选:AEAD 模式 + PFS,覆盖绝大多数现代客户端
- 第 5–6 项是兼容层:
AES128-SHA256和AES128-SHA(仅当客户端不支持 GCM/ChaCha 时才 fallback) - 尾部
!过滤项确保不会意外启用 SHA1 签名、导出套件或匿名交换
协议与密钥交换参数要同步放宽(谨慎)
ssl_protocols TLSv1.2 TLSv1.3;
✅ 必须保留 TLSv1.2(TLSv1.3 不受该指令影响,但它是安全基线)
❌ 不要加 TLSv1.1 或 TLSv1.0 —— 它们已无法通过主流扫描评级(A+),且易被降级攻击利用ssl_ecdh_curve secp256r1:prime256v1;secp256r1(即prime256v1)是兼容性最广的曲线,Android 4.0+、iOS 5+、Java 7+ 均支持;避免用secp384r1单独配置,否则部分老设备握手失败可选:添加
ssl_dhparam(2048 位)提升 DH 兼容性,但非必需(ECDHE 已成主流)
验证兼容性不能只看 A+,要看真实客户端协商结果
用 SSL Labs 的 SSL Server Test 扫描后,重点查看 Handshake Simulation 表格:
- ✅ 正常:Chrome 120、Firefox 115、Safari 17、Edge 120、Android 13、iOS 16 → 全部协商到
ECDHE+AES-GCM或CHACHA20 - ⚠️ 可接受:Android 4.4、Java 8u31 → 协商到
ECDHE-RSA-AES128-SHA(PFS 仍在,无 RC4/SHA1) - ❌ 异常:IE 11(Win7)显示
TLS_RSA_WITH_AES_128_CBC_SHA(RSA 密钥交换,无 PFS)→ 说明 cipher 列表混入了非 ECDHE 套件,或ssl_prefer_server_ciphers未生效
命令行快速验证兼容性组合:
# 模拟 Android 4.4 OpenSSL 1.0.1e(支持 ECDHE+SHA,不支持 GCM) openssl s_client -connect yourdomain.com:443 -cipher 'ECDHE+AES:RSA+AES' -tls1_2 # 模拟 Java 8u31(禁用 RC4、SHA1,但接受 AES-SHA) openssl s_client -connect yourdomain.com:443 -cipher 'ECDHE-RSA-AES128-SHA' -tls1_2
不复杂但容易忽略











