网络抓包记录

本文最后更新于:2023年8月3日 晚上

学习记录

这个博客主要记录了自己尝试通过抓包分析并解决一些问题的心路历程,从结果上来说很可能问题并没有解决,但是尝试解决这个问题的过程中遇到的一些问题以及自己的思考想通过写博客的方式先记录下来,在以后自己知识储备扩充的时候也许就可以回过头来看看解决下。

第一次抓包

遇到的问题

今天在尝试部署zerotierzeronsd私有DNS服务的时候遇到了一个问题:无论是在我之前国内的服务器A上还是香港的服务器B上,zeronsd的部署都是只需要无脑复制粘贴指令就能成功,但是今天尝试在新租赁的国内服务器C上部署的时候则遇到了一个报错:Error Response

不明所以的报错

在翻阅zeronsd源码的时候发现这块逻辑本来应该是对应请求zerotier那边获取到局域网内所有设备的IP以便于创建私有的DNS条目。

zeronsd源码

可以看见这部分错误处理里面并没有Error Response的产生原因,而且同时我在香港的服务器上依旧可以正常使用zeronsd。因此也产生了想尝试通过抓包找到问题所在的想法。

解决过程

通过lsof获取目标IP

既然知道了问题是来自于zeronsd,而且应该是一个和网络Response有关系的问题,那么通过抓包应该是最通用的排查方法。在这里首先通过lsof工具查询zeronsd打开的连接

最开始找到的指令是先通过pidof zeronsd找到进程的pid,然后通过pid来用lsof查询,指令大概是lsof -p $(pidof zeronsd),结果后面翻了下lsof的手册,发现可以直接用-c来找进程,不过pidof以后也感觉会用到,姑且做个记录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[root@Aliyun:~]
# lsof -c zeronsd
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
zeronsd 18437 root cwd DIR 254,1 4096 2 /
zeronsd 18437 root rtd DIR 254,1 4096 2 /
zeronsd 18437 root txt REG 254,1 8752136 804251 /usr/bin/zeronsd
zeronsd 18437 root mem REG 254,1 93000 787112 /usr/lib/x86_64-linux-gnu/libresolv-2.31.so
zeronsd 18437 root mem REG 254,1 26952 787106 /usr/lib/x86_64-linux-gnu/libnss_dns-2.31.so
zeronsd 18437 root mem REG 254,1 51696 787107 /usr/lib/x86_64-linux-gnu/libnss_files-2.31.so
zeronsd 18437 root mem REG 254,1 1901536 786465 /usr/lib/x86_64-linux-gnu/libc-2.31.so
zeronsd 18437 root mem REG 254,1 18688 787097 /usr/lib/x86_64-linux-gnu/libdl-2.31.so
zeronsd 18437 root mem REG 254,1 1321344 787098 /usr/lib/x86_64-linux-gnu/libm-2.31.so
zeronsd 18437 root mem REG 254,1 149520 787110 /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
zeronsd 18437 root mem REG 254,1 100736 786450 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
zeronsd 18437 root mem REG 254,1 3076992 802235 /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
zeronsd 18437 root mem REG 254,1 597792 802236 /usr/lib/x86_64-linux-gnu/libssl.so.1.1
zeronsd 18437 root mem REG 254,1 177928 786460 /usr/lib/x86_64-linux-gnu/ld-2.31.so
zeronsd 18437 root 0r CHR 1,3 0t0 4 /dev/null
zeronsd 18437 root 1u unix 0x0000000070328a2d 0t0 105666 type=STREAM
zeronsd 18437 root 2u unix 0x0000000070328a2d 0t0 105666 type=STREAM
zeronsd 18437 root 3u a_inode 0,13 0 8321 [eventpoll]
zeronsd 18437 root 4u a_inode 0,13 0 8321 [eventfd]
zeronsd 18437 root 5u a_inode 0,13 0 8321 [eventpoll]
zeronsd 18437 root 6u unix 0x000000008c202115 0t0 105669 type=STREAM
zeronsd 18437 root 7u unix 0x0000000072325ef6 0t0 105670 type=STREAM
zeronsd 18437 root 8u unix 0x000000008c202115 0t0 105669 type=STREAM
zeronsd 18437 root 9u IPv4 104709 0t0 TCP iZf8zgk9dawv2exr28bz0oZ:57136->151.101.109.91:https (SYN_SENT)

可以发现下面有创建一个TCP连接,并且是处于SYN_SENT的状态。同时在我短时间内重复输入lsof的指令(蠢但有效.jpg),发现返回的依旧是SYN_SENT。一般来说SYN握手的速度应该是很快的,这里很长时间内都处于SYN_SENT的状态就明显很不对劲,所以接下来就需要通过抓包来分析。

在我多次尝试了lsof之后,发现即使有的时候能让连接处于ESTABLISHED的状态,但是过了一会以后依旧会被掐断,并且返回Error Response。通过分析不同的lsof建立TCP连接的目标ip,发现服务器总是向151.101.109.91146.75.113.91建立连接,应该是请求的域名有做CDN所以解析到了不同的IP。接下来知道了目标IP,抓包就很容易了。这里采取的是通过tshark在配置较弱的服务器上获取到了数据包以后再导出到本地计算机的Wireshark的方法进行分析。

tshark抓包分析

首先使用下面的指令对所有http请求进行抓取,并将抓包的内容保存在data.cap文件中

1
tshark -d tcp.port==443,http -w data.cap

之后再将这个文件下载到本地电脑使用Wireshark过滤选定目标IP追踪TCP流,可以发现数据流如下图

数据流

可以发现就这一次的数据来说SYN握手的部分是成功了的,TLS的四次握手也能成功建立,但是在发送了一些应用数据之后,云的服务器就开始向远端服务器发送RST报文来请求强制终止连接了。重新抓包以后又发现出现了多次TCP数据包的重传。

对于在TCP连接中,先发送了FIN,然后发送RST的一个可能性的原因如下:

您的流中的FIN和RST数据包并不直接相关。通过发送FIN,表示没有更多要发送的数据。它仍然可以从连接的另一端接收更多数据。然而,当有更多数据到达时,发送RST来表示应用程序将不再从套接字读取任何数据。

如果一个应用程序想要干净地关闭TCP连接而不引发任何RST数据包,则必须首先使用shutdown系统调用关闭写入套接字,同时保持读取套接字处于打开状态。在关闭写入套接字之后,它仍然需要读取所有对方要发送的数据,然后才能完全关闭套接字。

但是zeronsd对于这次连接的重置是返回了Error的,所以基本上可以判断并不是zeronsd本身发送的rst阻断连接。

在这里为了让后续抓包更容易复现,首先对于TLS建立握手的第一个数据包,我们可以直接查询到域名

检查TLS握手的域名

之后我就尝试通过curl -vL my.zerotier.com的方法来通过抓取curl包分析问题。为了区分成功和失败的区别,我在这里也使用了curl -vL www.baidu.com作为对照组。

百度请求

返回的抓包内容大致如下:

使用curl请求百度

可以发现整个连接没有大问题,只是在连接结束以后百度那边发送了一个rst包给我们,但是tcp的四次挥手是正常完成了的。

Zerotier请求

使用curl请求zerotier

可以发现在想要结束连接的时候并没有正常挥手,在客户端这边接收到服务器那边的FIN之前就开始给服务器发送RST报文尝试断开连接

总述

这次抓包本身没有获取到啥决定性的信息可以确定问题产生的原因,因此目前自己也只能借由Zerotier和百度请求的对比,怀疑是因为Zerotier是国外网站,被服务商阻断了(但是在FIN之后再阻断也很奇怪,虽然会在FIN之后发送RST报文,但是curl还是可以读取到my.zerotier.com的网页信息),暂时对进一步的排查没有头绪。

第二次遇到问题

我尝试在同一台服务器上部署一个VOIP服务器。也是一样使用别的服务器的时候一点问题都没有,但是在这台国内的服务器上就遇到问题了。这次遇到问题就想尽可能的搞懂原因,因此做了以下实验

分情况尝试连接

  • 实验设备:一台香港服务器(对照组),一台阿里云国内服务器(样本组),以及自己的Windows设备

  • 实验情景:在香港和国内服务器上都部署Mumble的服务器(一个VOIP程序),然后使用Windows对这两台服务器进行连接,其中Mumble连接采取了TLS加密的方式,加密证书均为自签。

  • 实验步骤:

    1. 使用IP直连香港服务器上在端口64738部署的murmurMumble服务端的别称)
    2. 使用域名voice1.abc.com连接香港服务器在端口64738部署的murmur
    3. 使用IP直连国内服务器上在端口64738部署的murmur
    4. 使用域名voice2.abc.com连接国内服务器在端口64738部署的murmur
  • 实验期望:四种不同的方式连接murmur都能成功,且不会有明显区别

  • 实验结果:方法1-3都可以正常访问,但是方法4连接被服务器阻断

抓包分析问题

在对以上四种情况进行抓包以后,获取到的Wireshark图像大致如下

  1. 香港服务器使用域名连接

    香港 - 域名连接

  2. 香港服务器使用IP直连

    香港 - IP直连

  3. 国内服务器使用IP直连

    国内 - IP直连

  4. 国内服务器使用域名连接

    国内 - 域名连接

到这里基本上很明显可以发现只有在国内服务器使用域名连接的时候,服务器那边会在进行TLS握手的时候直接进行阻断,让你无法成功建立TLS连接

总述

这次抓包也没获得啥特别有用的信息。不过由于这个问题是在用阿里云的时候才遇到,之前用同样在国内的腾讯云没有遇到,则初步怀疑是阿里云对任意端口(非443)现在都做了备案检测,只要是没备案的域名/网站,无论是TLS还是明文,只要检测到你用了域名就禁封。相比之下腾讯那边就要宽松一些,至少murmur在腾讯云上是可以正常使用域名进行连接通讯的。


网络抓包记录
https://halc.top/p/3930e42b
作者
HalcyonAzure
发布于
2023年7月27日
许可协议