Linux下使用TCPDump抓包教程 结合Wireshark分析网络协议【指南】

不加 -s 0 的抓包文件,基本等于白抓——HTTP header、TLS handshake、Modbus 功能码全被截断在前 68 字节里,你看到的只是个“半截包”。
必须加 -s 0,否则 payload 被砍掉就无法分析协议内容
tcpdump 默认只捕获每个包前 68 字节(snaplen),这对链路层诊断可能够用,但对应用层协议毫无意义:
- HTTP 请求行、header、body 全部丢失,Wireshark 里看不到
GET /api/v1或Content-Length - TLS ClientHello/ServerHello 被截断,无法判断协商的 cipher suite 或 SNI
- Modbus TCP ADU 中的功能码、数据地址、字节数可能落在 68 字节之后,直接看不到读写意图
- 即使加了
-A(ASCII 输出),也只会显示截断后的乱码或空行
正确做法是显式指定 -s 0,强制捕获完整帧。注意这不是“可选优化”,而是分析任何应用层协议的前提。
网卡选错,包根本不在那个接口上
常见错误是查到 eth0 就开抓,结果目标流量其实在 lo、br0 或 docker0 上:
- 本地服务调用(如
curl https://localhost:8080)必须用-i lo,物理网卡上完全没影 - BMC 与安卓卡通信若走桥接网络(如
br0),抓eth0会漏掉所有业务包 any接口能抓所有网卡,但不含链路层信息(如 VLAN tag、MAC 地址),Wireshark 里看不到 Ethernet II 头- 用
ip link show看哪些接口状态是UP,再用ss -tuln | grep :502确认 Modbus 连接实际绑定在哪块卡
过滤表达式写错,看起来在抓,其实什么也没捕到
BPF 过滤不是自然语言,缺一个逻辑词或括号位置不对,整个条件就失效:
host 192.168.1.100 port 502❌ 缺and,tcpdump 会忽略port 502,实际等价于host 192.168.1.100src host A and dst port 502✅ 明确方向:只抓 A 发给本机 502 端口的包(即 Modbus 请求)tcp[tcpflags] & tcp-syn != 0✅ 抓 SYN 包;写成tcp-syn不加引号或大小写错误会报语法错- 想抓响应包却用了
src port 502,结果只看到本机发出去的 reply,漏掉对端发来的 request
建议先不加过滤跑几秒:sudo tcpdump -i lo -s 0 -c 5,确认有包出来再加条件。
Wireshark 打开后看不到明文?别怪 tcpdump,先看协议是否加密
抓到的包在 Wireshark 里显示为 TCP segment of a reassembled PDU 或全是十六进制,不一定是抓包问题:
port 443抓到的是 TLS 流量,-A或 Follow TCP Stream 只能看到加密载荷,tcpdump 本身不也不解密- Modbus TCP 若走 TLS 封装(如 modbus-TCP-over-TLS),同样看不到功能码,得用密钥导入 Wireshark 才能解密
- HTTP 明文但 Wireshark 显示乱码?检查是否误用了
-X(hex+ascii 混排)而非-A(纯 ascii),或者包真被-s截断了 - Wireshark 默认不解析某些私有协议(如自定义二进制协议),需手动设置 Decode As → TCP port 60000 → your-protocol
最常被跳过的动作是:确认 -s 0 和网卡是否匹配。这两个点没踩准,后面所有分析都是在错误数据上打转。
