# tcpdump 命令使用详细总结


# tcpdump 命令使用详细总结
`tcpdump` 是类Unix/Linux系统下**开源、轻量、高性能的命令行网络数据包捕获与分析工具**，基于libpcap库实现，是网络故障排查、协议分析、安全审计、流量监控的核心工具。**必须以root/sudo权限运行**才能操作网卡捕获流量，抓包结果可直接在终端分析，也可保存为pcap文件供Wireshark等工具深度解析。

## 一、基础语法
```bash
tcpdump [通用选项] [BPF过滤表达式]
```
- **通用选项**：控制抓包行为、输出格式、文件读写等核心动作
- **BPF过滤表达式**：伯克利包过滤语法，用于精准筛选目标流量，是tcpdump的核心能力

## 二、高频核心选项
按功能分类整理，标注高频必用选项，覆盖99%日常使用场景。

### 2.1 捕获控制选项（核心必用）
| 选项 | 功能说明 | 高频使用场景 |
| :--- | :--- | :--- |
| `-i <接口>` | 指定监听的网络接口，`any` 表示监听所有可用网卡 | 必用，`-i eth0` 抓指定网卡，`-i any` 全网卡抓包 |
| `-c <数量>` | 捕获指定数量的数据包后自动退出 | 避免无限抓包，精准控制抓包规模 |
| `-s <长度>` | 设置每个数据包的抓取长度（snaplen），`-s 0` 表示完整抓取整个数据包 | 解决默认长度导致的包内容截断问题，`-s 128` 仅抓头部减少性能损耗 |
| `-Q <方向>` | 指定抓包流量方向，可选 `in/out/inout`，默认 `inout` | 仅抓入方向/出方向流量，精准过滤 |
| `-p` | 关闭网卡混杂模式 | 普通环境下仅需抓取本机流量，避免不必要的权限开销 |
| `-n` | 不解析主机名，直接显示IP地址，避免DNS反向解析导致的输出卡顿 | 必用，大幅提升抓包响应速度 |
| `-nn` | 不解析主机名、端口号、协议名，完全以数字形式显示 | 最高频选项，比`-n`更彻底，无任何解析开销 |

### 2.2 输出格式选项
| 选项 | 功能说明 | 使用场景 |
| :--- | :--- | :--- |
| `-v/-vv/-vvv` | 逐级增加输出详细程度，`-vvv` 为最详细模式 | 深度分析协议字段、包细节 |
| `-e` | 输出数据链路层（二层）头部信息，包括源MAC、目的MAC、VLAN标签、以太网协议类型 | 排查二层网络问题、MAC地址过滤、VLAN流量分析 |
| `-A` | 仅以ASCII格式打印数据包载荷内容 | 分析HTTP、SMTP等文本类应用层协议 |
| `-X` | 同时以十六进制+ASCII格式打印数据包载荷 | 二进制协议分析、深度排查包内容 |
| `-XX` | 同`-X`，额外打印数据链路层头部的十六进制+ASCII内容 | 二层+三层+四层全内容分析 |
| `-S` | 打印TCP绝对序列号，而非默认的相对序列号 | 精准排查TCP序列号异常、丢包重传问题 |
| `-l` | 开启行缓冲模式 | 抓包同时通过管道`|`实时过滤关键词，如`grep`匹配 |

### 2.3 文件读写选项
| 选项 | 功能说明 | 使用场景 |
| :--- | :--- | :--- |
| `-w <文件名.pcap>` | 将捕获的原始数据包写入文件，而非输出到终端 | 长期抓包、后续离线分析、导出到Wireshark |
| `-r <文件名.pcap>` | 从已保存的pcap文件中读取数据包，配合过滤表达式做离线分析 | 历史流量回溯、二次筛选分析 |
| `-C <文件大小(MB)>` | 自动切割抓包文件，单个文件达到指定大小时，生成新文件（后缀自增.pcap1、.pcap2） | 高流量场景长期抓包，避免单个文件过大 |
| `-G <秒数>` | 按时间周期自动切割抓包文件，常用`-G 3600`（每小时1个文件） | 定时归档流量，配合时间命名`%Y%m%d_%H%M%S`区分文件 |

### 2.4 时间戳控制选项
| 选项 | 功能说明 |
| :--- | :--- |
| `-t` | 不打印时间戳 |
| `-tt` | 打印秒级时间戳（从1970年至今的秒数） |
| `-ttt` | 打印当前包与上一个包的时间间隔 |
| `-tttt` | 打印完整的日期+时间戳，可读性最高 |

## 三、BPF过滤规则（核心能力）
tcpdump的过滤能力基于BPF语法，可通过**类型、方向、协议、逻辑组合**实现精准流量筛选，避免捕获无关流量，提升抓包效率与分析效率。

### 3.1 基础过滤规则
#### 1. 主机/网络过滤（二层/三层地址过滤）
| 表达式 | 功能说明 |
| :--- | :--- |
| `host 192.168.1.100` | 捕获源或目的IP为192.168.1.100的所有流量 |
| `src host 10.0.0.5` | 仅捕获源IP为10.0.0.5的流量 |
| `dst host 172.16.0.10` | 仅捕获目的IP为172.16.0.10的流量 |
| `net 192.168.1.0/24` | 捕获192.168.1.0/24网段的所有流量 |
| `src net 10.0.0.0/8` | 仅捕获源地址属于10.0.0.0/8网段的流量 |
| `ether host 00:11:22:33:44:55` | 基于MAC地址过滤流量 |
| `broadcast` | 捕获广播包 |
| `multicast` | 捕获组播包 |

#### 2. 端口过滤（四层端口过滤）
| 表达式 | 功能说明 |
| :--- | :--- |
| `port 80` | 捕获源或目的端口为80的流量 |
| `src port 53` | 仅捕获源端口为53的流量（DNS响应） |
| `dst port 22` | 仅捕获目的端口为22的流量（SSH请求） |
| `portrange 1000-2000` | 捕获端口在1000-2000范围内的流量 |
| `src portrange 5000-6000` | 仅捕获源端口在指定范围的流量 |

#### 3. 协议过滤（按网络协议分层过滤）
| 表达式 | 功能说明 |
| :--- | :--- |
| `ether` | 以太网二层协议过滤，如`ether arp` |
| `arp` / `rarp` | 捕获ARP/RARP协议包（地址解析） |
| `ip` / `ip6` | 捕获IPv4/IPv6协议包 |
| `icmp` / `icmp6` | 捕获ICMP/ICMPv6包（ping/tracert流量） |
| `tcp` | 仅捕获TCP协议包 |
| `udp` | 仅捕获UDP协议包 |
| `sctp` | 捕获SCTP协议包 |

#### 4. 逻辑运算符（多条件组合过滤）
通过逻辑运算符实现多条件精准筛选，**复杂表达式建议用单引号包裹，避免shell解析特殊字符**。
| 运算符 | 功能说明 | 示例 |
| :--- | :--- | :--- |
| `and` / `&&` | 逻辑与，多个条件同时满足 | `host 192.168.1.100 and port 80` |
| `or` / `||` | 逻辑或，满足任意一个条件 | `port 80 or port 443` |
| `not` / `!` | 逻辑非，排除指定条件 | `not port 22`（排除SSH流量） |
| `()` | 括号，改变运算优先级 | `src net 192.168.1.0/24 and (dst port 80 or dst port 443)` |

### 3.2 高级过滤规则（基于包内容/字段偏移）
针对协议头部字段、载荷内容进行精准匹配，适用于深度协议分析、异常流量排查。

#### 1. TCP标志位过滤
TCP头部的标志位是连接状态诊断的核心，常用过滤规则如下：
| 表达式 | 功能说明 |
| :--- | :--- |
| `'tcp[tcpflags] & tcp-syn != 0'` | 捕获TCP SYN包（TCP连接发起请求） |
| `'tcp[tcpflags] & tcp-fin != 0'` | 捕获TCP FIN包（TCP连接关闭请求） |
| `'tcp[tcpflags] & tcp-rst != 0'` | 捕获TCP RST包（TCP连接强制重置） |
| `'tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)'` | 捕获TCP SYN+ACK包（TCP连接响应） |
| `'tcp[tcpflags] & (tcp-syn|tcp-fin|tcp-rst) != 0'` | 捕获TCP连接全生命周期的关键控制包 |

#### 2. 应用层内容过滤
基于数据包载荷的偏移量匹配关键词，精准捕获应用层请求：
```bash
# 捕获HTTP GET请求（GET 对应的十六进制为0x47455420）
tcpdump -nn -A 'tcp port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'

# 捕获HTTP POST请求
tcpdump -nn -A 'tcp port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504F5354'

# 捕获包含指定关键词的DNS查询
tcpdump -nn 'udp port 53 and udp[10] & 0x80 = 0'
```

#### 3. 其他高级过滤
```bash
# 捕获IP分片包
tcpdump -nn 'ip[6:2] & 0x1fff != 0'

# 捕获VLAN标签的流量
tcpdump -nn -e vlan

# 捕获TCP窗口为0的包（流量控制异常、零窗口）
tcpdump -nn 'tcp[14:2] = 0'
```

## 四、tcpdump 输出内容完整解读
掌握输出字段的含义，才能快速分析抓包结果。以下是典型的TCP包输出示例，逐字段拆解：
```
14:35:22.123456 IP 192.168.1.100.54321 > 192.168.1.200.80: Flags [S], seq 123456789, win 65535, length 0
```

| 字段 | 含义说明 |
| :--- | :--- |
| `14:35:22.123456` | 数据包捕获时间戳（时:分:秒.微秒），可通过`-tttt`显示完整日期 |
| `IP` | 网络层协议，此处为IPv4，IPv6会显示`IP6` |
| `192.168.1.100.54321` | 源IP地址.源端口号，`-nn`选项下直接显示数字，无解析 |
| `>` | 数据包传输方向，从左侧源地址发往右侧目的地址 |
| `192.168.1.200.80` | 目的IP地址.目的端口号 |
| `Flags [S]` | TCP标志位，核心字段，标识TCP包的类型 |
| `seq 123456789` | TCP序列号，`-S`选项显示绝对序列号，默认显示相对序列号 |
| `win 65535` | TCP窗口大小，标识接收端的缓冲区大小 |
| `length 0` | TCP载荷长度，0表示无应用层数据（仅控制包） |

### 常用TCP标志位速记
| 标志缩写 | 全称 | 核心含义 |
| :--- | :--- | :--- |
| `[S]` | SYN | 连接发起请求 |
| `[S.]` | SYN+ACK | 连接请求响应 |
| `[.]` | ACK | 数据确认包 |
| `[P]` | PSH | 推送数据，立即交给应用层 |
| `[F]` | FIN | 连接正常关闭请求 |
| `[R]` | RST | 连接强制重置 |
| `[U]` | URG | 紧急指针生效 |

## 五、高频实战场景案例
覆盖日常网络排查90%的使用场景，直接复制可用。

### 5.1 基础抓包场景
```bash
# 1. 查看所有可用网卡
tcpdump -D

# 2. 全网卡抓包，不解析域名/端口，基础通用命令
sudo tcpdump -i any -nn

# 3. 抓指定主机的所有流量，排除SSH干扰
sudo tcpdump -i eth0 -nn host 192.168.1.100 and not port 22

# 4. 抓ping包（ICMP流量），排查网络连通性
sudo tcpdump -i any -nn icmp

# 5. 抓指定端口的TCP/UDP流量，如HTTP/HTTPS/SSH/DNS
sudo tcpdump -i any -nn tcp port 80
sudo tcpdump -i any -nn port 443
sudo tcpdump -i any -nn udp port 53

# 6. 抓指定网段到指定端口的流量
sudo tcpdump -i eth0 -nn src net 192.168.1.0/24 and dst port 8080
```

### 5.2 进阶分析场景
```bash
# 1. 抓TCP异常连接包（SYN/FIN/RST），排查连接超时/重置问题
sudo tcpdump -i any -nn 'tcp[tcpflags] & (tcp-syn|tcp-fin|tcp-rst) != 0'

# 2. 抓HTTP请求内容，ASCII格式显示，快速查看请求头/响应
sudo tcpdump -i any -nn -A port 80 | grep -E "GET|POST|Host|HTTP/1.1"

# 3. 抓包并保存到文件，抓满1000个包自动停止
sudo tcpdump -i eth0 -nn -c 1000 -w traffic_capture.pcap

# 4. 按时间切割抓包文件，每1小时生成一个新文件，带时间戳命名
sudo tcpdump -i eth0 -nn -G 3600 -w capture_%Y%m%d_%H%M%S.pcap

# 5. 按大小切割抓包文件，单个文件最大100MB，自动归档
sudo tcpdump -i eth0 -nn -C 100 -w traffic_capture.pcap

# 6. 离线分析pcap文件，筛选指定主机/端口的流量
tcpdump -nn -r traffic_capture.pcap host 192.168.1.100 and port 443

# 7. 查看二层MAC地址，排查ARP/交换机转发问题
sudo tcpdump -i eth0 -nn -e arp
```

## 六、进阶用法与优化技巧
1. **高流量场景抓包优化**
   - 优先使用精准的过滤表达式，减少内核捕获的无关流量，降低性能损耗
   - 避免终端实时输出，直接用`-w`写入文件，终端打印会大幅降低抓包性能
   - 按需设置`-s`抓取长度，仅分析头部时设置`-s 128`，减少内存/磁盘开销

2. **实时流量过滤与监控**
   - 结合`-l`行缓冲模式，实时匹配关键词，快速定位异常：
     ```bash
     sudo tcpdump -i any -nn -A -l port 80 | grep "HTTP/1.1 500"
     ```

3. **容器/虚拟机流量抓取**
   - 容器流量：指定docker网桥`-i docker0`，或进入容器命名空间抓包
   - 虚拟机流量：指定虚拟网卡`-i virbr0`，或对应veth虚拟接口

4. **跨平台分析**
   - tcpdump抓取的`pcap`文件可直接导入Wireshark、科来等图形化工具，进行可视化协议分析、流重组、故障定位

## 七、常见坑与注意事项
1. **权限问题**：tcpdump必须使用`sudo`或root用户运行，普通用户无权限操作网卡捕获流量
2. **混杂模式限制**：现代交换机环境下，混杂模式仅能捕获本机的单播包、广播/组播包，无法捕获同网段其他主机的单播流量，需配置交换机端口镜像（SPAN）才能实现全网抓包
3. **包截断问题**：默认抓取长度可能不足，导致应用层内容被截断，深度分析时必须加`-s 0`完整抓取
4. **DNS解析卡顿**：必须加`-n`/`-nn`选项，否则tcpdump会对每个IP进行反向DNS解析，导致输出严重卡顿，甚至丢包
5. **shell转义问题**：包含括号、&、|等特殊字符的过滤表达式，必须用单引号`''`包裹，否则会被shell解析执行，导致命令报错
6. **丢包问题**：高流量场景下，若内核缓冲区不足，会出现丢包。可通过增大缓冲区`-B 4096`（单位KB）缓解，同时优化过滤表达式减少无关流量
7. **IPv6过滤**：IPv6流量需使用`ip6`关键字过滤，如`tcpdump -nn ip6 host 2409:8a1e::1`，默认`ip`仅匹配IPv4流量


