在普通 HTTPS 中,只有服务器用证书证明身份。客户端(浏览器)是匿名的——服务器不知道是谁在连接。
**双向 TLS(mTLS)**增加了第二步:客户端也出示证书。双方相互认证。服务器根据受信任的 CA 验证客户端证书,客户端验证服务器的——因此称为”双向”。
普通 TLS vs 双向 TLS
| 普通 TLS | 双向 TLS(mTLS) | |
|---|---|---|
| 服务器证明身份 | ✅ 证书 + CA 签名 | ✅ 相同 |
| 客户端证明身份 | ❌ 匿名 | ✅ 客户端证书 |
| 认证方式 | 单向(仅服务器) | 双向(双方) |
| 使用场景 | 公开网站 | 内部 API、零信任 |
| 客户端需要 | 仅浏览器 | 证书 + 私钥 |
| 配置复杂度 | 标准 | 较高——需要管理客户端证书 |
何时使用 mTLS
服务间通信
微服务之间通过网络相互通信。mTLS 确保只有授权的服务才能连接——不是任何知道 URL 的人。
Service A ←──mTLS──→ Service B
Both verify: "Are you who you claim to be?"
零信任架构
在零信任中,没有网络连接是默认受信任的——即使在企业网络内部。mTLS 用基于身份的信任(证书)取代基于网络的信任(防火墙、VPN)。
API 安全
超越 API 密钥保护敏感 API。被窃取的 API 密钥任何人都能使用。客户端证书绑定到特定私钥——更难窃取和使用。
物联网设备认证
设备在制造时预置客户端证书连接到后端。服务器知道它在与真实设备通信,而非伪造的。
mTLS 的工作原理
- 客户端连接并发起 TLS 握手(与普通 TLS 相同)
- 服务器发送其证书 —— 客户端验证(与普通 TLS 相同)
- 服务器请求客户端证书 —— 发送
CertificateRequest消息 - 客户端发送其证书 —— 服务器根据受信任的 CA 验证
- 双方计算会话密钥,加密通信开始
步骤 3-4 使其成为”双向”。
Nginx mTLS 配置
server {
listen 443 ssl;
server_name api.example.com;
# Server certificate (same as regular HTTPS)
ssl_certificate /etc/ssl/server-fullchain.pem;
ssl_certificate_key /etc/ssl/server-privkey.pem;
# Client certificate verification
ssl_client_certificate /etc/ssl/client-ca.pem; # CA that signed client certs
ssl_verify_client on; # Require client cert
# Optional: pass client cert info to your app
proxy_set_header X-Client-DN $ssl_client_s_dn;
proxy_set_header X-Client-Verify $ssl_client_verify;
}
mTLS vs 其他认证方式
| 方式 | 安全级别 | 复杂度 | 最适合 |
|---|---|---|---|
| API key | 低(可共享) | 低 | 公开 API、速率限制 |
| OAuth/JWT | 中 | 中 | 面向用户的 API |
| mTLS | 高(密码学绑定) | 高 | 服务间通信、零信任 |
| mTLS + JWT | 最高 | 高 | 传输层和应用层双重认证 |
mTLS 与 GetHTTPS
GetHTTPS 签发的是服务器证书——你的 Web 服务器用来证明身份的证书。这是所有 HTTPS 网站使用的标准 SSL 证书。
mTLS 的客户端证书通常由私有 CA(你组织的内部 CA)签发,而非像 Let’s Encrypt 这样的公共 CA。Let’s Encrypt 不签发客户端证书——它们只为公共域名签发服务器证书。
常见问题
能用 Let’s Encrypt 做 mTLS 吗?
服务器证书:可以。客户端证书:不行。客户端证书需要由你控制的私有 CA 签发——由你决定哪些客户端被授权。openssl、cfssl 或 step-ca 等工具可以充当你的私有 CA。
mTLS 和”客户端证书认证”是同一个东西吗?
是的。“双向 TLS”、“mTLS”、“双向 TLS”和”客户端证书认证”都指同一个东西——双方在 TLS 握手时都出示证书。
mTLS 能替代 API 密钥吗?
可以,但它们服务于不同目的。mTLS 证明的是传输层身份(哪个服务在连接)。API 密钥/JWT 证明的是应用层身份(哪个用户/权限)。许多系统同时使用两者以实现纵深防御。
mTLS 常用在哪里?
Kubernetes(使用 Istio/Linkerd 的服务网格)、Cloudflare Access、AWS API Gateway(双向 TLS)、Google Cloud 的 BeyondCorp,以及大多数企业零信任实现。