中国移动建立 TLS 连接时根据 Client Hello 的 SNI 被关闭连接

19次阅读

共计 4693 个字符,预计需要花费 12 分钟才能阅读完成。

背景

  • IP 湖北武汉。
  • 电信宽带申请了一个公网 IPV4 地址,光猫拨号并设置 DMZ 分配给了一个 Arm 服务器。
  • 准备搭建 Tailscale 的 Derper 节点来进行虚拟组网。

问题

  • 搭建好 Derper 服务之后,发现移动宽带下的设备无法建立连接。

初步诊断

  • 移动网络下,可以与该电信服务器 SSH、Ping、使用域名访问 Derper 端口的网页。但在 Tailscale 中无法建立连接。
  • 移动网络下,可以与华为云上建立的 Derper 服务器在 Tailscale 中建立连接。
  • 电信网络以及校园网下,可以与该电信服务器的 Derper 服务器在 Tailscale 中建立连接。

抓包诊断

  • 使用 Wireshark 在客户端抓包,发现服务器发送了 RST
No.	Time	Source	Destination	Protocol	Length	Info
23	1.520649	192.168.1.147	27.16.XX	TCP	66	64858 → 10445 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM
24	1.533934	27.16.XX	192.168.1.147	TCP	66	10445 → 64858 [SYN, ACK] Seq=0 Ack=1 Win=32120 Len=0 MSS=1452 SACK_PERM WS=128
25	1.534033	192.168.1.147	27.16.XX	TCP	54	64858 → 10445 [ACK] Seq=1 Ack=1 Win=132096 Len=0
26	1.534275	192.168.1.147	27.16.XX	TLSv1	315	Client Hello (SNI=XX.free.hr)
27	1.541790	27.16.XX	192.168.1.147	TCP	60	10445 → 64858 [RST, ACK] Seq=1 Ack=262 Win=66048 Len=0
28	1.541790	27.16.XX	192.168.1.147	TCP	60	10445 → 64858 [RST] Seq=1 Win=66048 Len=0
29	1.547338	27.16.XX	192.168.1.147	TCP	60	[TCP Window Update] 10445 → 64858 [ACK] Seq=1 Ack=262 Win=31872 Len=0
30	1.547363	192.168.1.147	27.16.XX	TCP	54	64858 → 10445 [RST] Seq=262 Win=0 Len=0

  • 使用 tcpdump 在服务器抓包,传回本地导入 Wireshark 进行分析,发现客户端发送了 RST
No.	Time	Source	Destination	Protocol	Length	Info
353	13.187083	117.154.XX	192.168.31.2	TCP	66	11250 → 33443 [SYN] Seq=0 Win=64240 Len=0 MSS=1452 WS=256 SACK_PERM
354	13.187329	192.168.31.2	117.154.XX	TCP	66	33443 → 11250 [SYN, ACK] Seq=0 Ack=1 Win=32120 Len=0 MSS=1460 SACK_PERM WS=128
355	13.198110	117.154.XX	192.168.31.2	TCP	60	11250 → 33443 [ACK] Seq=1 Ack=1 Win=132096 Len=0
356	13.198594	117.154.XX	192.168.31.2	TLSv1	315	Client Hello (SNI=XX.free.hr)
357	13.198733	192.168.31.2	117.154.XX	TCP	54	33443 → 11250 [ACK] Seq=1 Ack=262 Win=31872 Len=0
358	13.200749	117.154.XX	192.168.31.2	TCP	60	11250 → 33443 [RST, ACK] Seq=1 Ack=1 Win=132096 Len=0
359	13.200749	117.154.XX	192.168.31.2	TCP	60	11250 → 33443 [RST] Seq=262 Win=132096 Len=0
  • 客户端切换到电信网,则不会出现 RST 包
No.	Time	Source	Destination	Protocol	Length	Info
943	5.009217	192.168.236.64	27.16.XX	TCP	66	51705 → 10445 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM
960	5.031696	27.16.XX	192.168.236.64	TCP	66	10445 → 51705 [SYN, ACK] Seq=0 Ack=1 Win=32120 Len=0 MSS=1360 SACK_PERM WS=128
961	5.032256	192.168.236.64	27.16.XX	TCP	54	51705 → 10445 [ACK] Seq=1 Ack=1 Win=131840 Len=0
962	5.033771	192.168.236.64	27.16.XX	TLSv1.3	315	Client Hello (SNI=XX.free.hr)
969	5.058078	27.16.XX	192.168.236.64	TCP	54	10445 → 51705 [ACK] Seq=1 Ack=262 Win=31872 Len=0
970	5.060818	27.16.XX	192.168.236.64	TLSv1.3	2774	Server Hello, Change Cipher Spec, Application Data, Application Data, Application Data
971	5.060818	27.16.XX	192.168.236.64	TLSv1.3	80	Application Data
972	5.060891	192.168.236.64	27.16.XX	TCP	54	51705 → 10445 [ACK] Seq=262 Ack=2747 Win=131840 Len=0
973	5.061203	192.168.236.64	27.16.XX	TLSv1.3	118	Change Cipher Spec, Application Data

  • 客户端在移动网下使用浏览器对该域名进行访问,也不会出现 RST 包
No.	Time	Source	Destination	Protocol	Length	Info
2288	15.006871	192.168.1.147	27.16.XX	TCP	66	60082 → 10444 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM
2290	15.018397	27.16.XX	192.168.1.147	TCP	66	10444 → 60082 [SYN, ACK] Seq=0 Ack=1 Win=32120 Len=0 MSS=1452 SACK_PERM WS=128
2291	15.018469	192.168.1.147	27.16.XX	TCP	54	60082 → 10444 [ACK] Seq=1 Ack=1 Win=132096 Len=0
2292	15.018671	192.168.1.147	27.16.XX	TLSv1.2	1879	Client Hello (SNI=XX.free.hr)
2297	15.027778	27.16.XX	192.168.1.147	TCP	66	[TCP Window Update] 10444 → 60082 [ACK] Seq=1 Ack=1 Win=32128 Len=0 SLE=1453 SRE=1826
2299	15.027778	27.16.XX	192.168.1.147	TCP	60	10444 → 60082 [ACK] Seq=1 Ack=1826 Win=31872 Len=0

猜测

  • RST 包既不是客户端也不是服务端主动发出的,是由中间设备发出。
  • RST 包在服务端收到的延迟比在客户端低,猜测发送的中间设备更加靠近服务端。
  • 浏览器进行 HTTPS 域名访问,不会收到 RST,猜测是识别了 Tailscale 建立连接的 Client Hello 指纹,进行针对性发送 RST.

实验

方法

  • 使用 Python 编写客户端,向服务器建立 TLS 连接

结果

  • 同样收到 RST
No.	Time	Source	Destination	Protocol	Length	Info
9448	66.855063	192.168.1.147	27.16.XX	TCP	66	56190 → 10444 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM
9449	66.867467	27.16.XX	192.168.1.147	TCP	66	10444 → 56190 [SYN, ACK] Seq=0 Ack=1 Win=32120 Len=0 MSS=1452 SACK_PERM WS=128
9450	66.867543	192.168.1.147	27.16.XX	TCP	54	56190 → 10444 [ACK] Seq=1 Ack=1 Win=132096 Len=0
9575	67.787635	192.168.1.147	27.16.XX	TLSv1	571	Client Hello (SNI=XX.free.hr)
9576	67.793835	27.16.XX	192.168.1.147	TCP	60	10444 → 56190 [RST, ACK] Seq=1 Ack=518 Win=66048 Len=0
9577	67.793835	27.16.XX	192.168.1.147	TCP	60	10444 → 56190 [RST] Seq=1 Win=66048 Len=0

分析

  • 使用 Python 建立 TLS 连接的时候,Client Hello 的指纹与 Tailscale、浏览器均不同,但仍然被发送 RST。
  • Python 建立 TLS 的指纹应该是一个很大众的指纹,不可能被针对。如果这都被针对了,那客户端上面运行的其他软件很有可能也无法建立 TLS 连接。
  • 其他软件 Client Hello 中与该 Python 代码发送的区别在于 SNI 不同。
  • 修改 SNI 看是否仍然收到 RST

实验二

方法

  • 在实验一基础上,IP 地址不变,修改 SNI 为 baidu.com

结果

  • 没收到 RST
No.	Time	Source	Destination	Protocol	Length	Info
3670	26.811577	192.168.1.147	27.16.XX	TCP	66	53655 → 10444 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM
3679	26.829037	27.16.XX	192.168.1.147	TCP	66	10444 → 53655 [SYN, ACK] Seq=0 Ack=1 Win=32120 Len=0 MSS=1452 SACK_PERM WS=128
3680	26.829159	192.168.1.147	27.16.XX	TCP	54	53655 → 10444 [ACK] Seq=1 Ack=1 Win=132096 Len=0
4206	30.534391	192.168.1.147	27.16.XX	TLSv1.2	571	Client Hello (SNI=baidu.com)
4207	30.546027	27.16.XX	192.168.1.147	TCP	60	10444 → 53655 [ACK] Seq=1 Ack=518 Win=31872 Len=0

分析

  • 该 RST 的触发与 SNI 有关
  • 对 SNI 进行修改,找出被发送 RST 的 SNI 规律

实验三

方法

  • 修改不同 SNI,看哪些会被发送 RST

结果

  • 包含 free.hr 的 SNI 会被发送 RST

结论

中国移动在对中国电信发送 TLS 请求时,会根据 SNI 判断是否发送 RST 强行关闭 TCP 连接。

正文完
 0