共计 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 连接。
正文完