掌握TCPDump的核心在于熟练使用过滤表达式精准捕获目标流量。本文整理了最实用的过滤示例,覆盖协议、端口、IP等常见场景,并提供配套分析方法,助你快速定位网络问题。
一、基础过滤速查表
1. 协议过滤(单协议)
python
# 捕获TCP流量
sudo tcpdump -i any tcp
# 捕获UDP流量
sudo tcpdump -i any udp
# 捕获ICMP(ping)流量
sudo tcpdump -i any icmp
# 捕获ARP请求
sudo tcpdump -i any arp
# 捕获DNS协议
sudo tcpdump -i any port 53
2. 端口过滤
python
# 捕获80端口(HTTP)流量
sudo tcpdump -i any port 80
# 捕获443端口(HTTPS)流量
sudo tcpdump -i any port 443
# 捕获源端口为8080的流量
sudo tcpdump -i any src port 8080
# 捕获目标端口3306(MySQL)的流量
sudo tcpdump -i any dst port 3306
# 捕获端口范围8000-9000的流量
sudo tcpdump -i any portrange 8000-9000
3. IP地址过滤
python
# 捕获与192.168.1.100相关的所有流量
sudo tcpdump -i any host 192.168.1.100
# 捕获来自10.0.0.1的流量
sudo tcpdump -i any src host 10.0.0.1
# 捕获发送到8.8.8.8的流量
sudo tcpdump -i any dst host 8.8.8.8
# 捕获192.168.1.0/24网段的流量
sudo tcpdump -i any net 192.168.1.0/24
二、组合过滤实战示例
1. 协议+端口组合
python
# 捕获HTTP流量(TCP+80端口)
sudo tcpdump -i any 'tcp and port 80'
# 捕获HTTPS流量(TCP+443端口)
sudo tcpdump -i any 'tcp and port 443'
# 捕获DNS流量(UDP+53端口)
sudo tcpdump -i any 'udp and port 53'
2. IP+端口组合
python
# 捕获到8.8.8.8的DNS查询
sudo tcpdump -i any 'dst host 8.8.8.8 and dst port 53'
# 捕获来自192.168.1.100的SSH流量
sudo tcpdump -i any 'src host 192.168.1.100 and port 22'
# 捕获到数据库服务器的流量
sudo tcpdump -i any 'dst host 10.0.0.5 and (port 3306 or port 5432)'
3. 复杂逻辑组合
python
# 捕获非HTTP的TCP流量
sudo tcpdump -i any 'tcp and not port 80'
# 捕获来自特定网段到外部80端口的流量
sudo tcpdump -i any 'src net 192.168.1.0/24 and dst port 80'
# 捕获SYN或RST包(TCP连接建立/重置)
sudo tcpdump -i any 'tcp[tcpflags] & (tcp-syn|tcp-rst) != 0'
三、高级协议分析示例
1. HTTP请求分析
sql
# 捕获HTTP GET/POST请求头
sudo tcpdump -i any -A -s0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0' | grep -E 'GET |POST |HTTP/'
# 输出示例
GET /api/users HTTP/1.1
Host: example.com
User-Agent: curl/7.68.0
分析要点:
- 检查请求路径和Host头是否匹配
- 查看User-Agent识别客户端类型
- 观察是否有异常请求头
2. DNS问题排查
makefile
# 捕获DNS请求和响应
sudo tcpdump -n -s0 -i any port 53
# 输出示例
15:30:45.123456 IP 192.168.1.100.5353 > 8.8.8.8.53: 12345+ A? example.com. (32)
15:30:45.234567 IP 8.8.8.8.53 > 192.168.1.100.5353: 12345 1/0/0 A 93.184.216.34 (48)
分析流程:
- 确认DNS查询是否发出(
A? example.com
) - 检查是否收到响应(
A 93.184.216.34
) - 响应时间是否正常(本例中111毫秒)
- 响应码:
NOERROR
(0)表示成功,NXDOMAIN
(3)表示域名不存在
3. TCP连接问题分析
bash
# 捕获TCP握手包
sudo tcpdump -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0'
# 输出示例
16:20:01.123456 IP 10.0.0.2.34567 > 10.0.0.3.80: Flags [S], seq 123456789
16:20:01.234567 IP 10.0.0.3.80 > 10.0.0.2.34567: Flags [S.], seq 987654321, ack 123456790
16:20:06.456789 IP 10.0.0.2.34567 > 10.0.0.3.80: Flags [S], seq 123456789 # 重传
问题诊断:
- 正常流程:SYN → SYN-ACK → ACK
- 本例问题:客户端未收到SYN-ACK,导致SYN重传
- 可能原因:防火墙阻止、服务未监听、网络不通
四、组合过滤场景分析指南
场景1:网站访问失败
markdown
# 组合过滤:目标域名+端口
sudo tcpdump -i any 'host example.com and port 80'
# 分析步骤:
1. 检查是否有SYN包发出 → 无则表示DNS或路由问题
2. 检查是否收到SYN-ACK → 无则表示服务未响应
3. 检查是否发送HTTP请求 → 无则表示客户端问题
4. 检查HTTP响应码 → 5xx为服务端错误
场景2:数据库连接超时
markdown
# 组合过滤:数据库IP+端口
sudo tcpdump -i any 'host 10.0.0.5 and port 3306'
# 分析步骤:
1. 检查TCP握手是否完成 → 未完成则检查网络/防火墙
2. 观察连接建立时间 → 长延迟可能网络问题
3. 检查是否有重传 → 重传指示丢包
4. 查看连接是否被RST终止 → 服务端主动拒绝
场景3:API性能下降
markdown
# 组合过滤:API端点+方法
sudo tcpdump -i any 'port 8080 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354' -A
# 分析步骤:
1. 测量请求-响应时间 → 定位延迟阶段
2. 检查是否有TCP重传 → 网络问题
3. 观察HTTP响应码分布 → 5xx增加指示服务问题
4. 分析请求/响应大小 → 大数据量可能影响性能
五、TCP报文分析
一、Flags [S] 和 Flags [R.] 的含义
-
Flags [S](SYN 标志) 表示该数据包携带同步标志位(SYN) ,用于建立 TCP 连接的三次握手过程36。
-
场景 :客户端首次向服务器发送连接请求时,会设置
SYN=1
,此时tcpdump
显示为Flags [S]
。例如:bash10:00:00.123456 IP client.50000 > server.80: Flags [S], seq 123456, win 65535
-
作用:初始化序列号,请求与对端建立连接。
-
-
Flags [R.](RST+ACK 标志) 表示该数据包同时设置了复位标志位(RST)和 确认标志位(ACK) ,通常用于异常终止连接。
-
场景:
- 服务器收到发往未监听端口的 SYN 请求时,会回复
RST+ACK
,表示 "端口不可达"。 - 连接过程中出现数据不一致(如序列号不匹配),一方发送
RST+ACK
强制关闭连接。
- 服务器收到发往未监听端口的 SYN 请求时,会回复
-
tcpdump 输出示例:
bash10:00:01.789012 IP server.80 > client.50000: Flags [R.], seq 0, ack 123457, win 0
-
特点:RST 包不携带数据,接收方收到后会立即终止连接并通知应用层。
-
二、TCP 标志位全集及 tcpdump 表示
TCP 头部共有 6 个标志位,在tcpdump
中通过以下字符表示:
标志位 | 全称 | 简写 | 含义 |
---|---|---|---|
SYN | Synchronize | S |
同步序列号,用于建立连接(三次握手第一步) |
ACK | Acknowledgment | . |
确认号有效,用于确认已接收数据(除 SYN 包外,其他包通常包含 ACK) |
RST | Reset | R |
强制复位连接,用于终止异常或无效连接 |
FIN | Finish | F |
结束标志,用于关闭连接(四次挥手第一步) |
PSH | Push | P |
提示接收方立即将数据交付给应用层,避免缓冲队列积压 |
URG | Urgent | U |
紧急指针有效,表示数据需优先处理(带外数据) |
特殊组合:
S.
= SYN + ACK(三次握手第二步,服务器响应客户端的 SYN 请求)F.
= FIN + ACK(四次挥手第二步,对端确认关闭请求)P.
= PSH + ACK(推送数据并确认)
三、详细分析 TCP 报文的方法
1. 基础字段解析
通过tcpdump
输出的关键字段可定位问题:
bash
10:00:00.123456 IP client.50000 > server.80: Flags [S], seq 123456, win 65535
- 时间戳 :
10:00:00.123456
------ 抓包时间。 - IP 地址与端口 :
client.50000 > server.80
------ 源 IP: 端口 → 目的 IP: 端口。 - 标志位 :
Flags [S]
------ SYN 标志位。 - 序列号 :
seq 123456
------ 初始序列号(ISN),用于数据排序和确认。 - 窗口大小 :
win 65535
------ 接收方通告的滑动窗口大小,单位为字节。
2. 使用 tcpdump 参数深入分析
-
抓取完整数据包:
arduinotcpdump -i eth0 -s0 -w capture.pcap 'tcp port 80'
-s0
:关闭默认的 68 字节截断,抓取完整数据包。-w capture.pcap
:保存为 PCAP 文件供后续分析。
-
显示十六进制和 ASCII 内容:
arduinotcpdump -XX -s0 'tcp port 80'
-XX
:同时显示二层头、IP 头、TCP 头及数据部分的十六进制和 ASCII 表示。
-
过滤特定标志位:
bashtcpdump 'tcp-syn|tcp-rst' # 仅抓取SYN或RST包
3. 结合 Wireshark 可视化分析
-
导入 PCAP 文件 : 将
capture.pcap
拖入 Wireshark,通过Statistics → Conversation List → TCP查看流量会话。 -
关键分析点:
- 三次握手失败:若客户端发送 SYN 后未收到 SYN+ACK,可能是服务器端口未监听(触发 RST)或网络阻断。
- 重传与超时 :Wireshark 的 TCP Stream Graph → Time-Sequence Graph (Stevens) 可直观显示重传次数和超时事件。
- 异常终止:大量 RST 包可能表示连接被强制关闭,需检查防火墙规则或应用逻辑。
4. 进阶诊断技巧
-
序列号与确认号:
- 正常情况下,
ack = seq + 数据长度
。若ack
值异常,可能存在丢包或乱序。 - 示例:客户端发送
seq=100
、长度 50 字节的数据,服务器应回复ack=150
。
- 正常情况下,
-
窗口缩放 : 若
win
字段显示为0
,可能是接收方缓冲区已满,触发流量控制(TCP Zero Window)。 -
紧急数据 : 若
URG
标志位被设置,需结合urgptr
字段定位紧急数据位置。
四、常见场景与标志位组合
-
三次握手成功:
iniclient → server: Flags [S] server → client: Flags [S.] client → server: Flags [.]
-
连接拒绝:
iniclient → server: Flags [S] server → client: Flags [R.] # 端口未监听或防火墙拦截
-
正常关闭(四次挥手) :
iniclient → server: Flags [F.] server → client: Flags [.] server → client: Flags [F.] client → server: Flags [.]
-
数据推送:
iniclient → server: Flags [P.] # 立即将数据交付给应用层
五、总结
通过tcpdump
和 Wireshark 结合分析 TCP 标志位,可快速定位网络连接问题:
- SYN/RST:排查端口是否开放、防火墙规则是否拦截。
- PSH/ACK:验证数据是否及时交付应用层。
- FIN/ACK:检查连接关闭是否正常完成。
掌握这些方法后,可有效诊断网络延迟、丢包、连接异常等问题,提升 TCP/IP 协议栈的故障排查效率。
六、结果分析方法与工具
1. 命令行实时分析
bash
# 统计TCP标志位分布
sudo tcpdump -i any -q -tttt 'tcp' | awk '{print $6}' | sort | uniq -c
# 输出示例:
1422 Flags [P.]
893 Flags [.]
128 Flags [S]
5 Flags [R.]
解读:
[P.]
:数据传输包(PSH+ACK)[.]
:ACK确认包[S]
:SYN连接请求[R.]
:连接重置(异常)
2. 使用Wireshark深度分析
python
# 捕获并保存到文件
sudo tcpdump -i any -w capture.pcap
# 在Wireshark中分析
wireshark capture.pcap
Wireshark高级功能:
- 流量图(Statistics > Flow Graph)
- 协议分层统计(Statistics > Protocol Hierarchy)
- 专家信息分析(Analyze > Expert Info)
- IO图表(Statistics > IO Graph)
3. 自动化分析脚本
bash
# 分析HTTP响应时间
tcpdump -ttt -n -r capture.pcap 'tcp port 80 and tcp[13] == 0x18' | \
awk '/HTTP/{print $1, $5, $6, $7, $8}'
# 输出示例
0.000000 GET /api/v1/users 200
0.125000 POST /api/v1/orders 201
0.250000 GET /api/v1/products 200
七、性能优化技巧
1. 高效捕获配置
bash
# 限制包大小(只捕获头部)
sudo tcpdump -s 128 -w optimized.pcap
# 设置缓冲区大小(避免丢包)
sudo tcpdump -B 4096 -w buffer_optimized.pcap
# 过滤后保存(减少文件大小)
sudo tcpdump -w http_only.pcap 'port 80'
2. 长期监控方案
perl
# 按时间分割文件(每小时一个)
sudo tcpdump -G 3600 -w capture_%H.pcap
# 按大小分割文件(每100MB)
sudo tcpdump -C 100 -w capture.pcap
# 自动压缩归档
sudo tcpdump -w - | gzip > capture_$(date +%Y%m%d_%H%M%S).pcap.gz
八、常用场景命令速查
| 场景 | 命令 |
|------------|--------------------------------------------------|---------|------------------|
| 基础抓包 | sudo tcpdump -i any -w capture.pcap
|
| HTTP分析 | sudo tcpdump -i any -A -s0 'tcp port 80'
|
| DNS调试 | sudo tcpdump -n -s0 port 53
|
| TCP连接 | `sudo tcpdump 'tcp[tcpflags] & (tcp-syn | tcp-fin | tcp-rst) != 0'` |
| IP+端口 | sudo tcpdump 'host 192.168.1.100 and port 443'
|
| 性能监控 | sudo tcpdump -tttt -q -n -i any > traffic.log
|
黄金法则:遇到网络问题,三步走:
sudo tcpdump -i any -w capture.pcap
保存原始数据- 使用过滤命令缩小范围
- 在Wireshark中深入分析
学习资源推荐
- 官方文档 :
man tcpdump
(最权威参考) - 过滤指南 :PCAP-FILTER(7)
- 实战教程 :TCPDump Mastery
- 在线练习 :CloudShark
立即打开终端尝试这些命令,遇到具体问题欢迎在评论区交流讨论!