sslverifydepth必须严格匹配客户端证书链结构,设错将导致合法客户端被拒或安全失效;启用双向tls认证且证书由多级ca签发时需调整,应通过openssl统计链中证书总数减1确定值,并同步配置sslverifyclient require、sslcacertificatefile及正确权限。

ssl_verify_depth(Apache 中为 SSLVerifyDepth)不是调优参数,而是精确匹配项——它必须严格对应你实际部署的客户端证书链结构,既不能凭经验放大,也不该保守设小。设错直接导致合法客户端被拒或安全边界失效。
什么情况下需要调整 SSLVerifyDepth
- 你启用了双向 TLS 认证(即
SSLVerifyClient require) - 客户端证书由多级 CA 签发(非自签、非根 CA 直签)
- Apache 报错:
unable to get local issuer certificate、certificate chain too long或返回 403 - 你更换了内网 PKI 架构(例如从单级中间 CA 升级为两级)
它不适用于单向 HTTPS(服务端证书校验)、反向代理后端校验(那是 SSLProxyVerifyDepth 的职责),也不影响性能调优或缓存策略。
怎么确定该填多少(不是猜,是查)
用 OpenSSL 直接解析客户端证书链:
openssl crl2pkcs7 -nocrl -certfile client-full-chain.pem | openssl pkcs7 -print_certs -noout
数输出中 BEGIN CERTIFICATE 出现的次数 —— 这就是整条链包含的证书总数(含终端证书)。SSLVerifyDepth 值 = 该总数 − 1(因为深度统计的是“向上追溯的签发者层级”,不包括终端证书本身)。
常见对照:
- 自签名客户端证书(1 张证书)→
SSLVerifyDepth 0 - 根 CA 直签(终端 + 根)→
SSLVerifyDepth 1(默认值,但极少单独使用) - Let’s Encrypt 或 DigiCert 签发的客户端证书(终端 + 中间 CA + 根 CA)→ 实际链长 3 →
SSLVerifyDepth 2 - 企业三级 PKI(终端 → 部门 CA → 公司 CA → 根 CA)→ 链长 4 →
SSLVerifyDepth 3
⚠️ 注意:
SSLVerifyDepth 3不代表“允许 3 层中间 CA”,而是“最多向上追溯 3 级签发者”,即终端证书可经 3 次签名跳转抵达可信根。超过此深度的链会被截断并拒绝。
必须同步配置的三项(缺一不可)
仅改 SSLVerifyDepth 不生效,Apache 会静默跳过验证或报 500 错误:
-
SSLVerifyClient require:强制启用客户端证书校验(optional或optional_no_ca不触发深度检查) -
SSLCACertificateFile /path/to/trusted-cas.pem:PEM 文件必须包含所有参与链路的非终端证书(即全部中间 CA + 根 CA),顺序无关,但缺一个就断链 - 证书文件权限正确:Apache 工作进程用户(如
www-data)需有读取权限;SELinux 启用时需确认上下文(ls -Z)
常见错误与应对
客户端连接失败,error_log 显示
unable to get local issuer certificate
→ 检查SSLCACertificateFile是否遗漏某一级中间 CA,而非盲目调高SSLVerifyDepth设置
SSLVerifyDepth 5后看似“通了”,但实际接纳了可疑长链
→ 生产环境建议上限为 3;深度 ≥ 4 的链应视为异常,需审计签发策略使用 Let’s Encrypt 客户端证书却设
SSLVerifyDepth 1
→ 必然失败,因其标准链为“终端 ← R3 ← ISRG Root X1”,需设为 2在
<directory></directory>块中配置但未在<virtualhost></virtualhost>启用SSLEngine on
→ 指令被忽略,需确保 HTTPS 虚拟主机已激活且监听 443 端口











