sslproxycheckpeercn已失效且不安全,自apache 2.4.8起废弃、2.4.26彻底移除;应改用sslproxycheckpeername on配合sslproxyverify require,依据rfc 6125校验san字段并验证证书链。

SSLProxyCheckPeerCN 不能防止后端中间人冒充攻击,它早已失效,且本身设计就不安全。
这个指令在 Apache 2.4.8 起被标记为废弃,2.4.26 及以后版本彻底移除。如果你在配置中写入:
SSLProxyCheckPeerCN on
Apache 启动时会直接报错:
Invalid command 'SSLProxyCheckPeerCN', perhaps misspelled...
根本原因在于:仅校验证书的 CN(Common Name)字段,既不检查 Subject Alternative Name(SAN),也不遵循现代 TLS 主机名验证标准(RFC 6125)。攻击者只要让后端证书的 CN 碰巧匹配目标域名(哪怕 SAN 为空或错误),就能绕过校验——这完全无法抵御中间人冒充。
✅ 正确做法:用 SSLProxyCheckPeerName 替代
从 Apache 2.4.8 开始,唯一有效、符合安全实践的后端主机名校验方式是:
SSLProxyEngine on SSLProxyVerify require SSLProxyCheckPeerName on SSLProxyVerifyDepth 2
其中关键点:
-
SSLProxyCheckPeerName on:强制依据证书的 SAN 字段(优先)或 CN(仅无 SAN 时回退)做精确主机名匹配 -
SSLProxyVerify require:同时校验证书链有效性(签名、有效期、吊销状态等) - 二者缺一不可:只开
SSLProxyCheckPeerName不校验证书链,仍可能被伪造证书欺骗;只开SSLProxyVerify require不校验主机名,则证书虽合法但可能属于别的域名(如attacker.com)
? 必须配套的配置项
光写上面四行还不够,常见失败全因缺失以下任一环节:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
-
可信 CA 证书必须显式加载
若后端用私有 CA 或自签名证书,必须指定:SSLProxyCACertificateFile /etc/apache2/ssl/backend-ca.crt
系统级信任库(如
/etc/ssl/certs/ca-certificates.crt)默认不生效。 -
后端证书 SAN 必须匹配
ProxyPass目标域名
例如:ProxyPass /api https://payment.internal/
则后端证书的 SAN 中必须包含
DNS:payment.internal—— 仅CN=payment.internal无效,且大小写、尾部点号(.internalvsinternal)都需严格一致。 时间同步至关重要
SSLProxyCheckPeerExpire on(默认启用)要求后端服务器时间误差 ≤ 5 分钟,否则连接直接拒绝,日志只显示模糊的SSL handshake failed。
? 为什么别再找“恢复 SSLProxyCheckPeerCN”的方法?
- 试图通过降级 Apache 版本、回滚模块、或用
LoadModule加载旧模块,不仅无法解决根本风险,还会引入已知漏洞(如 CVE-2009-3555 重协商攻击)、失去 TLS 1.3 支持、并脱离安全更新通道。 - 所有主流发行版(Ubuntu 22.04+、RHEL 8/9、Debian 11+)默认 Apache 均 ≥ 2.4.29,
SSLProxyCheckPeerCN已物理不存在。
✅ 验证是否真正生效
访问代理路径触发后端调用后,检查 Apache 错误日志:
- 成功校验:无相关错误
- SAN 不匹配:出现
SSL Proxy: Peer certificate does not match hostname - CA 不可信:出现
unable to get local issuer certificate或certificate signed by unknown authority
也可用命令快速测试后端证书是否满足要求:
openssl s_client -connect payment.internal:443 -servername payment.internal 2>/dev/null | openssl x509 -noout -text | grep -A1 "Subject Alternative Name"
确保输出中包含 DNS:payment.internal。
不复杂但容易忽略。










