mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6mobile wallpaper 7mobile wallpaper 8mobile wallpaper 9mobile wallpaper 10mobile wallpaper 11mobile wallpaper 12mobile wallpaper 13mobile wallpaper 14mobile wallpaper 15mobile wallpaper 16mobile wallpaper 17mobile wallpaper 18mobile wallpaper 19mobile wallpaper 20mobile wallpaper 21mobile wallpaper 22
2148 字
6 分钟
理解 mTLS:客户端证书到底是怎么工作的
2026-05-29

本文中的域名、IP 地址、路径、Token 等信息均已脱敏处理。

很多人在把自己的服务暴露到公网以后,都会遇到一个问题:

除了账号密码之外,还有没有办法再增加一层保护?

例如:

  • 浏览器导航页
  • 私人部署的密码库
  • 某个服务的管理面板
  • NAS
  • 各种自建服务等等

这些服务大多都有自己的登录系统。

但只要地址暴露在公网里,理论上任何人都能访问到登录页面。

虽然未必能登录成功,但入口始终是开放的,这就多了一个攻击面多了一层隐患。

于是很多人都会开始寻找一种额外的访问控制方法。


常见方案为什么不一定适合#

IP 白名单#

最容易想到的方案就是 IP 白名单。

例如:

只允许:
203.0.113.10
198.51.100.20

访问服务。

这种方案简单直接,而且安全性也不错,在早期的互联网环境可用性还是不错的。

但在今天的网络环境里,它已经不再适合。

因为:

  • 家宽通常是动态 IP 或干脆是运营商的大内网 IP
  • 就算是手机流量,那出口地址也是会不断变化的
  • 外出连接其他网络时 IP 则又完全不同
  • 就算是 IPv6 前缀也可能发生变化

结果就是:

每换一次网络、刷新一次 IP ,就需要重新维护白名单。

对于经常在不同设备、不同网络之间切换的人来说,这种方式并不方便。


HTTP 认证#

另一种常见方案是 HTTP Basic Authentication。

Nginx 就能直接实现。

访问网站时,浏览器会先弹出认证窗口:

Username:
Password:

输入正确的账号密码后才能继续访问。

这种方案确实有效。

但也存在一些问题。

首先,很多应用本身已经带有登录系统。

于是访问流程会变成:

HTTP 认证
应用登录

两套认证同时存在,访问登录过程繁琐。

其次,并不是所有客户端都对 HTTP 认证支持良好。

大多浏览器通常没有问题。

但移动端 App、桌面客户端、浏览器扩展等场景,体验未必一致,因为软件作者大多都不会适配。

对于一些需要多端访问的服务来说,这会带来额外的兼容性问题。


VPN#

还有一种思路。

干脆不开放公网。

把所有服务都放到 VPN 后面。

例如:

  • WireGuard
  • Tailscale
  • ZeroTier

这种方案的安全性很高。

因为不连接 VPN,理论上就无法访问内部服务。

但它的问题在于:

如果只是为了访问某一个服务,就把整套系统的网络流量一起切进 VPN,那代价有点高。

因为实际使用时,设备并不会只做这一件事,你的后台可能还有:

  • 下载任务
  • 文件同步
  • 系统更新
  • 消息推送

等各种网络活动。

这时候为了访问某个服务,就让整台设备都挂在 VPN 网络里,那可不太划算。

因此 VPN 更适合构建完整的私有网络。

而不一定适合作为某个单独服务的访问控制方案。


客户端证书是什么#

客户端证书提供了另一种思路。

它不是在应用层做认证。

而是在 TLS 握手阶段完成认证。

也就是说:

在网页打开之前。

在登录页面出现之前。

甚至在 HTTP 请求发送之前。

服务器就已经能够判断:

  • 客户端是否携带证书
  • 证书是否可信
  • 是否允许访问

这套机制被称为:

mTLS
(Mutual TLS)

也就是双向 TLS 认证。


普通 HTTPS 做了什么#

理解 mTLS 之前,需要先理解普通 HTTPS。

当浏览器访问:

https://example.com

时,首先会进行 TLS 握手。

服务器会把自己的证书发送给浏览器。

浏览器随后验证:

  • 证书是否可信
  • 域名是否匹配
  • 是否在有效期内
  • 证书链是否完整

验证通过以后,连接继续建立。

整个过程中:

客户端验证服务器。

服务器并不会验证客户端身份。

因此普通 HTTPS 解决的问题是:

你访问的是否是真正的服务器。

而不是:

访问服务器的人是谁。


mTLS 多做了一步什么#

mTLS 在普通 HTTPS 的基础上增加了一步:

服务器要求客户端也出示证书。

TLS 握手过程中,服务器会发送:

Certificate Request

要求客户端提供证书。

如果客户端没有证书。

或者证书无法通过验证。

连接会被服务器直接拒绝。

因此:

普通 HTTPS
=
服务器证明自己
mTLS
=
服务器证明自己
+
客户端证明自己

这也是 mTLS 名字中“Mutual(双向)”的来源。


mTLS 的证书体系#

一个典型的 mTLS 环境通常包含三类证书。

CA 根证书#

CA(Certificate Authority)负责签发证书。

在自建环境中,很多人会创建自己的私有 CA(是的,我就是)。

后续所有服务器证书和客户端证书都由它签发。

它相当于整个信任体系的根节点。


服务器证书#

服务器证书用于证明服务器身份。

例如:

panel.example.com
vault.example.com
git.example.com

浏览器访问网站时,会首先验证这张证书。


客户端证书#

客户端证书用于证明客户端身份。

它可以签发给:

  • 电脑
  • 手机
  • 平板

等设备。

服务器通过验证客户端证书来决定是否允许访问。


TLS 握手过程中发生了什么#

整个过程可以简化为下面几个步骤。

第一步#

客户端访问网站:

https://panel.example.com

开始 TLS 握手。


第二步#

服务器发送自己的证书。

客户端验证:

  • 域名
  • 有效期
  • 签名
  • 信任链

这一步与普通 HTTPS 完全相同。


第三步#

服务器发送:

Certificate Request

要求客户端出示证书。

这是 mTLS 独有的步骤。


第四步#

客户端从本地证书库中选择合适的证书。

然后发送给服务器。

通常导入设备的证书格式为:

.p12
.pfx

第五步#

服务器使用自己的 CA 证书验证客户端证书:

  • 是否由指定 CA 签发
  • 是否过期
  • 是否有效

如果验证失败。

连接会被服务器直接拒绝,TLS 握手无法继续完成。


第六步#

验证成功后。

TLS 握手完成。

双方开始建立加密连接并传输数据。


Nginx 如何启用 mTLS#

在实际部署中。

最常见的做法是由 Nginx 完成客户端证书验证。

配置通常类似:

ssl_client_certificate /etc/nginx/certs/ca.crt;
ssl_verify_client on;
ssl_verify_depth 2;

含义分别是:

ssl_client_certificate#

指定用于验证客户端证书的 CA。


ssl_verify_client on#

要求客户端必须提供有效证书。


ssl_verify_depth#

控制证书链验证深度。


mTLS 适合哪些场景#

mTLS 并不适合所有网站。

公开网站通常没有必要这样做。

但对于:

  • 浏览器导航页
  • 私人部署的密码库
  • 某个服务的管理面板
  • NAS
  • 各种自建服务等等

这类只允许少数或单一用户访问的服务。

它非常合适。

因为它能够把访问控制提前到 TLS 握手阶段。

在应用真正开始处理请求之前,就先完成身份验证。


小结#

普通 HTTPS 解决的是:

服务器是不是真的。

而 mTLS 进一步解决的是:

客户端是不是被允许访问。

它不依赖固定 IP。

不需要额外增加一层 HTTP 认证。

也不要求整套网络都接入 VPN。

而是在 TLS 握手阶段完成客户端身份验证。

对于需要将私有服务暴露到公网,但又希望增加额外保护的人来说,mTLS 是一种值得了解的方案。


实战:#

《使用客户端证书保护 Sun-Panel》

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

部分信息可能已经过时

目录