tcpdump过滤表达式必须用bpf语法:空格表“与”,or表“或”,not表否定,括号需转义\( \);典型双向mysql抓包为'tcp and \( (src host a and dst host b and dst port 3306) or (src host b and dst host a and src port 3306) \)'。

在生产环境中用 tcpdump 捕获特定 IP 与端口的流量,关键不是堆参数,而是写对逻辑过滤表达式——它直接决定你抓到的是有效诊断数据,还是海量无关包。
理解 tcpdump 过滤语法的核心逻辑
tcpdump 的过滤器基于 BPF(Berkeley Packet Filter)语法,不支持 && || 等高级逻辑符号,而是用空格表示“与”,用 or 表示“或”,用 not 表示否定。括号必须用反斜杠转义:\( ... \)。
常见误区:写成 src host A and dst port 8080 or src host B,实际等价于 (src host A and dst port 8080) or src host B——这会意外捕获 B 的所有流量(无论端口)。正确做法是显式加括号明确优先级。
捕获「指定源/目标 IP + 特定端口」的典型组合
生产中高频需求是定位某服务间通信,例如:只抓 10.20.30.40 访问 192.168.5.100:3306 的 MySQL 流量,或双向包含这两个地址+端口的所有 TCP 包:
-
仅客户端发往服务端(单向):
tcpdump -i eth0 'tcp and src host 10.20.30.40 and dst host 192.168.5.100 and dst port 3306' -
服务端回包(单向):
tcpdump -i eth0 'tcp and src host 192.168.5.100 and dst host 10.20.30.40 and src port 3306' -
双向完整会话(推荐):
tcpdump -i eth0 'tcp and \( (src host 10.20.30.40 and dst host 192.168.5.100 and dst port 3306) or (src host 192.168.5.100 and dst host 10.20.30.40 and src port 3306) \)'
注意:若服务监听在多个端口(如 3306 和 3307),可写成 dst port 3306 or dst port 3307,但需确保外层括号包裹整个 or 表达式。
生产环境实用增强技巧
纯过滤还不够,真实场景需兼顾性能、可读性与安全性:
-
限制包大小:加
-s 65535防截断(默认仅抓前 68 字节),尤其对 HTTP/JSON 类协议很重要; -
避免干扰业务:用
-c N限定抓 N 个包后自动退出,防止长时间运行占满磁盘; -
输出可读格式:加
-nn(禁用 DNS/端口名解析)+-q(精简输出)+-tttt(带完整时间戳),便于日志分析; -
保存为 pcap 方便后续分析:追加
-w /tmp/mysql-debug.pcap,之后可用 Wireshark 或tshark -r离线深挖。
验证过滤是否生效的快速方法
别等跑完再怀疑——先小范围验证:
- 用
netstat -tuln | grep :PORT或ss -tuln | grep PORT确认目标端口确实在监听; - 从另一台机器执行
curl -v http://TARGET_IP:PORT/health或telnet TARGET_IP PORT触发少量流量; - 启动 tcpdump 后立即触发请求,观察终端是否实时打印匹配行(有输出即过滤成功);
- 若无输出,检查网卡名(
ip a)、IP 是否写错、是否跨 VLAN/防火墙拦截、端口方向(src/dst)是否颠倒。
不复杂但容易忽略。











