Linux tcpdump 命令完全指南:网络包分析从入门到精通

Linux tcpdump 命令完全指南:网络包分析从入门到精通

Someone Lv5

引言

在网络故障排查和性能调优中,tcpdump 是每位运维工程师和开发者的必备工具。它能够实时捕获和分析网络接口上传输的数据包,帮助我们定位连接异常、诊断性能瓶颈、分析协议行为。本文将系统性地介绍 tcpdump 的使用方法,从基础抓包到高级过滤,配合实战场景让你快速上手。

tcpdump 工作原理

tcpdump 基于 libpcap 库工作,其流程如下:

  1. 将网卡设置为混杂模式(Promiscuous Mode),捕获所有经过接口的包
  2. 通过 BPF(Berkeley Packet Filter) 进行高效的内核级过滤
  3. 将匹配的数据包拷贝到用户空间进行解析和输出

这种设计使得 tcpdump 即使在流量很大的服务器上也能高效运行。

安装 tcpdump

1
2
3
4
5
6
7
8
# Ubuntu / Debian
sudo apt update && sudo apt install -y tcpdump

# RHEL / CentOS / Rocky
sudo yum install -y tcpdump

# 验证安装
tcpdump --version

基础用法

查看可用网络接口

1
tcpdump -D

输出示例:

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

# 只抓取 N 个包后停止
sudo tcpdump -i eth0 -c 100

# 不进行 DNS 解析(加快速度)
sudo tcpdump -i eth0 -n

# 显示更详细的信息
sudo tcpdump -i eth0 -v

# 不解析端口为服务名
sudo tcpdump -i eth0 -nn

保存和读取抓包文件

1
2
3
4
5
6
7
8
# 保存到文件(-w 写入,-W 文件大小 MB)
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
# 只抓 TCP 包
sudo tcpdump -i eth0 tcp

# 只抓 UDP 包
sudo tcpdump -i eth0 udp

# 只抓 ICMP 包(ping)
sudo tcpdump -i eth0 icmp

# 只抓 ARP 包
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

# 抓取源 IP 为 192.168.1.100 的包
sudo tcpdump -i eth0 src host 192.168.1.100

# 抓取目标 IP 为 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

# 抓取端口范围(HTTP/HTTPS)
sudo tcpdump -i eth0 portrange 80-443

组合过滤条件

使用逻辑运算符 and&&)、or||)、not!)组合多个条件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 抓取来自 192.168.1.100 的 HTTP 流量
sudo tcpdump -i eth0 src host 192.168.1.100 and port 80

# 抓取非 SSH 的 TCP 流量
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)'

# 抓取 SYN 包(三次握手第一步)
sudo tcpdump -i eth0 'tcp[13] & 2 != 0'

# 抓取 SYN-ACK 包
sudo tcpdump -i eth0 'tcp[13] = 18'

实战场景

场景1:排查 HTTP 服务不可用

1
2
# 监控 80 端口的双向流量,ASCII 输出
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
# 抓取 DNS 查询和响应
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
# 抓取与特定服务器的 TCP 握手,查看时间戳
sudo tcpdump -i eth0 -nn -v host 203.0.113.10

# 更精确的延迟测量:记录 SYN 和 SYN-ACK 的时间
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
# 先找到进程 PID
sudo ss -tlnp | grep nginx

# 用 cgroup 过滤器(需要内核支持)或通过端口间接抓取
sudo tcpdump -i eth0 -nn port 80 or port 443

场景5:DHCP 交互分析

1
2
# 抓取 DHCP 协议(端口 67/68,UDP)
sudo tcpdump -i eth0 -nn -v port 67 or port 68

DHCP 使用四步握手(Discover → Offer → Request → ACK),通过 tcpdump 可以清晰看到每一步的交互过程。

高级技巧

1. 限制包大小以提升性能

1
2
# 只抓取每个包的前 128 字节(头部信息)
sudo tcpdump -i eth0 -s 128 -nn port 80

在生产服务器上抓包时,建议设置 -s 来减小内存和磁盘开销,除非你需要分析应用层 payload。

2. 抓包并实时统计

1
2
# 每秒统计 HTTP 流量
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
# 后台持续抓包,每 100MB 轮转一个文件,保留 10 个文件
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
# 每 10 秒统计一次流量
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

# 将文件传到本地,用 Wireshark 打开
# Wireshark 提供强大的协议解析、流量统计、对话分析等功能

输出格式解读

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.54321IP.端口
方向>> 表示发送;< 表示接收
目标地址10.0.0.2.80IP.端口
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 等工具

安全注意事项

  1. 权限管理:tcpdump 需要 root 权限,生产环境不建议长期在后台运行,用完即停
  2. 数据敏感性:抓包文件可能包含密码、Token 等敏感信息,妥善保管 .pcap 文件
  3. 法律合规:在非自己控制的网络上抓包可能违反法律,务必获得授权
  4. 性能影响:在高流量服务器上抓包会增加 CPU 和磁盘 I/O 负载,建议:
    • 使用精准过滤条件缩小范围
    • 限制 snaplen(-s 128
    • 避免写入慢速磁盘
  5. 日志轮转:长时间抓包务必使用 -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辅助生成,内容仅供参考

  • 标题: Linux tcpdump 命令完全指南:网络包分析从入门到精通
  • 作者: Someone
  • 创建于 : 2026-06-12 22:15:00
  • 更新于 : 2026-06-18 08:39:57
  • 链接: https://demo-blog.qusite.cn/2026-06-12-tcpdump-command-guide/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。