Apache默认禁用不安全TLS重协商以防范CVE-2009-3555;仅当确需兼容JDK 6u45前版本等老旧客户端且日志明确报renegotiation拒绝时,才在VirtualHost内启用SSLInsecureRenegotiation on,并须严格限制作用范围及配套安全措施。

Apache 默认禁止不安全的 TLS 重协商,这是为了防范 CVE-2009-3555 攻击。但当你对接 JDK 6u45 之前版本、某些嵌入式设备或老 Android WebView 时,它们可能无法发起符合 RFC 5746 的安全重协商,连接会卡在 Re-negotiation requested but not allowed 或直接报 handshake failed。此时才需谨慎启用 SSLInsecureRenegotiation,而非“修复 SSL”。
确认是否真需要开启
不是所有握手失败都源于重协商——先排除证书链、协议版本(如 SSLv3)、SNI 或 CipherSuite 不匹配等更常见原因。只有在日志中明确看到 renegotiation 相关拒绝,且已确认客户端完全无法升级时,才考虑此配置。
- 检查 Apache 错误日志:
grep -i renegot /var/log/apache2/error.log - 用
openssl s_client -connect yoursite.com:443 -reconnect测试:若返回SSL alert number 100或连接中断,说明重协商被拒;若真能进入RENEGOTIATING阶段并完成,则说明已开启或客户端本身支持安全重协商 - 确认客户端环境:JDK < 6u45、OpenSSL < 0.9.8m、旧版 IoT 固件等才真正依赖该开关
在虚拟主机中正确启用
SSLInsecureRenegotiation 是 per-vhost 指令,必须写在启用 HTTPS 的 <VirtualHost> 块内,不能放在全局配置或 .htaccess 中。
- 编辑站点配置文件(如
/etc/apache2/sites-enabled/example.com.conf) - 在已有 SSL 配置段中添加一行:
SSLInsecureRenegotiation on(建议放在SSLCertificateFile和SSLCertificateKeyFile附近,便于维护) - 确保
SSLEngine on已启用,否则该指令不生效 - 重启服务:
sudo systemctl reload apache2(Debian/Ubuntu)或sudo apachectl graceful(RHEL/CentOS)
启用后必须做的安全控制
开启后,Apache 将接受已知存在中间人劫持风险的重协商流程——这不是无代价的兼容,而是有明确攻击面扩大的折中。
- 仅对必要接口启用:不要全局开启,只在对接老旧系统的特定
<VirtualHost>或路径下配置 - 前置 TLS 终止无效:如果用了 Cloudflare、AWS ALB、Nginx 作反代,重协商请求根本到不了 Apache,此配置不起作用,应改在 LB 层处理
- 禁用过时协议:仍要保留
SSLProtocol all -SSLv2 -SSLv3,避免叠加其他漏洞 - 不配合客户端证书认证:若该虚拟主机同时启用了
SSLVerifyClient require,重协商风险会显著放大,应避免组合使用
优先考虑替代方案
直接开 SSLInsecureRenegotiation 是最后手段。更稳妥的做法包括:
- 推动客户端升级:JDK 6u45(2013年发布)已支持安全重协商,多数遗留系统可打补丁而非维持高危通信
- 加一层代理适配:用 Nginx 或 Envoy 在前端做协议转换,让旧客户端连代理,代理再以现代 TLS 连 Apache
- 隔离通信路径:为老旧系统单独分配子域名或端口,并在网络层限制访问源 IP,缩小暴露面
- 验证是否真触发重协商:很多老客户端其实并不主动发起重协商,问题可能出在服务端配置(如强制要求客户端证书)或中间设备干扰


















