|
Nginx的加件ssl_ciphers指令,看着像一串天书,密套其实是加件给TLS握手定的“点菜规则”。你告诉服务器:我只接受这几道菜,密套客人点别的加件,直接掀桌。密套 去年排查一个线上故障,加件某银行客户反馈https页面在Windows XP老机器上打不开。密套抓包一看,加件客户端发来的密套cipher suite里只有RC4和3DES——这俩在Nginx默认配置里早被拉黑了。两边谈不拢,加件TLS握手直接失败。密套后来单独给那个location配了个兼容性cipher列表,加件问题解决。密套但代价是加件安全等级降了一截,这事得权衡。 cipher的写法有讲究。冒号分隔,顺序就是优先级。比如:
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305'; 这里把ECDHE椭圆曲线密钥交换放最前,因为它支持前向保密。AES-GCM是AEAD加密,效率高且防篡改。CHACHA20是老移动设备的救星——某些ARM芯片没有AES硬件加速,跑CHACHA20反而快。 有人图省事直接写ssl_ciphers HIGH:!aNULL:!MD5;。HIGH是个宏,代表所有高强度算法。但这么干有个坑:它会包含CBC模式的套件,比如AES256-SHA。CBC在TLS 1.2里有BEAST攻击隐患,虽然现代浏览器都防住了,但PCI-DSS合规扫描会报风险。 真正该关注的不是单个算法,而是套件组合的逻辑。比如!aNULL排除匿名认证,!MD5排除弱哈希,!3DES排除老古董。这些排除项比包含项更重要——白名单永远比黑名单安全,但黑名单能防止你手滑把某个危险算法加进去。 有个反直觉的点:cipher顺序比cipher本身更影响安全性。如果服务器把ECDHE-RSA-AES128-SHA放在ECDHE-RSA-AES256-SHA前面,攻击者可能通过降级攻击强迫客户端选128位版本。所以Nginx官方建议优先用GCM套件,把CBC排后面。 实际运维中,我见过最蠢的配置是有人把ssl_ciphers写进http块,结果所有server都继承。后来某个子站需要兼容老设备,单独在server块里覆盖,结果忘加ssl_protocols,TLS 1.0还在启用状态。这俩指令是配合使用的:protocols决定能用的TLS版本,ciphers决定每个版本里能用哪些算法。只调cipher不管protocol,等于换了锁芯但门框是纸糊的。 最后说个测试技巧。配完别急着上线,用openssl ciphers -v '你的配置'先本地看一遍解析结果。再拿sslscan扫一遍,重点看有没有NULL、EXPORT、LOW这些危险标记。真正的生产环境,我建议至少保留三个套件:一个ECDHE+AES-GCM(现代浏览器主力)、一个CHACHA20(移动端备选)、一个DHE+AES-GCM(兼容老旧但支持前向保密的客户端)。至于RC4和3DES——2024年了,直接删干净,别心软。 |