tcpdump 抓包分析
tcpdump 是网络工程师的听诊器——直接捕获网卡上流过的每一个数据包,看到真实的网络行为,而不只是工具的推断。掌握过滤语法和输出解读,是排查疑难网络问题的核心能力。
基本语法
tcpdump [选项] [过滤表达式]
常用选项:
-i eth0 # 指定接口(-i any = 所有接口)
-n # 不做 DNS 反查(IP 不转域名)
-nn # 不做 DNS 和端口名反查(端口显示数字)
-v/-vv/-vvv # 详细程度(-vv 适合日常)
-c 100 # 抓 100 个包后停止
-s 0 # 抓完整包(默认只抓 68 字节)
-w /tmp/cap.pcap # 保存到文件(用 Wireshark 打开)
-r /tmp/cap.pcap # 读取已保存的文件
-A # 以 ASCII 显示包内容(看 HTTP 明文有用)
-X # 以十六进制+ASCII 显示
-e # 显示链路层头(MAC 地址)
-t # 不显示时间戳
-S # 显示绝对序号(而非相对序号)
过滤表达式速查
# === 按协议 ===
tcpdump -i eth0 tcp
tcpdump -i eth0 udp
tcpdump -i eth0 icmp
tcpdump -i eth0 arp
tcpdump -i eth0 not arp and not icmp # 排除 ARP 和 ping
# === 按 IP 地址 ===
tcpdump -i eth0 host 192.168.1.100 # 与该IP的所有通信
tcpdump -i eth0 src host 192.168.1.100 # 来自该IP
tcpdump -i eth0 dst host 192.168.1.100 # 发往该IP
tcpdump -i eth0 net 10.0.0.0/8 # 某个网段
# === 按端口 ===
tcpdump -i eth0 port 80 # HTTP
tcpdump -i eth0 port 80 or port 443 # HTTP 或 HTTPS
tcpdump -i eth0 portrange 8000-8100 # 端口范围
# === 按 TCP 标志 ===
tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0' # SYN 包(新连接)
tcpdump -i eth0 'tcp[tcpflags] & tcp-rst != 0' # RST 包(连接重置)
tcpdump -i eth0 'tcp[tcpflags] == tcp-syn' # 只有 SYN 的包
# === 复合条件 ===
tcpdump -i eth0 -nn 'host 10.0.50.10 and port 3306' # MySQL 连接
tcpdump -i eth0 -nn 'tcp port 443 and (tcp[tcpflags] & tcp-syn != 0)' # HTTPS 新建连接
tcpdump -i eth0 -nn 'not port 22' # 排除 SSH(避免刷屏)
输出解读
# 命令:
tcpdump -i eth0 -nn host 8.8.8.8 and icmp
# 输出:
10:23:45.123456 IP 192.168.1.100 > 8.8.8.8: ICMP echo request, id 12345, seq 1, length 64
10:23:45.143789 IP 8.8.8.8 > 192.168.1.100: ICMP echo reply, id 12345, seq 1, length 64
# 字段解析:
# 10:23:45.123456 = 时间戳(精确到微秒)
# IP = 网络层协议(IP)
# 192.168.1.100 = 源地址
# > = 流向
# 8.8.8.8 = 目标地址
# ICMP echo request = 协议 + 包类型
# seq 1 = ICMP 序号
# length 64 = 包大小
# TCP 连接抓包示例:
tcpdump -i eth0 -nn -S host 10.0.50.10 and port 3306
# 10:00:01.000 IP 10.0.10.100.54321 > 10.0.50.10.3306: Flags [S], seq 1000, win 64240
# ↑SYN (新连接)
# 10:00:01.001 IP 10.0.50.10.3306 > 10.0.10.100.54321: Flags [S.], seq 2000, ack 1001, win 65535
# ↑SYN-ACK (服务器响应)
# 10:00:01.002 IP 10.0.10.100.54321 > 10.0.50.10.3306: Flags [.], ack 2001
# ↑ACK (三次握手完成)
# TCP Flags 速查:
# [S] = SYN
# [.] = ACK(单独的确认)
# [P.] = PSH+ACK(有数据)
# [F.] = FIN+ACK(正常关闭)
# [R] = RST(强制重置)
# [S.] = SYN+ACK
实战场景:排查 MySQL 连接问题
# 场景:应用报错"MySQL connection timeout"
# 1. 抓取 MySQL 连接的 TCP 握手
tcpdump -i eth0 -nn -c 50 'host 10.0.50.10 and port 3306'
# 可能的情况:
# 情况 A:看到 SYN,没有 SYN-ACK
# 10:00:01 IP app-server > 10.0.50.10.3306: Flags [S]
# (沉默)
# → 防火墙丢弃了 SYN,MySQL 服务器没有收到
# 情况 B:看到 SYN,RST 立即响应
# 10:00:01 IP app-server > 10.0.50.10.3306: Flags [S]
# 10:00:01 IP 10.0.50.10 > app-server: Flags [R]
# → 端口开放但被拒绝(MySQL 没启动,或 bind-address 不对)
# 情况 C:三次握手成功,然后 RST
# [S] → [S.] → [.] → 数据 → [R]
# → 连接建立但认证失败(密码/权限问题),MySQL 发了 RST
# 2. 在 MySQL 服务器上同时抓包(看是否收到 SYN)
# 如果应用服务器有 SYN,MySQL 服务器没收到 → 中间防火墙问题
# 如果 MySQL 服务器收到 SYN,但没响应 → 本机防火墙或 MySQL 配置问题
保存和离线分析
# 保存抓包文件(供 Wireshark 打开)
tcpdump -i eth0 -nn -s 0 -w /tmp/capture.pcap \
'host 10.0.50.10 and not port 22'
# 指定文件大小限制(每 100MB 切割一个文件)
tcpdump -i eth0 -s 0 -w /tmp/cap-%Y%m%d_%H%M%S.pcap \
-G 3600 -C 100 # -G: 每3600秒切割; -C: 每100MB切割
# 从文件读取并过滤
tcpdump -r /tmp/capture.pcap -nn 'tcp[tcpflags] & tcp-rst != 0'
# 统计 Top 10 连接
tcpdump -r /tmp/capture.pcap -nn | \
awk '{print $3, $5}' | sort | uniq -c | sort -rn | head 10
常用一句话命令
# 监控所有新 TCP 连接(SYN 包)
tcpdump -i any -nn 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack = 0'
# 抓 HTTP 请求(明文,看 GET/POST)
tcpdump -i eth0 -A -nn 'tcp port 80 and (tcp[tcpflags] & tcp-push != 0)'
# 检查 DNS 查询
tcpdump -i eth0 -nn 'udp port 53'
# 检查 ARP(IP 冲突排查)
tcpdump -i eth0 -e arp
# 监控 ICMP 丢包
tcpdump -i eth0 -nn 'icmp and icmp[icmptype] == 3' # Destination Unreachable
# 不抓 SSH 流量(在通过 SSH 管理时避免刷屏)
tcpdump -i eth0 -nn not port 22
CCNA 对应考点
考纲位置:Domain 6.2 — Describe the use of IP SLA
tcpdump 不在 CCNA 考纲内,但理解数据包结构(IP 头、TCP 标志位、ICMP 类型)是考纲要求的基础知识,tcpdump 是验证这些理论最好的实践工具。
下一节:Wireshark 过滤与协议分析——tcpdump 是命令行抓包,Wireshark 提供图形界面和协议解析,能看到每个协议字段的详细内容。