本文目录导读:

- 基础过滤:按协议类型
- 核心过滤:按主机 (IP 地址)
- 精确过滤:按端口 (Port)
- 高级过滤:按标志位和包类型
- 逻辑组合:and (与), or (或), not (非)
- 包长度过滤
- 常用实战案例
- 需要知道的“坑”与技巧
- 万能的过滤公式模板
tcpdump 是 Linux/Unix 环境下非常强大的命令行抓包工具,过滤的核心在于使用 BPF (Berkeley Packet Filter) 语法。
以下是按照不同维度分类的常用过滤方法,从基础到进阶。
基础过滤:按协议类型
直接在命令后跟协议名。
# 仅抓取 ICMP (ping) 包 tcpdump icmp # 仅抓取 TCP 包 tcpdump tcp # 仅抓取 UDP 包 tcpdump udp # 仅抓取 ARP 包 tcpdump arp
核心过滤:按主机 (IP 地址)
使用 host、src(源)、dst(目标)。
# 抓取所有与 192.168.1.100 相关的流量 (源或目标) tcpdump host 192.168.1.100 # 抓取 源IP 为 192.168.1.100 的流量 (从此主机发出) tcpdump src host 192.168.1.100 # 抓取 目标IP 为 192.168.1.100 的流量 (发给此主机) tcpdump dst host 192.168.1.100 # 抓取网段中的流量 (使用CIDR) tcpdump net 192.168.1.0/24 # 抓取非某IP的流量 tcpdump not host 192.168.1.1
精确过滤:按端口 (Port)
使用 port 或 portrange。
# 抓取访问 80 端口 (HTTP) 的流量 (含源端口和目标端口) tcpdump port 80 # 抓取 源端口 为 443 的流量 (通常是服务器发送数据) tcpdump src port 443 # 抓取 目标端口 为 22 的流量 (SSH 登录请求) tcpdump dst port 22 # 抓取端口范围 (如 8000-8100) tcpdump portrange 8000-8100
高级过滤:按标志位和包类型
这是 tcpdump 最强大的地方,适合分析三次握手或异常流量。
语法格式: tcp[tcpflags] & tcp-<flag> != 0
# 抓取 SYN 包 (建立连接) tcpdump 'tcp[tcpflags] & tcp-syn != 0' # 抓取 SYN-ACK 包 (通常对 Web 服务抓包时用到) tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0' # 抓取 RST 包 (连接重置,常用于异常诊断) tcpdump 'tcp[tcpflags] & tcp-rst != 0' # 抓取 FIN 包 (结束连接) tcpdump 'tcp[tcpflags] & tcp-fin != 0' # 抓取 只有 SYN 而没有 ACK 的包 (即“半连接”,可能是扫描攻击) tcpdump 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0'
逻辑组合:and (与), or (或), not (非)
这是最常用的,可以组合出非常精确的过滤条件。
# 抓取 主机 192.168.1.100 的 HTTP (80端口) 流量 tcpdump host 192.168.1.100 and port 80 # 抓取 主机 192.168.1.100 的 DNS (53端口) 和 HTTP (80端口) 流量 tcpdump host 192.168.1.100 and (port 80 or port 53) # 抓取 源IP为 10.0.0.1 且 目标端口为 22 的流量 tcpdump src host 10.0.0.1 and dst port 22 # 抓取除了 22 端口 (SSH) 以外的所有流量 (防止抓到自己 SSH 的内容刷屏) tcpdump not port 22
包长度过滤
# 抓取长度大于 500 字节的包 tcpdump greater 500 # 抓取长度小于 64 字节的包 (通常是控制帧或碎片) tcpdump less 64
常用实战案例
案例1:抓取对百度首页的 HTTP 请求
# 假设你刚才访问了百度 # 获取百度的IP (ping baidu.com) # 抓取 目标IP(ip_of_baidu) 且 80端口 的包 tcpdump dst host 39.156.66.10 and port 80 -X # -X 表示以HEX和ASCII混合打印内容,可以看到HTTP请求头
案例2:抓取MySQL查询 (默认3306端口)
# 只抓取发给MySQL的数据包 (不抓取本机ssh等杂包) tcpdump -i eth0 dst port 3306 -X # 如果需要看SQL语句内容,需要配合 -A (只打印ASCII) 或 -X tcpdump -i eth0 port 3306 -X -s 0
案例3:抓取并保存到文件 (避免刷屏)
# 抓取所有 80 端口流量,保存到 pcap 文件 (可用 Wireshark 打开分析) tcpdump port 80 -w http_traffic.pcap # 读取刚才保存的文件进行分析 tcpdump -r http_traffic.pcap # 读取文件并过滤 tcpdump -r http_traffic.pcap host 192.168.1.100
需要知道的“坑”与技巧
-
单引号 vs 双引号:
- 如果过滤条件中包含 或 ,在 Shell 中请务必用单引号包裹,否则 Shell 会先解析。
- ✅
tcpdump 'tcp[tcpflags] & tcp-syn != 0' - ❌
tcpdump tcp[tcpflags] & tcp-syn != 0(可能会报错)
-
VLAN:
- 如果数据包带 VLAN 标签,普通的
host过滤可能会失效,需要使用vlan关键字。 tcpdump vlan and host 192.168.1.100
- 如果数据包带 VLAN 标签,普通的
-
TUN/TAP (VPN) 接口:
- 在
tun0接口上抓包,过滤的是解封装后的原始 IP 包,通常直接使用host即可生效。
- 在
-
性能建议:
- 如果不关心包内容,只关心头信息,加上
-s 60(只抓前60字节),能大幅提升抓包效率。 tcpdump -s 60 -i eth0 tcp port 80
- 如果不关心包内容,只关心头信息,加上
万能的过滤公式模板
# 语法模板 tcpdump -i <网卡> <协议> <方向> <主机/网段> and <端口> and <包类型> -<输出选项> # 举例:在 eth0 上抓取 发给 192.168.1.1 的 TCP 80 端口且不是本机SSH的包 tcpdump -i eth0 tcp dst host 192.168.1.1 and dst port 80 and not port 22 -nn -X # -nn 表示不解析DNS,不解析端口服务名 (显示数字) # -X 显示包内容
建议先从简单的 host 和 port 组合练起,熟悉之后再用位运算过滤标志位。