mtls核心是服务端与客户端互相验证身份,需统一私有ca签发证书、服务端强制校验客户端证书(如apache用sslverifyclient require、nginx用ssl_verify_client on),并透传x-client-dn等头供后端鉴权,同时关闭http端点防降级。

SSL 双向认证(mTLS)不是“加个证书就行”,而是让服务端和客户端互相验证身份。核心是:服务端必须要求客户端提供证书,并用可信 CA 公钥验证它;客户端也得信任服务端证书。这比单向 HTTPS 多一层身份把关,适合 API 网关、数据库连接、内部系统集成等高安全场景。
准备统一可信的证书体系
所有证书必须出自同一个私有 CA(不建议用 Let’s Encrypt 等公网 CA,因其通常不签发客户端证书)。关键文件包括:
- CA 根证书(ca.crt):服务端和所有合法客户端都需信任它;
- 服务端证书(server.crt + server.key):CN 或 SAN 必须匹配实际访问域名,私钥权限设为 600;
- 客户端证书(client.crt + client.key):每个调用方单独签发,DN 字段(如 CN、O、OU)应清晰可识别,便于后端鉴权;
- 推荐使用 ECDSA(如 secp256r1)替代 RSA,尤其对移动端或 IoT 设备更轻量高效。
服务端强制校验客户端证书
不同服务组件配置方式略有差异,但逻辑一致:启用 SSL、指定可信 CA、要求客户端提供有效证书。
-
Apache:在虚拟主机中设置
SSLVerifyClient require、SSLCACertificateFile /path/to/ca.crt、SSLVerifyDepth 2; -
Nginx:配置
ssl_verify_client on、ssl_client_certificate /etc/nginx/ssl/ca.crt、ssl_verify_depth 2; -
MySQL:在
my.cnf中启用require_secure_transport = ON,并创建用户时用REQUIRE SUBJECT '/CN=xxx'精确绑定证书 DN; -
SVN(基于 Apache):依赖
SSLVerifyClient require和SSLUserName SSL_CLIENT_S_DN_CN将证书 CN 映射为 SVN 用户名。
把客户端身份可靠传递给后端
服务端验证通过后,需将证书信息透传给上游应用,否则后端无法做细粒度权限控制。
- Apache 可用
RequestHeader set X-Client-CN "%{SSL_CLIENT_S_DN_CN}s"注入请求头; - Nginx 推荐
proxy_set_header X-Client-DN $ssl_client_s_dn和X-Client-Verify $ssl_client_verify; - 后端应校验这些头是否非空、DN 是否在白名单内,不能只依赖 TLS 层——避免中间代理绕过校验。
限制非 mTLS 访问路径
mTLS 只作用于 HTTPS 连接,HTTP 端点必须显式关闭或跳转,防止降级攻击。
- 注释掉
Listen 80或删除 HTTP 虚拟主机; - 若需兼容,用
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]强制跳转; - 对敏感接口(如
/api/private),可在 location 块内单独启用ssl_verify_client on,其他路径保持宽松,兼顾安全与可用性。











