tcpdump 网络抓包
tcpdump 是 Linux 最强大的命令行抓包工具,可以捕获和分析网络数据包。白话说就是"偷听网络上传来传去的数据,找出网络问题在哪"。
核心知识点
| 概念 | 说明 |
|---|
| 抓包 | 捕获网络接口上经过的数据包 |
| 过滤器 | 按条件筛选要抓的包(IP、端口、协议等) |
| pcap | 抓包文件格式,可以用 Wireshark 打开分析 |
| BPF | Berkeley 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 # 显示完整时间