必须设为SSLProxyVerify require,否则后端HTTPS连接不校验证书;开启后报500或连接重置,根源在于TLS握手被后端证书拦截,需同时满足CA证书可读可用、后端证书SAN与ProxyPass域名完全匹配、时间偏差±5分钟内,且SSLProxyVerify require与SSLProxyCheckPeerName on必须协同启用。

必须设为 SSLProxyVerify require,否则后端 HTTPS 连接不校验证书,等同于裸奔。
为什么 SSLProxyVerify require 一开就报 500 或连接重置
这不是配置写错了,而是 Apache 在 TLS 握手阶段被后端证书“拦下来”了。它不关心你的 ProxyPass 写得多准,只认三件事是否齐备:
-
SSLProxyCACertificateFile指向的 CA 证书文件存在、可读(www-data或apache用户有权限),且内容是 PEM 格式纯根证书(不能混私钥、不能多空行、不能带注释) - 后端证书的 SAN(Subject Alternative Name)中至少有一项与
ProxyPass目标域名完全一致 —— 仅 CN 匹配无效,例如ProxyPass /api https://svc.internal/,证书里必须有DNS:svc.internal - 后端服务器时间偏差不超过 ±5 分钟;
SSLProxyCheckPeerExpire on(默认开启)会严格校验有效期,误差大了直接断连,日志里却只显示模糊的SSL handshake failed
SSLProxyVerify 和 SSLProxyCheckPeerName 是两回事
很多人以为开了 SSLProxyVerify require 就自动校验主机名,其实不是:
-
SSLProxyVerify require只管证书链是否可信(签名、CA、有效期、吊销状态) -
SSLProxyCheckPeerName on才负责比对域名 —— 它从 Apache 2.4.8 起成为唯一有效机制,SSLProxyCheckPeerCN已彻底移除,写了会启动失败 - 两者必须同时启用才构成完整校验:一个保身份,一个保归属
调试时别靠猜,用 openssl s_client 复现 Apache 的行为
Apache 报错含糊,但 openssl 会把问题摊开:
- 模拟握手:
openssl s_client -connect svc.internal:443 -CAfile /path/to/your/ca-bundle.pem - 如果返回
verify error:num=20:unable to get local issuer certificate,说明 CA 文件没加载对或缺中间证书 - 如果返回
CN = wrong.host或subjectAltName does not match,就是后端证书 SAN 不匹配,得让后端重签 - 加
-servername svc.internal参数还能验证 SNI 是否被正确发送(某些老客户端或负载均衡器会干扰)
最常被忽略的一点:Apache 默认不读系统级 CA 信任库(如 /etc/ssl/certs/ca-certificates.crt)。哪怕后端证书是 Let’s Encrypt 签的,也得显式用 SSLProxyCACertificateFile 指向你本地的 bundle —— 否则 require 就是纸面要求。


















