«

如果访问 Google,收到百度的证书,会有怎样的现象发生?

时间:2025-7-8 10:15     作者:wanzi     分类: 网络


最近在学习 Wireshark 抓包,想看看 TLS 握手过程中都传了些什么,然后在做一个简单的 HTTPS 请求测试时,突然冒出了一个奇怪的想法:

如果我明明是访问 google.com,但中间有人把请求偷偷重定向到了 www.baidu.com:443,那么服务器会怎么处理?会直接报错?还是返回一些奇怪的数据?


01 - 初步实验

为了验证这个问题,我做了如下操作:

iptables 简单重定向

可以用 iptables 把目标地址为 google.com 的 443 端口请求转到百度:

先解析百度的 IP

dig +short www.baidu.com # 假设结果是 220.181.38.150

iptables 添加重定向规则(假设外网访问走 eth0):

sudo iptables -t nat -A OUTPUT -p tcp -d google.com --dport 443 -j DNAT --to-destination 220.181.38.150:443

或者直接写 IP:

sudo iptables -t nat -A OUTPUT -p tcp -d 142.250.4.113 --dport 443 -j DNAT --to-destination 220.181.38.150:443
如果是给 本地 curl 请求生效,还需要给 本地流量(lo)或 OUTPUT 链 添加。

⚠️ 注意:

这种做法只是强制把 TCP 连接发给百度,不能改变 HTTPS 协议里的 SNI 字段。curl、浏览器仍然以 google.com 为目标主机名发起 TLS 握手。

然后打开 Wireshark,看看 TLS 层的通信情况。

02 - 实验结果

非常有趣的是:

* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLS certificate verification: CERT_NAME_INVALID
* error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed
* Closing connection
curl: (60) SSL certificate problem: certificate has expired or is not yet valid

那么,百度怎么办?

百度自然不可能有 google.com 的证书,它按照惯例,返回了自己的 HTTPS 证书,证书里写着「*.baidu.com」。

于是,客户端一看:

“你给我的是 baidu.com 的证书,我要的是 google.com,证书不匹配,安全风险,连接失败!”


03 - 这是不是服务器的「错误行为」?

并不是。这正是大多数 HTTPS 服务器的标准行为。

在收到 SNI 后,服务器会:


04 - 为什么不直接拒绝?

你可能会问:

“服务器为什么不直接断开连接,说:我没有 google.com 的证书?”

原因很简单:

当然,一些高安全场景,可以配置服务器直接拒绝,比如:


简单理解下tls协议流程:

服务器如何处理 SNI

HTTPS 建立过程的第一步是 客户端发起 TLS ClientHello,里面包含了:

服务器拿到 ClientHello 后会:

  1. 检查是否有对应 SNI 的证书
  2. 如果有,比如:

    • SNI 是 www.baidu.com,服务器配置了 baidu.com 的证书 → 返回 baidu 的证书
    • SNI 是 google.com,但服务器根本没配 google.com 的证书
  3. 那么服务器只能:

    • 返回「默认证书」 → 一般就是 第一个配置的证书,或默认站点证书
    • 通常是 baidu.com 的证书

⚠️ 没有 “不给证书” 这种操作,因为 TLS 协议要求必须返回证书完成握手,除非直接断开连接(那就是拒绝服务了)。


🔍 为什么是默认证书而不是直接拒绝?

因为:

✔️ 这是为了:

SNI 只是「建议」,服务器只会返回它有的证书;没有就用默认的,TLS 协议不会因为 SNI 不存在就拒绝握手,但客户端会因为证书不对而中断。


05 - 一次有趣的误会

所以,这个实验的结果也挺有趣的:

我问“google.com”是谁,百度虽然不认识,但还是礼貌地递给我一张自己的名片,客户端一看,名字不对,直接拒绝了。


06 - 小结