Apache双向认证需同时配置SSLCACertificateFile、SSLVerifyClient require及服务端证书私钥三要素,限定于业务路径启用,结合OCSP吊销检查与RequestHeader透传身份信息。

要在Apache中通过mod_ssl实现企业级内部系统的双向认证,关键不是只加一句SSLVerifyClient require,而是构建一套完整、可验证、可运维的信任链和控制逻辑。配置错误会导致500错误、403拒绝或形同虚设,尤其在内部系统中,权限误放风险极高。
必须配齐三要素,缺一不可
仅设置SSLVerifyClient require会触发500错误,日志报peer did not return a certificate——这不是客户端问题,是服务端缺失信任锚。真正起效需同时满足:
-
SSLCACertificateFile:指向包含根CA和/或中间CA证书的PEM文件(不能含私钥、空行或多余字符),权限设为600,属主为Apache运行用户(如
www-data); - SSLVerifyClient require:强制客户端提供证书并完成签名验证,生产环境唯一推荐值;
-
SSLCertificateFile + SSLCertificateKeyFile:服务端自身有效的证书与未加密私钥(若私钥加密,需配置
SSLPassPhraseDialog)。
按业务路径启用,避免全局误伤
把SSLVerifyClient require放在整个虚拟主机里,会让CSS、JS、图片等静态资源也强制验签,浏览器通常不自动发送证书,结果大量403,还拖慢首屏加载。正确做法是限定到真实需要认证的接口路径:
- 在
<Location "/api/v2/">或<Directory "/var/www/app/backend">块内配置SSLVerifyClient require; - 搭配
SSLRequireSSL确保该路径只走HTTPS; - 如需基于证书字段做权限控制,用现代
Require指令替代已废弃的SSLRequire,例如:Require expr %{SSL_CLIENT_S_DN_OU} == 'Finance' && %{SSL_CLIENT_VERIFY} == 'SUCCESS'。
增强可信性:加入吊销检查
仅验证签名和有效期不够,企业场景必须确认证书未被主动撤销。两种主流方式选其一:
-
OCSP Stapling(推荐):在Apache中启用
SSLUseStapling on,并配置SSLStaplingCache,由服务端定期向CA OCSP服务器查询并缓存结果,握手时直接“钉”给客户端,低延迟且隐私友好; -
CRL文件校验:用
SSLCARevocationFile指定CRL PEM文件,并配合SSLCARevocationCheck chain,但需定期更新CRL,运维成本较高。
向后端安全透传身份信息
Apache验证通过后,需把可信的证书信息交给后端应用(如Java Tomcat、PHP或Node.js),不能依赖原始请求头。标准做法是用RequestHeader注入环境变量内容:
-
RequestHeader set X-Client-DN "%{SSL_CLIENT_S_DN}s"; -
RequestHeader set X-Client-Verify "%{SSL_CLIENT_VERIFY}s"; -
RequestHeader set X-Client-Serial "%{SSL_CLIENT_M_SERIAL}s"。
后端据此提取CN、OU、序列号等字段做RBAC或审计,无需自己解析证书。
不复杂但容易忽略


















