SSLProxyVerify 是 Apache mod_ssl 中控制反向代理连接上游 HTTPS 服务时是否校验其证书的指令,必须设为 require 才能强制验证证书链、域名匹配和签名可信度,否则存在中间人攻击风险。

SSLProxyVerify 是什么,为什么必须设为 require
SSLProxyVerify 是 Apache mod_ssl 提供的代理模式下对后端 HTTPS 服务端证书的校验开关。它不控制 Apache 自己对外暴露的证书,而是管 Apache 作为反向代理时「连接上游 HTTPS 服务」是否验证对方身份。默认值是 none,即完全跳过校验 —— 这会让中间人攻击(MITM)畅通无阻,尤其在对接内部微服务或第三方 API 时风险极高。
必须设为 require 才能强制校验后端证书链有效性、域名匹配和签名可信度。只设 optional 或 optional_no_ca 等同于没开校验,别被名字误导。
配置 SSLProxyVerify require 的最小必要步骤
光写 SSLProxyVerify require 不够,它依赖完整证书信任链。漏掉任一环节都会导致代理请求直接失败(500 错误或 Connection reset),且错误日志里往往只报 SSL handshake failed,不提具体缺啥。
- 确保已启用
mod_ssl和mod_proxy(含mod_proxy_http) - 在对应
<virtualhost></virtualhost>或<proxy></proxy>块中添加:SSLProxyVerify require<br>SSLProxyCheckPeerCN off<br>SSLProxyCheckPeerName on<br>SSLProxyCheckPeerExpire on
-
SSLProxyCACertificateFile或SSLProxyCACertificatePath必须指向包含后端服务器 CA 根证书的 PEM 文件(不是你自己的证书!) - 若后端用私有 CA(如企业内部 PKI),该 CA 证书必须显式加载,系统级 CA 信任库(如 /etc/ssl/certs/ca-certificates.crt)默认不生效
常见失败原因和对应修复
启用 SSLProxyVerify require 后 500 报错最常源于三类问题,按出现频率排序:
-
CA 证书路径错误或权限不足:Apache 进程用户(如 www-data)读不到
SSLProxyCACertificateFile指定的文件,检查ls -l和 SELinux 上下文(RHEL/CentOS) -
后端证书 SAN 不匹配:
SSLProxyCheckPeerName on要求证书 Subject Alternative Name(SAN)中至少有一个条目与 ProxyPass 目标域名完全一致。例如ProxyPass /api https://svc.internal/,则后端证书必须含DNS:svc.internal,仅 CN 匹配无效 -
时间偏差:后端服务器系统时间误差超过 5 分钟,会导致
SSLProxyCheckPeerExpire on拒绝连接,且错误信息极不直观
调试技巧:快速定位证书链问题
别靠猜。用 openssl s_client 模拟 Apache 的握手行为:
openssl s_client -connect svc.internal:443 -CAfile /path/to/your/ca-bundle.pem
如果这步失败,Apache 必然失败。重点看输出末尾的 Verify return code:
-
0:成功(Apache 应该能过) -
2:无法获取发行者证书(SSLProxyCACertificateFile缺失或内容不对) -
18:自签名证书未被信任(后端用了自签证书但没把它的根证书加进 CA bundle) -
21:验证时证书过期(后端证书真的过期了,或时间不同步)
Apache 日志等级调到 debug(LogLevel ssl:debug proxy:debug)后,会打印更细粒度的证书解析过程,但先跑通 openssl 再看日志更高效。
真正难的是私有 CA 场景下的证书分发一致性 —— 后端轮换证书时,所有代理节点的 SSLProxyCACertificateFile 必须同步更新,否则某台机器突然就 500,排查起来像找幽灵bug。

















