问题背景
该问题案例来自于公众号朋友分享,虽然以前也有类似 Web 服务打不开,结果是被封堵的案例,但此次数据包可展开分析的内容有更多的含义,所以记录一下故障排查过程。
问题分析
最终用户反馈移动 4G 打不开网站页面,故障排查通过笔记本 WIFI 热点的方式抓取了相应访问数据包。
一般数据包抓取方式,从我个人建议无需使用捕获过滤,可以在完整的数据包文件上通过显示过滤方式来抽取想要的数据包。
IP 会话过滤
明确知道了所访问的网站域名,自然可以通过 nslookup 等方式确认 IP 地址,之后通过 IP 会话过滤的方式过滤出源和目的交互的所有数据包。
ip.addr eq 10.10.10.1 and ip.addr eq 192.168.0.1
然后导出特定分组,仅保存显示过滤后的数据包文件,可发现源和目的之间存在多条 TCP 会话流,结果如下:
数据包文件部分统计信息如下,数据包数量经过 IP 会话过滤后由 387 变为 249 。
$ capinfos -csdl 1226.pcap
File name: 1226.pcap
Packet size limit: file hdr: 262144 bytes
Number of packets: 387
File size: 85 kB
Data size: 79 kB
$ capinfos -csdl 1226-01.pcapng
File name: 1226-01.pcapng
Packet size limit: file hdr: (not set)
Number of packets: 249
File size: 54 kB
Data size: 46 kB
TCP 流会话过滤
因客户端访问服务器的行为不同,触发所产生的 TCP 会话流也有多条,根据追踪流方式确认结果
tcp.stream == <num>
简单遍历各条流内容后,发现 RST 异常大同小异,挑选其中一条流做实际分析,数据包内容如下。
tcp.stream == 4
实际分析
从 TCP 会话流明显看到 RST 现象,正常来说数据中心内部(无安全设备区域的前提下)RST 一般来自于会话双方的某一方,但考虑到安全设备的存在,又或是本案例中通过互联网访问(数据流途径网络架构未知的情况),需要具体判断 RST 来自何方。
- 首先分析 IRTT;
IRTT 信息来自于 TCP 三次握手,存在于整条 TCP 流中做为参考,大体可得知源和目的交互往返时间约为 119 ms 。
2. RST 返回时间
判断 RST 来自何方,为什么可以利用 RST 返回时间做为依据之一?简单思考下,如果 RST 来自于服务器,那么根据 IRTT 值做为参考,基本也在 119 ms 左右返回,但如果明显小于 IRTT 值,可见并不一定是服务器返回,有可能为中间端的设备所产生(多见安全设备)。
增加 Delta Time 列,表达式含义为 frame.time_delta_displayed
, 详见之前文章 frame.time_delta 和 frame.time_delta_displayed 。
可以明显看到 RST 在客户端 GET 请求(数据包51)之后,大约 68 ms 即返回,初步可以判断非真实服务器返回。如何进一步佐证?利用 TTL 。
3. TTL
众所周知,TTL 可用来判断 IP 数据包在网络中转发的跳数,因此增加 TTL 字段作为列参考。
可以看到 TCP 三次握手 SYN/ACK 数据包的 TTL 为 112,但是 RST 数据包的 TTL 为 61 ,可见并不是由同一台设备发出,结合 RST 返回时间,可以判断得出结论: Web 服务访问确实是被互联网中间的安全设备所封堵。
深入分析
说到 TTL,可能心细的朋友会有注意到上述图中几个 TTL 值的不同,64、112、61、48,尤其是同样来自于服务器 10.10.10.1 的数据包, TTL 会有 112、61、48 三个的区别,那么具体是什么情况呢?
首先 TTL ,由于各个操作系统的不同,甚至说协议的不同,使得不同的数据包 TTL 初始值并不一样,部分设备/操作系统如下:
设备/操作系统 | TTL | 备注 |
---|---|---|
Linux | 64/255 | |
Windows | 128 |
1.TTL 64
来自于客户端的 TTL 值 64,结合 Length 长度 54,可判断该数据包文件是在本地客户端上抓取的包。
2. TTL 61
来自于中间安全设备 RST 数据包携带的 TTL 值 61,可判断该安全设备离客户端大概 3 跳,有可能是靠近本端的运营商所做的安全策略管控。
3. TTL 112 和 48
来自于 TCP 三次握手中服务器 SYN/ACK 携带的 TTL 值 112,从初始值 128 来看,判断离客户端大概 16 跳。
同样来自于服务器数据包所携带的 TTL 值 48,从初始值 64 来看,判断离客户端大概也是 16 跳。
那么为什么同一台服务器会产生两个 TTL 值 112 和 48 ?个人猜测仍是安全设备引起,只不过这个安全设备是在服务器侧(类似 WAF 设备),在 TCP 三次握手阶段,由安全设备充当 TCP 三次握手的代理,在确认 TCP 三次握手正式完成后,才将正常业务数据包转发至真实服务器,起到了安全防护作用(譬如 SYN Flood 攻击防护)。因此 TTL 112 为服务器侧安全设备返回,TTL 48 为真实服务器返回。
问题总结
结合数据包实际情况,剥丝抽茧,一步步分析数据包中各项字段的含义,有助于合理判断真实的故障到底在哪里。
感谢阅读,更多技术文章可关注个人公众号:Echo Reply ,谢谢。