Linux tcpdump 命令完全指南:网络包分析从入门到精通
引言
在网络故障排查和性能调优中,tcpdump 是每位运维工程师和开发者的必备工具。它能够实时捕获和分析网络接口上传输的数据包,帮助我们定位连接异常、诊断性能瓶颈、分析协议行为。本文将系统性地介绍 tcpdump 的使用方法,从基础抓包到高级过滤,配合实战场景让你快速上手。
tcpdump 工作原理
tcpdump 基于 libpcap 库工作,其流程如下:
- 将网卡设置为混杂模式(Promiscuous Mode),捕获所有经过接口的包
- 通过 BPF(Berkeley Packet Filter) 进行高效的内核级过滤
- 将匹配的数据包拷贝到用户空间进行解析和输出
这种设计使得 tcpdump 即使在流量很大的服务器上也能高效运行。
安装 tcpdump
1 2 3 4 5 6 7 8
| sudo apt update && sudo apt install -y tcpdump
sudo yum install -y tcpdump
tcpdump --version
|
基础用法
查看可用网络接口
输出示例:
1 2 3 4
| 1.eth0 [Up, Running] 2.lo [Up, Running] 3.any (Pseudo-device that captures on all interfaces) 4.docker0 [Up]
|
基础抓包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| sudo tcpdump -i eth0
sudo tcpdump -i any
sudo tcpdump -i eth0 -c 100
sudo tcpdump -i eth0 -n
sudo tcpdump -i eth0 -v
sudo tcpdump -i eth0 -nn
|
保存和读取抓包文件
1 2 3 4 5 6 7 8
| sudo tcpdump -i eth0 -w capture.pcap
tcpdump -r capture.pcap
tcpdump -r capture.pcap -nn port 80
|
核心选项速查表
| 选项 | 说明 | 示例 |
-i | 指定监听的网络接口 | -i eth0 |
-n | 不解析主机名(保留 IP) | -n |
-nn | 不解析主机名和端口名 | -nn |
-c | 抓取指定数量包后退出 | -c 100 |
-s | 设置 snaplen(抓取每个包的字节数,0 为完整包) | -s 0 |
-w | 将原始包写入文件 | -w output.pcap |
-r | 从文件读取包 | -r output.pcap |
-v / -vv / -vvv | 输出详细程度递增 | -vv |
-e | 显示链路层头部(MAC 地址) | -e |
-X | 以 HEX 和 ASCII 输出包内容 | -X |
-A | 以 ASCII 输出包内容(适合 HTTP) | -A |
-q | 精简输出模式 | -q |
-K | 不验证 TCP 校验和 | -K |
-t | 不打印时间戳 | -t |
包过滤表达式(BPF 语法)
tcpdump 的强大之处在于其灵活的过滤表达式。过滤表达式使用 BPF(Berkeley Packet Filter) 语法,支持组合条件。
按协议过滤
1 2 3 4 5 6 7 8 9 10 11
| sudo tcpdump -i eth0 tcp
sudo tcpdump -i eth0 udp
sudo tcpdump -i eth0 icmp
sudo tcpdump -i eth0 arp
|
按主机过滤
1 2 3 4 5 6 7 8 9 10 11
| sudo tcpdump -i eth0 host 192.168.1.100
sudo tcpdump -i eth0 src host 192.168.1.100
sudo tcpdump -i eth0 dst host 192.168.1.100
sudo tcpdump -i eth0 net 192.168.1.0/24
|
按端口过滤
1 2 3 4 5 6 7 8 9 10 11
| sudo tcpdump -i eth0 port 80 sudo tcpdump -i eth0 port 443 sudo tcpdump -i eth0 port 22
sudo tcpdump -i eth0 src port 8080 sudo tcpdump -i eth0 dst port 53
sudo tcpdump -i eth0 portrange 80-443
|
组合过滤条件
使用逻辑运算符 and(&&)、or(||)、not(!)组合多个条件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| sudo tcpdump -i eth0 src host 192.168.1.100 and port 80
sudo tcpdump -i eth0 tcp and not port 22
sudo tcpdump -i eth0 'tcp port 80 and (src host 192.168.1.100 or dst host 192.168.1.100)'
sudo tcpdump -i eth0 'tcp[13] & 2 != 0'
sudo tcpdump -i eth0 'tcp[13] = 18'
|
实战场景
场景1:排查 HTTP 服务不可用
1 2
| sudo tcpdump -i eth0 -nn -A port 80
|
输出示例:
1 2 3 4 5 6 7
| 12:34:56.789012 IP 10.0.0.1.54321 > 10.0.0.2.80: Flags [S], seq 12345, ... GET /api/health HTTP/1.1 Host: example.com ... HTTP/1.1 200 OK Content-Type: application/json ...
|
通过查看实际请求和响应内容,可以快速判断是服务端问题还是客户端问题。
场景2:DNS 解析故障排查
1 2
| sudo tcpdump -i eth0 -nn port 53
|
输出示例:
1 2
| 12:34:57.123456 IP 10.0.0.1.54322 > 8.8.8.8.53: 1234+ A? example.com. (28) 12:34:57.234567 IP 8.8.8.8.53 > 10.0.0.1.54322: 1234 1/0/0 A 93.184.216.34 (44)
|
如果只看到 A? 请求但没有响应,说明上游 DNS 不可达或防火墙拦截了 UDP 53 端口。
场景3:网络延迟分析
1 2 3 4 5
| sudo tcpdump -i eth0 -nn -v host 203.0.113.10
sudo tcpdump -i eth0 -ttt -nn 'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0 and host 203.0.113.10'
|
-ttt 选项会打印每行相对于前一行的微秒级时间差,非常适合分析网络延迟。
场景4:抓取特定进程的网络流量
1 2 3 4 5
| sudo ss -tlnp | grep nginx
sudo tcpdump -i eth0 -nn port 80 or port 443
|
场景5:DHCP 交互分析
1 2
| sudo tcpdump -i eth0 -nn -v port 67 or port 68
|
DHCP 使用四步握手(Discover → Offer → Request → ACK),通过 tcpdump 可以清晰看到每一步的交互过程。
高级技巧
1. 限制包大小以提升性能
1 2
| sudo tcpdump -i eth0 -s 128 -nn port 80
|
在生产服务器上抓包时,建议设置 -s 来减小内存和磁盘开销,除非你需要分析应用层 payload。
2. 抓包并实时统计
1 2
| sudo tcpdump -i eth0 -nn -c 1000 'port 80' 2>/dev/null | awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -rn
|
3. 后台抓包 + 轮转文件
1 2
| sudo nohup tcpdump -i eth0 -nn -C 100 -W 10 -w /var/log/tcpdump/traffic.pcap -Z root &
|
4. 使用 tcpdump 做简单的带宽监控
1 2 3 4 5
| while true; do sudo tcpdump -i eth0 -nn -c 100 -t 2>/dev/null | wc -l sleep 10 done
|
5. 结合 Wireshark 进行图形化分析
1 2 3 4 5
| sudo tcpdump -i eth0 -nn -s 0 -w capture.pcap host 192.168.1.100
|
输出格式解读
tcpdump 默认输出格式如下:
1
| 12:34:56.789012 IP 10.0.0.1.54321 > 10.0.0.2.80: Flags [S], seq 12345:12345, win 65535, options [mss 1460], length 0
|
| 字段 | 示例值 | 说明 |
| 时间戳 | 12:34:56.789012 | 微秒级精度 |
| 协议 | IP | 链路层协议类型 |
| 源地址 | 10.0.0.1.54321 | IP.端口 |
| 方向 | > | > 表示发送;< 表示接收 |
| 目标地址 | 10.0.0.2.80 | IP.端口 |
| TCP 标志 | Flags [S] | S=SYN, F=FIN, R=RST, P=PSH, .=ACK |
| 序列号 | seq 12345:12345 | 起始:结束 |
| 窗口大小 | win 65535 | 接收窗口大小 |
| 选项 | options [mss 1460] | TCP 选项 |
| 长度 | length 0 | 应用层数据长度 |
TCP 标志位速查
| 标志 | 缩写 | 含义 |
[S] | SYN | 连接请求(三次握手第一步) |
[S.] | SYN-ACK | 连接确认(三次握手第二步) |
[.] | ACK | 确认包 |
[P.] | PSH-ACK | 推送数据(传输数据时最常见) |
[F.] | FIN-ACK | 连接关闭 |
[R] | RST | 连接重置(通常表示异常) |
[R.] | RST-ACK | 带确认的重置 |
常见问题排查
| 问题 | 原因 | 解决方案 |
| tcpdump: no suitable device found | 权限不足或设备不存在 | 使用 sudo 运行;检查 tcpdump -D |
| tcpdump: eth0: You don't have permission | 非 root 用户 | 使用 sudo 或添加 CAP_NET_RAW 能力 |
| 捕获到大量无关包 | 过滤条件不精确 | 细化 BPF 过滤表达式 |
| 抓包文件过大 | 未限制大小或 snaplen | 使用 -s 128 和 -C 轮转 |
| 输出显示乱码 | 二进制数据被直接输出 | 用 -A(文本)或 -X(HEX)控制 |
| 无法捕获 VLAN 流量 | 未启用 VLAN 标签解析 | 加 -e 显示链路层头部 |
| tcpdump 消耗高 CPU | 流量过大 | 设置 -c 限制包数;使用 BPF 精准过滤;考虑使用 ntopng 等工具 |
安全注意事项
- 权限管理:tcpdump 需要 root 权限,生产环境不建议长期在后台运行,用完即停
- 数据敏感性:抓包文件可能包含密码、Token 等敏感信息,妥善保管
.pcap 文件
- 法律合规:在非自己控制的网络上抓包可能违反法律,务必获得授权
- 性能影响:在高流量服务器上抓包会增加 CPU 和磁盘 I/O 负载,建议:
- 使用精准过滤条件缩小范围
- 限制 snaplen(
-s 128)
- 避免写入慢速磁盘
- 日志轮转:长时间抓包务必使用
-C(文件大小轮转)和 -W(文件数量限制)
命令速查表
| 场景 | 命令 |
| 查看 HTTP 请求内容 | sudo tcpdump -i eth0 -A port 80 |
| 查看 DNS 查询 | sudo tcpdump -i eth0 -nn port 53 |
| 监控与某个 IP 的所有流量 | sudo tcpdump -i eth0 host 192.168.1.1 |
| 抓取 TCP 三次握手 | sudo tcpdump -i eth0 -nn 'tcp[tcpflags] & (tcp-syn) != 0' |
| 保存到文件供 Wireshark 分析 | sudo tcpdump -i eth0 -s 0 -w capture.pcap |
| 后台持续抓包(轮转) | sudo nohup tcpdump -i eth0 -C 100 -W 10 -w traffic.pcap & |
| 实时带宽统计(粗略) | sudo tcpdump -i eth0 -nn -c 1000 -t 2>/dev/null | wc -l |
| 排除 SSH 会话自身干扰 | sudo tcpdump -i eth0 not port 22 |
| 抓取特定进程流量(间接) | sudo tcpdump -i eth0 port $(sudo ss -tlnp | grep nginx | awk '{print $4}' | cut -d: -f2) |
| 检查 ICMP 丢包 | sudo tcpdump -i eth0 -nn icmp |
| 查看 DHCP 交互 | sudo tcpdump -i eth0 -nn port 67 or port 68 |
| 分析 TCP 重传 | sudo tcpdump -i eth0 -nn 'tcp[tcpflags] & (tcp-retrans) != 0' |
扩展阅读工具
tcpdump 适合快速诊断,但对于深入分析,可以配合以下工具:
- Wireshark / TShark:图形化/命令行协议分析器,提供协议解码树、流量统计、IO 图表等高级功能
- ngrep:类似 grep 但针对网络包,支持正则匹配 payload
- nethogs:按进程显示网络带宽使用
- iftop:实时显示接口带宽(类似 top)
- bmon:带宽监控与可视化
总结
tcpdump 是 Linux 网络诊断工具箱中最核心的成员之一。掌握 tcpdump 不仅意味着会抓包,更重要的是理解 TCP/IP 协议栈的工作原理。本文从基础安装到高级实战,系统性地介绍了 tcpdump 的完整用法。
核心要点:
- 始终用
sudo 运行,用 -nn 避免 DNS 和端口解析延迟
- 精准的 BPF 过滤表达式是高效排障的关键
- 生产环境抓包时注意性能和安全,善用
-s、-C、-c 选项
-w 保存 pcap 文件后配合 Wireshark 图形化分析效率更高
本文由AI辅助生成,内容仅供参考