12.2 抓包与协议分析:选择观测点,再解释数据
抓包能回答“这个观测点实际看到了什么包”,但不能自动告诉你全链路发生了什么。选错接口、抓在 NAT 前后不同位置,或忽略网卡卸载,都可能得到看似矛盾却各自真实的结果。
本课目标
- 选择与故障假设匹配的抓包位置;
- 区分 capture filter 与 Wireshark display filter;
- 从 TCP 建连、重传、关闭和 TLS 握手中提取证据;
- 识别 offload、namespace、代理和加密带来的观测边界;
- 安全保存和分享 pcap。
先画观测点
一次请求可能经过:
client process
-> client namespace / host
-> NAT or proxy
-> load balancer
-> server host / container namespace
-> server process在客户端抓到 SYN 发出,只证明包到达客户端抓包点;在服务端抓不到,问题可能位于中间,也可能是抓错了接口或 namespace。最强的对照通常是同一时间窗内的双端抓包,再用五元组、TCP 序号和时间关联。
开始前记录:
- UTC 时间与时钟同步状态;
- 客户端和服务端地址、端口;
- 容器、Pod、network namespace 与代理边界;
- NAT 或负载均衡前后的地址变化;
- 复现请求的 trace ID 或唯一请求头。
用 tcpdump 做有界采集
只在你拥有或明确获准诊断的系统与流量上抓包。先收窄接口、主机、端口、时长与文件大小:
sudo tcpdump -i eth0 -nn -s 0 \
'host 203.0.113.10 and tcp port 443' \
-c 500 -w incident-443.pcap参数含义:
-i eth0:明确观测接口;Linux 的any方便初筛,但链路层信息和行为可能不同于具体接口;-nn:不做主机名和服务名解析,减少额外流量与歧义;-s 0:按当前 tcpdump 语义抓取完整包;若涉及敏感数据,应改用足够诊断的较小 snaplen;-c 500:到包数即停止;-w:保存原始捕获,而不是解析后的文本。
长时间采集应轮转文件并限制数量:
sudo tcpdump -i eth0 -nn -s 256 \
'host 203.0.113.10 and tcp port 443' \
-G 60 -W 5 -w 'incident-%Y%m%dT%H%M%S.pcap'不同 tcpdump 版本对 -G、-W 与文件名轮转的组合细节可能不同,正式值守前要在目标版本上演练。
两种过滤器不是一种语法
tcpdump 的 capture filter 通常使用 BPF 语法,在采集时决定哪些包进入文件:
host 203.0.113.10 and tcp port 443
tcp[tcpflags] & (tcp-syn|tcp-ack) != 0Wireshark display filter 在包已经捕获后筛选显示,语法不同:
ip.addr == 203.0.113.10 && tcp.port == 443
tcp.flags.syn == 1
tcp.analysis.retransmission
tls.handshake.type == 1把 display filter 粘进 tcpdump,或把 BPF 粘进 Wireshark 显示过滤框,都会失败或产生错误预期。
建连阶段:按包而不是按报错字符串判断
典型 TCP 建连:
client -> server SYN
server -> client SYN, ACK
client -> server ACK几类证据模式:
| 客户端抓包 | 服务端抓包 | 更接近的解释 |
|---|---|---|
| SYN 重复发出,无响应 | 看不到 SYN | 请求未到服务端观测点,或服务端抓错位置 |
| SYN 重复发出,无响应 | 看得到 SYN,无 SYN-ACK | 服务端路径、策略、资源或内核处理需继续检查 |
| 收到 RST | 可能看到 RST 发出 | 主机或中间设备主动拒绝 |
| 收到 SYN-ACK,但客户端继续发 SYN | 服务端反复发 SYN-ACK | 客户端未接受响应,或最终 ACK 在路径中丢失 |
不要仅凭一次客户端抓包确定丢包发生的精确设备。双端证据能把范围缩到两个观测点之间,但仍未指出中间哪台设备负责。
重传与乱序:分析器提示是推断
Wireshark 的 tcp.analysis.retransmission、fast_retransmission、out_of_order 是依据当前捕获和分析状态生成的提示,不是发送端内核日志。抓包丢包、snaplen、分流、时间戳精度和观测点都可能影响判断。
判断重传时至少核对:
- 五元组和方向;
- TCP 序号区间与 ACK;
- SACK block;
- 相同 payload 是否再次出现;
- 捕获文件自身是否丢包;
- 两端是否都看到同一段。
在发送端抓包时,TSO/GSO 可能让捕获看到比线上 MTU 大的“包”;在接收端,GRO/LRO 可能合并多个段。校验和也可能在抓包发生后才由网卡填写,于是本机捕获显示 checksum incorrect,而线上包实际正确。需要判断线上帧形态时,在对端或中间 TAP 抓包,或在可控实验中临时检查 offload 设置;不要在生产环境未经评估就修改网卡特性。
TLS:能看到什么,不能看到什么
没有会话密钥时,TLS 1.2/1.3 的应用数据是加密的。抓包通常仍能观察到:
- IP、端口、包长、方向和时序;
- TCP 或 QUIC 的部分传输行为;
- TLS ClientHello 中未被 ECH 保护的 SNI、ALPN 和 supported versions;
- 服务端证书是否可见取决于 TLS 版本和握手阶段;TLS 1.3 在 ServerHello 后加密大部分握手消息。
因此,“Follow TCP Stream” 对 HTTPS 默认只会得到 TLS records,不会凭空还原 HTTP。
在受控测试环境中,可让支持的客户端通过 SSLKEYLOGFILE 导出会话秘密,再配置 Wireshark 解密。密钥日志等同于该会话的敏感解密材料,必须受限保存并及时销毁;并非所有运行时或客户端都支持这个环境变量。
对于 QUIC/HTTP/3,常规 TCP 分析不适用。优先结合客户端 key log、实现提供的 qlog、连接 ID、服务端日志和应用 trace。
NAT、代理与负载均衡
地址在链路上改变是正常现象:
- 客户端出口 SNAT 会让服务端看到公网出口地址;
- DNAT/负载均衡会把虚拟地址映射到后端地址;
- 反向代理会终止客户端连接,再建立独立的上游连接;
- PROXY protocol 或可信的转发头可传递原始地址,但必须由两端共同配置和验证。
所以“服务端看到的源 IP 不是用户 IP”不能直接推出 NAT 配置错误。先画出每一段连接的终点,并明确你观察的是哪一段。
一套可复用的抓包流程
- 写下待验证假设,例如“客户端 SYN 到了负载均衡,但没有到后端”。
- 选择能区分两种结果的观测点,统一时间。
- 用最小过滤器和短采集窗口复现一次。
- 保存原始 pcap、命令、工具版本与主机位置。
- 先看包是否存在,再看时序、序号与协议字段。
- 将抓包与连接表、防火墙计数器、负载均衡日志和应用 trace 对齐。
- 得出范围有限的结论,并明确尚未观测的区间。
数据安全
pcap 可能包含 Cookie、Authorization、查询参数、内部地址、DNS 名称和未加密业务数据。分享前应:
- 在源头限制捕获范围和 snaplen;
- 使用受控存储与最小权限;
- 不直接用文本替换二进制 pcap 做“脱敏”;
- 必要时用专门工具生成删减后的副本并验证;
- 记录保留期限并删除临时密钥日志。
本课小结
抓包不是全知视角,而是一处传感器。先选择观测点,再解释协议;先确认原始包,再参考分析器提示。下一课会把这些工具组织成三个安全、可重复的本地实验。
规范与手册入口
- tcpdump manual page 与 pcap-filter manual page;
- Wireshark User's Guide:capture filters、display filters、TCP analysis;
- RFC 9293(TCP)、RFC 8446(TLS 1.3)、RFC 9000(QUIC)。