跳转至

tcpdump 网络抓包

tcpdump 是 Linux 最强大的命令行抓包工具,可以捕获和分析网络数据包。白话说就是"偷听网络上传来传去的数据,找出网络问题在哪"。

核心知识点

概念说明
抓包捕获网络接口上经过的数据包
过滤器按条件筛选要抓的包(IP、端口、协议等)
pcap抓包文件格式,可以用 Wireshark 打开分析
BPFBerkeley Packet Filter,tcpdump 使用的过滤语法
混杂模式抓取网卡上所有包,而不只是发给自己的

安装配置

# Ubuntu/Debian 安装
sudo apt install tcpdump  # 安装 tcpdump

# CentOS/RHEL 安装
sudo yum install tcpdump  # 安装 tcpdump

# 确认安装
tcpdump --version  # 查看版本

# tcpdump 需要 root 权限才能抓包
sudo tcpdump  # 需要 sudo

基本使用

基础抓包

# 抓取所有网卡的所有数据包(按 Ctrl+C 停止)
sudo tcpdump  # 最基础的抓包,会刷屏

# 指定网卡抓包
sudo tcpdump -i eth0  # 只抓 eth0 网卡的包
sudo tcpdump -i any   # 抓所有网卡的包

# 查看可用网卡
sudo tcpdump -D  # 列出可以抓包的网卡列表

# 限制抓包数量
sudo tcpdump -c 100  # 抓 100 个包就停

# 不解析域名(速度更快)
sudo tcpdump -n  # 不把 IP 解析为域名
sudo tcpdump -nn  # IP 和端口都不解析(推荐,速度快)

按协议过滤

# 只抓 TCP 包
sudo tcpdump -i eth0 tcp  # 只抓 TCP 协议的包

# 只抓 UDP 包
sudo tcpdump -i eth0 udp  # 只抓 UDP 协议的包

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

# 只抓 DNS 查询
sudo tcpdump -i eth0 port 53  # DNS 使用 53 端口

# 只抓 HTTP
sudo tcpdump -i eth0 port 80  # HTTP 使用 80 端口

# 只抓 HTTPS
sudo tcpdump -i eth0 port 443  # HTTPS 使用 443 端口

按 IP 和端口过滤

# 抓指定目标 IP 的包
sudo tcpdump -i eth0 host 192.168.1.100  # 与这个 IP 相关的所有包

# 只抓来自某 IP 的包
sudo tcpdump -i eth0 src 192.168.1.100  # src = 来源

# 只抓发往某 IP 的包
sudo tcpdump -i eth0 dst 192.168.1.100  # dst = 目标

# 抓指定端口
sudo tcpdump -i eth0 port 3306  # MySQL 端口

# 抓端口范围
sudo tcpdump -i eth0 portrange 8000-9000  # 8000-9000 范围内的端口

# 组合过滤(and/or/not)
sudo tcpdump -i eth0 host 192.168.1.100 and port 80  # 某 IP 的 HTTP 流量
sudo tcpdump -i eth0 src 10.0.0.1 or src 10.0.0.2    # 来自两个 IP 的包
sudo tcpdump -i eth0 not port 22  # 排除 SSH(抓包时不想看到 SSH 连接的干扰)

# 按网段过滤
sudo tcpdump -i eth0 net 192.168.1.0/24  # 整个子网的包

高级用法

保存和读取抓包文件

# 保存到文件(pcap 格式,可以用 Wireshark 打开)
sudo tcpdump -i eth0 -w capture.pcap  # -w 写入文件

# 保存时带条件
sudo tcpdump -i eth0 port 80 -w http.pcap -c 1000  # 抓 1000 个 HTTP 包保存

# 读取抓包文件
sudo tcpdump -r capture.pcap  # -r 读取文件

# 从文件中过滤
sudo tcpdump -r capture.pcap port 80  # 从已保存的文件中筛选 HTTP 包

# 按文件大小分割(每 100MB 一个文件)
sudo tcpdump -i eth0 -w trace.pcap -C 100  # -C 100 表示 100MB 切割
# 会生成 trace.pcap, trace.pcap1, trace.pcap2...

# 按时间分割(每 3600 秒 = 1 小时一个文件)
sudo tcpdump -i eth0 -w trace.pcap -G 3600  # -G 按秒分割

显示包内容

# 显示包的十六进制内容
sudo tcpdump -i eth0 -X port 80  # -X 十六进制 + ASCII

# 显示 ASCII 内容(可以看到 HTTP 请求内容)
sudo tcpdump -i eth0 -A port 80  # -A 只显示 ASCII

# 增加详细程度
sudo tcpdump -i eth0 -v   # 一个 v 显示更多信息
sudo tcpdump -i eth0 -vv  # 两个 v 更详细
sudo tcpdump -i eth0 -vvv # 三个 v 最详细

# 设置抓取包的最大长度
sudo tcpdump -i eth0 -s 0 port 80  # -s 0 抓完整包(默认可能截断)
sudo tcpdump -i eth0 -s 100  # 只抓前 100 字节

实用抓包场景

# 场景1:排查 DNS 问题
sudo tcpdump -i eth0 -nn port 53  # 看 DNS 查询和响应

# 场景2:抓 HTTP 请求内容
sudo tcpdump -i eth0 -A -s 0 'port 80 and (tcp[13] & 0x18 != 0)'
# 只抓有数据的 HTTP 包(不抓握手包)

# 场景3:排查 TCP 连接问题(三次握手)
sudo tcpdump -i eth0 -nn 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0' and host 目标IP
# 只看 SYN 和 FIN 包,分析连接建立和断开

# 场景4:监控特定服务器之间的通信
sudo tcpdump -i eth0 -nn host 10.0.0.1 and host 10.0.0.2 -c 500 -w server_comm.pcap
# 抓两台服务器之间的 500 个包

# 场景5:排查网络延迟
sudo tcpdump -i eth0 -nn -ttt host 目标IP  # -ttt 显示包之间的时间差

# 场景6:抓 MySQL 查询
sudo tcpdump -i eth0 -nn -A port 3306 | grep -i 'select\|insert\|update\|delete'
# 实时看 MySQL 在执行什么 SQL

配合时间戳

# 显示绝对时间戳
sudo tcpdump -i eth0 -tttt port 80  # 完整日期时间

# 显示每个包之间的时间差
sudo tcpdump -i eth0 -ttt port 80  # 与上一个包的时间差(排查延迟)

# 显示微秒精度
sudo tcpdump -i eth0 --time-stamp-precision=micro  # 微秒精度

常见报错

问题原因解决
tcpdump: permission denied没有 root 权限sudo
No suitable device found没有可用网卡或名称错误tcpdump -D 查看可用网卡
抓不到包过滤条件太严格先去掉过滤条件看看有没有流量
SSH 干扰太多SSH 连接产生大量包not port 22 过滤掉
文件太大抓的包太多了-C 分割或 -c 限制数量
pcap_loop: recvfrom: Network is down网卡断开了检查网络连接

速查表

# === 基础抓包 ===
tcpdump -i eth0               # 指定网卡
tcpdump -i any                # 所有网卡
tcpdump -c 100                # 限制数量
tcpdump -nn                   # 不解析域名和端口

# === 过滤条件 ===
tcpdump host IP               # 指定 IP
tcpdump src/dst IP            # 来源/目标 IP
tcpdump port 端口             # 指定端口
tcpdump portrange 开始-结束   # 端口范围
tcpdump tcp/udp/icmp          # 指定协议
tcpdump net 网段/掩码         # 指定网段

# === 组合条件 ===
tcpdump A and B               # 同时满足
tcpdump A or B                # 满足其一
tcpdump not A                 # 排除

# === 保存与读取 ===
tcpdump -w 文件.pcap          # 保存到文件
tcpdump -r 文件.pcap          # 读取文件
tcpdump -C 大小MB             # 按大小分割
tcpdump -G 秒数               # 按时间分割

# === 显示控制 ===
tcpdump -A                    # 显示 ASCII 内容
tcpdump -X                    # 显示十六进制 + ASCII
tcpdump -v/-vv/-vvv           # 详细程度
tcpdump -s 0                  # 抓完整包
tcpdump -ttt                  # 显示时间差
tcpdump -tttt                 # 显示完整时间