双向tls认证要求客户端和服务器相互验证身份:服务器用client-verify-ca指定的ca根证书验证客户端证书,且必须设置client-verify=required;服务器自身需配置pem-file证书供客户端验证。

服务器身份认证本身不依赖客户端证书——那是客户端身份认证的职责。你真正需要的,是让服务器能验证来访客户端的身份,也就是实现“客户端证书认证”,它通常作为双向 TLS(mTLS)的一部分运行。
为什么服务器要验证客户端证书?
这不是为了证明“服务器是谁”,而是为了确保只有持有合法证书的客户端才能接入。适用于内部 API、微服务间调用、管理后台、金融或医疗类敏感接口等场景。它比账号密码或 Token 更难伪造,且在传输层完成校验,不依赖应用逻辑。
关键点:
- 服务器必须配置受信任的 CA 根证书(
client-verify-ca),用于验证客户端证书是否由该 CA 签发 - 必须启用强制校验(
client-verify = required),否则客户端可选择不提供证书 - 服务器自身仍需配置自己的证书和私钥(
pem-file),这是单向 TLS 的基础,也供客户端验证服务器身份
核心配置项(以 hitch 为例)
hitch 是轻量、高性能的 TLS 终止代理,常用于前置认证。其客户端证书认证只需两个关键参数:
-
client-verify = required:必须提供且验证通过,否则拒绝连接 -
client-verify-ca = "/etc/hitch/client-ca.pem":指定签发客户端证书的 CA 公钥(根证书或中间证书链),不能是客户端自己的.crt
注意:client-verify-ca 文件里放的是 CA 的公钥(即 ca.crt),不是客户端的证书;服务器不需要也不应该持有每个客户端的 .crt 文件。
证书体系怎么搭才合理?
不要用同一个证书文件既当服务器证书又当客户端证书。标准做法是分三层:
-
CA 根证书(
ca.crt+ca.key):离线保管,只用于签发其他证书 -
服务器证书(
server.crt+server.key):由 CA 签发,部署在 hitch/Nginx 等代理上 -
客户端证书(
client.crt+client.key):同样由同一 CA 签发,分发给可信终端(如服务实例、运维工具、专用客户端)
所有参与方(服务器和每个客户端)都必须信任同一个 CA 根证书(ca.crt)。客户端用它验服务器,服务器用它验客户端。
常见验证失败原因
连接被拒或报 “SSL handshake failed” 时,优先检查:
- 客户端是否在请求中正确携带了
.crt和.key(例如 HTTPX 的cert=()、curl 的--cert和--key) - 服务器配置的
client-verify-ca是否为 PEM 格式、内容完整、权限可读 - 客户端证书是否在有效期内、未被吊销、CN 或 SAN 匹配策略(部分服务会校验)
- 客户端证书是否确实由
client-verify-ca对应的 CA 签发(可用openssl verify -CAfile ca.crt client.crt验证)











