V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
piaoyang
V2EX  ›  程序员

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

  •  1
     
  •   piaoyang · 190 天前 · 2857 次点击
    这是一个创建于 190 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    • 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 连接。

    第 1 条附言  ·  190 天前
    补充解决办法:从 xx.free.hr 域名换成了 xx.cloudns.org 域名就没有问题了。
    23 条回复    2024-08-16 14:42:22 +08:00
    piaoyang
        1
    piaoyang  
    OP
       190 天前
    反正真的很离谱。写下来希望能够对之后遇到同样问题的人有帮助。
    cyaki
        2
    cyaki  
       190 天前
    河南福建等地区访问境外网站时, 也会遇到 TLS Client Hello 包发出后, 被 RST 的问题
    yyzh
        3
    yyzh  
       190 天前
    没啥.移动的墙中墙就是这样的.这个应该是网络白名单的测试吧.
    yinmin
        4
    yinmin  
       190 天前 via iPhone
    是不是用了国外免费的 ddns 服务? 改成自己域名试试
    povsister
        5
    povsister  
       190 天前
    这域名被反诈了大概,你试试 http 访问会不会跳转到反诈提醒劫持页面。TLS 没办法劫持就只能 RST 了。
    国内 ISP 对于一些奇奇怪怪域名各地策略都不一样
    june4
        6
    june4  
       190 天前
    我的网站用户就有不少报告打不开我的网站(网站在国外),网站本身没被墙,不同域名结果不同,且同一域名也有时能打开有时不能,似乎是近一年内的事
    nivalxer
        7
    nivalxer  
       190 天前 via iPhone
    是的,移动会这么搞。前段时间我们搬办公室,移动专线,之前接入备案做了的。搬过去 IP 变化要重新做接入备案,在做备案这几天,端口和域名都被 RST 阻断了,测试结果相同,即其他地区正常,同地区移动,电信,联通,云商访问都 RST 阻断。完成接入备案后就恢复了。
    totoro625
        8
    totoro625  
       190 天前
    华为云上建立的 Derper 服务器用的域名是备案域名吗?
    必须是大企业的域名才能免于 RST 的话,域名伪装大有可图
    piaoyang
        9
    piaoyang  
    OP
       190 天前
    @cyaki 境外网站被 RST 是有心理准备的。但是我这连武汉市都没出,就是武汉移动访问武汉电信,都被 RST 了,真的是完全没有预料到。
    @yyzh 服了,第一次遇到。一开始让我最摸不着头脑的就是浏览器中 HTTPS 可以正常访问。
    @yinmin 这个 free.hr 域名是我自己的,托管在 Cloudflare 上面在。用自己写的脚本做的 DDNS 。
    @povsister 从浏览器发起 HTTP 和 HTTPS 请求都不会被 RST
    @june4 奇奇怪怪的。没出武汉都遇到问题。
    @nivalxer 如果突然遇到这个问题,真的是没头绪。
    @totoro625 你这么一说,我想起来华为云上面是直接用的 IP ,没用域名。把 Derper 的证书检验关掉了。
    uiiytwyfsdtr
        10
    uiiytwyfsdtr  
       190 天前
    sni 的这个东西 墙很早就开始搞了

    所以 dns 包括 client hello 都一定要加密
    totoro625
        11
    totoro625  
       190 天前
    @piaoyang #9 免费域名用的人多被拉黑了,自备一个备案域名
    xqzr
        12
    xqzr  
       190 天前
    浏览器的 TLS CH ,比较长,可能被 TCP 分段
    wu67
        13
    wu67  
       190 天前
    广州移动还会掐 sftp 流量呢, 流量大一点直接无响应
    Navee
        14
    Navee  
       190 天前
    这周开始也遇到了类似的问题
    e3c78a97e0f8
        15
    e3c78a97e0f8  
       190 天前
    我用的 duckdns.org 的子域名,在移动下也是 SNI 阻断
    NewYear
        16
    NewYear  
       190 天前   ❤️ 1
    1 、国内服务器使用未备案域名的 TLS 连接,会拦截,已经有样本了
    2 、试试看用已备案域名,自签名证书。

    正常情况是要用已备案的域名
    nivalxer
        17
    nivalxer  
       190 天前
    @piaoyang 移动是这样的。我们还是公司核心的外网邮件系统,下班后被封的,查了 1 小时才判断出来原因。还好我们之前有经验多申请了一个 IP 作为备线,临时切换到备线解决。
    oumayo
        18
    oumayo  
       190 天前
    我去,广州移动跟 OP 也有同样的现象。而且我发现这个检测即使允许连接也会引入 150ms 左右的延迟,体验太差了。
    julyclyde
        19
    julyclyde  
       189 天前
    求教,所谓 TLS 指纹具体是指什么
    wushenlun
        20
    wushenlun  
       189 天前 via Android
    反诈弄得,换 IP 无效


    部分地区的运营商喜欢干这种事情,封禁逻辑是 ip+sni 换 ip 可能有就解了


    如果是合规业务直接投诉,如果是个人业务就认栽吧
    kenny9572
        21
    kenny9572  
       189 天前
    广州移动也有这个问题
    piaoyang
        22
    piaoyang  
    OP
       158 天前
    原来这么多人都遇到了类似的情况,也有很多人提出了这个现象可能的解释以及应对办法。
    希望后人搜到此类能够及时解决。
    daimaosix
        23
    daimaosix  
       124 天前
    用 nftables 把 SYN+ACK 握手报文的 Window 修改为一个较小值,这样客户端发的 HTTP GET/TLS Hello 会被拆成两个,移动的无状态检测就看不到 host 了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5782 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 784ms · UTC 06:23 · PVG 14:23 · LAX 22:23 · JFK 01:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.