tcpdump可通过tcp[tcpflags]配合位运算精确筛选tcp标志位;syn包用tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn,syn-ack用== (tcp-syn|tcp-ack),fin包用& tcp-fin != 0。

tcpdump 可以直接通过 TCP 标志位(如 SYN、ACK、FIN)进行精确筛选,关键在于使用 tcp[tcpflags] 表达式配合位运算操作。
理解 TCP 标志位在 tcpdump 中的表示
TCP 头部的 flags 字段占 1 字节(8 位),其中低 6 位对应 URG、ACK、PSH、RST、SYN、FIN。tcpdump 将其视为一个整数(0–63),常用标志对应值如下:
- SYN → 2(二进制 00000010)
- ACK → 16(二进制 00010000)
- FIN → 1(二进制 00000001)
- RST → 4(二进制 00000100)
tcpdump 提供了 tcp[tcpflags] 语法来提取该字段,并支持 &(按位与)和 == 比较,用于检测特定标志是否被置位。
只捕获 SYN 包(三次握手初始包)
SYN 包的 flags 字段中只有 SYN 位为 1,其他标志通常为 0(即 flags == 2)。但更稳妥的方式是检查 SYN 位是否被设置且 ACK 未设置(避免误抓 SYN-ACK):
tcpdump 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0'
或者简写为(tcpdump 内置别名支持):
tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn'
捕获 SYN-ACK 响应包
服务端对 SYN 的响应会同时设置 SYN 和 ACK 位(flags == 18,即 2+16):
tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)'
等价于:
tcpdump 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack != 0'
捕获 FIN 或 FIN-ACK 连接终止包
主动关闭方发送 FIN(可能不含 ACK),被动方回应 FIN-ACK(含 FIN 和 ACK)。若想捕获任意含 FIN 的包(无论是否带 ACK):
tcpdump 'tcp[tcpflags] & tcp-fin != 0'
若只抓纯 FIN(无 ACK,较少见,常见于异常断连):
tcpdump 'tcp[tcpflags] & tcp-fin != 0 and tcp[tcpflags] & tcp-ack == 0'
抓 FIN-ACK(典型四次挥手中的第 2 或第 3 个包):
tcpdump 'tcp[tcpflags] & (tcp-fin|tcp-ack) == (tcp-fin|tcp-ack)'
实用技巧与注意事项
tcpdump 默认解析时会自动识别 tcp-syn、tcp-ack 等符号,无需手动计算数值;但需注意:
- 表达式中的括号必须用英文小括号,且
&前后要有空格 - 过滤器字符串整体要用单引号包裹,防止 shell 解析特殊字符
- 若同时指定端口或主机,可组合使用,例如:
'tcp port 80 and tcp[tcpflags] & tcp-syn != 0' - 加
-nn参数避免 DNS/端口反解,提升性能和可读性
不复杂但容易忽略细节。










