SSLInsecureRenegotiation 是 Apache mod_ssl 控制是否允许不安全 TLS 重协商的开关,默认关闭以防范 CVE-2009-3555;仅当确认老旧客户端(如 JDK 6u45 前)无法升级且必须通信时,才在 VirtualHost 中启用并严格管控。

SSLInsecureRenegotiation 是什么,为什么现在还要管它
SSLInsecureRenegotiation 是 Apache mod_ssl 提供的一个开关,控制是否允许不安全的 TLS 重协商(即未使用 RFC 5746 安全重协商机制的旧式 renegotiation)。2011 年后主流客户端和服务端默认禁用该行为,但某些嵌入式设备、老版本 Java(如 JDK 6u45 前)、或定制固件仍依赖它。开启后,Apache 会接受不带 secure_renegotiation 扩展的重协商请求——这本身有 CVE-2009-3555 风险,所以默认是 off。
如果你的日志里反复出现类似 Re-negotiation requested but not allowed,或客户端报 “SSL handshake failed” 且确认对方无法升级,才需要考虑打开它。
如何在 Apache 中启用 SSLInsecureRenegotiation
必须在启用 HTTPS 的 <virtualhost></virtualhost> 或全局 SSL 上下文中设置,仅靠 SSLEngine on 不生效。
- 编辑你的站点配置(如
/etc/apache2/sites-enabled/example.com.conf),在<virtualhost></virtualhost>块内添加一行:SSLInsecureRenegotiation on
- 确保该指令出现在
SSLCertificateFile和SSLCertificateKeyFile之后(顺序无关紧要,但放在一起便于维护) - 重启 Apache:
sudo systemctl reload apache2(Debian/Ubuntu)或sudo apachectl graceful(RHEL/CentOS)
注意:SSLInsecureRenegotiation 是 per-vhost 指令,不能写在 .htaccess 中;也不支持 SSLInsecureRenegotiation off 显式关闭(默认就是 off,写出来反而可能被误读)。
启用后要注意哪些兼容性与安全折中
开这个开关不是“修复 SSL”,而是绕过协议校验——它会让 Apache 接受已知存在中间人劫持风险的重协商流程。实际影响取决于你的客户端生态:
- 只影响触发重协商的场景:比如客户端在已建立的连接上发起客户端证书认证、或某些代理/负载均衡器转发时二次协商
- 现代浏览器(Chrome 30+、Firefox 25+、Safari 7+)和 OpenSSL 1.0.1+ 服务端完全不走这条路,开了也无感
- Java 6u45 之前版本、部分 IoT 设备 SDK、老旧 Android WebView 可能因此连通,但你同时放弃了对 CVE-2009-3555 的防护
- 如果用了 TLS 终止在前置 LB(如 AWS ALB、Cloudflare),则 Apache 根本收不到原始 renegotiation 请求,此配置无效
替代方案比直接开 SSLInsecureRenegotiation 更值得优先尝试
真正安全的做法是让客户端升级,而不是服务端降级。以下路径更可持续:
- 检查客户端是否真无法更新:抓包看 ClientHello 是否带
renegotiation_info扩展(Wireshark 过滤ssl.handshake.extensions_server_name == "" and ssl.handshake.type == 1) - 若客户端可控,强制其使用
-Djsse.enableSNIExtension=true(Java)或升级到支持 RFC 5746 的 TLS 库 - 用
SSLProtocol -all +TLSv1.2显式禁用 TLS 1.0/1.1(它们更容易暴露 renegotiation 缺陷),逼客户端走更安全路径 - 若只是调试需要,可在测试环境开
SSLInsecureRenegotiation on,但生产环境务必加监控:日志中搜索insecure_renegotiation确认是否真被触发
这个配置项本质是个临时胶带——粘得住老设备,但盖不住协议层缺陷。真正棘手的从来不是怎么开它,而是怎么确认你非开不可,以及开完有没有人记得关。

















