tcpdump
Tcpdump
tcpdump 是一个强大的命令行工具,用于捕获和分析网络流量。它是网络管理员、安全专业人员和开发人员在 Linux/Unix-like 系统上进行网络故障排除、监控、安全审计和协议分析的必备工具。
你可以把 tcpdump 想象成是给你的网卡安装了一双“透视眼”:
它让你实时看到数据包是怎么在网络中穿梭的,从 MAC 层到 IP 层再到应用层,全都一览无遗。你不仅能“看到”别人说了什么(数据内容),还能知道他们从哪里来、去哪儿、用了哪种语言(协议)、走了哪条路(路由)
一、Tcpdump 核心概念:捕获与过滤
tcpdump 的核心功能:
- 实时数据包捕获:
tcpdump可以实时地从网络接口捕获数据包,并将其内容打印到标准输出或保存到文件。 - 丰富的过滤表达式:它支持使用 BPF (Berkeley Packet Filter) 语法创建高度定制的过滤规则,只捕获你感兴趣的流量。
- 协议解析:
tcpdump可以解析多种网络协议的头部信息,包括 Ethernet, IP, TCP, UDP, ICMP, ARP, DNS, HTTP 等,并以可读的格式显示。 - 远程捕获:由于是命令行工具,
tcpdump非常适合在没有图形界面的远程服务器上运行。 - 离线分析:可以将捕获的数据包保存为
.pcap文件,供后续使用tcpdump本身或 Wireshark 等图形工具进行离线分析
二、Tcpdump 基本用法与常用选项
- 基本语法:
sudo tcpdump [选项] [过滤表达式]
由于 tcpdump 需要访问网络接口的原始数据,因此通常需要 root 权限运行(使用 sudo)。
核心命令行选项:
-i <interface>:指定要监听的网络接口。- 示例:
sudo tcpdump -i eth0(监听eth0接口) - 示例:
sudo tcpdump -i any(监听所有可用接口,但不使用混杂模式) - 可以通过
tcpdump -D或tcpdump --list-interfaces查看所有可用接口。
- 示例:
-n:不解析主机名(显示 IP 地址)。这可以加快输出速度,并避免 DNS 解析带来的额外网络流量。-nn:不解析主机名和端口号(显示 IP 地址和端口号)。-v/-vv/-vvv:显示更详细的包信息。-c <count>:指定捕获数据包的数量,达到数量后自动停止。- 示例:
sudo tcpdump -c 10 -i eth0(捕获eth0上的前10个数据包)
- 示例:
-w <file>:将捕获的数据包写入文件,文件格式为.pcap。- 示例:
sudo tcpdump -w capture.pcap -i eth0(将捕获的数据保存到capture.pcap)
- 示例:
-r <file>:从指定的.pcap文件中读取数据包进行分析。- 示例:
sudo tcpdump -r capture.pcap(读取capture.pcap并显示内容)
- 示例:
-v,-vv,-vvv:提高输出的详细程度(verbosity)。v越多,显示的信息越多,包括 TTL、ID、报文长度等。-A:以 ASCII 格式打印每个数据包的内容(用于查看 HTTP 等文本协议的数据)。-X:以十六进制和 ASCII 格式打印每个数据包的内容(包括链路层头部)。-XX:同-X,但包含链路层头部。-s <snaplen>:设置捕获的数据包的快照长度(snap length),即每个数据包捕获的字节数。默认通常很大 (e.g., 65535),这意味着捕获整个数据包。设置为 0 则表示捕获整个数据包。- 示例:
sudo tcpdump -s 100 -i eth0(只捕获每个数据包的前100字节)
- 示例:
-e:在输出中显示链路层头部信息(如 MAC 地址)。-l:使输出行缓冲。这在将tcpdump的输出通过管道传递给其他命令(如grep)时很有用。
三、精通过滤表达式 (BPF 语法)
过滤表达式是 tcpdump 最强大的功能之一。你可以通过它们来精确地指定你想要捕获的流量。过滤器可以由一个或多个“原语”(primitives)组成,并通过逻辑运算符 and (&&), or (||), not (!) 进行组合。
BPF(Berkeley Packet Filter) 是一种用于过滤网络数据包的表达式语言,最初用于 Unix 系统的 tcpdump 和 libpcap,现在广泛用于:
tcpdumpiptables/nftablesWiresharkeBPF(扩展 BPF,用于内核监控、安全、可观测性)
BPF 表达式基本结构
BPF 表达式由若干部分构成,一般顺序如下:
1 | [协议] [方向] [匹配类型] [操作符] [值] |
这几项不是必须全部出现,可以按需组合。
类型(Type)限定符:指定要匹配的“类型”。
host <hostname/ip>:匹配特定主机。tcpdump host 192.168.1.1(捕获与192.168.1.1相关的所有流量)
net <network/cidr>:匹配特定网络。tcpdump net 192.168.1.0/24(捕获192.168.1.0/24网络的所有流量)
port <port_number>:匹配特定端口。tcpdump port 80(捕获所有端口 80 的流量)
portrange <port1-port2>:匹配端口范围。tcpdump portrange 1024-65535
方向(Direction)限定符:指定流量方向。
src:源地址。dst:目的地址。src or dst: (默认)任意方向。src and dst:必须同时匹配。tcpdump src host 192.168.1.10(捕获源自192.168.1.10的流量)tcpdump dst port 22(捕获目标端口为 22 的流量)
协议(Protocol)限定符:指定协议类型。
ether(以太网帧)ip(IPv4)ip6(IPv6)arp(ARP)rarp(RARP)tcp(TCP)udp(UDP)icmp(ICMP)vlan(VLAN)tcpdump tcp(捕获所有 TCP 流量)tcpdump udp port 53(捕获 UDP 协议的 DNS 流量)
逻辑运算符:
and(&&):与or(||):或not(!):非=/!=>/<&(按位与)组合示例:
tcp and host 192.168.1.10 and port 80(注意括号转义\(\)在 shell 中使用时的必要性)
组合过滤表达式:
使用 and, or, not (或它们的符号 &&, ||, !) 来组合过滤条件。
当使用逻辑运算符时,建议使用括号 () 来明确优先级,但需要注意在 shell 中使用括号时需要进行转义 ( 和 )。
tcpdump host 192.168.1.1 and port 22tcpdump src host 192.168.1.10 and not dst port 22tcpdump 'tcp port 80 or tcp port 443'(注意引号,避免 shell 解析|)tcpdump -i eth0 'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn'(捕获 SYN 包)tcpdump icmp[icmptype] == icmp-echo(捕获 ping 请求)
字节偏移访问(BPF 原生命令)
BPF 支持通过偏移访问协议头部的特定字段,这种方式功能强大,能直接检查如 TTL、flags、窗口大小等底层内容。
格式如下:
1 | proto[offset[:len]] op value |
例如:
1 | tcp[13] & 0x02 != 0 # SYN |
ip[8] 是 IPv4 报文中的 TTL 字段
tcp[13] 是 TCP 报文中的 flags 字节
tcp[14:2] 是 TCP 窗口大小字段(两个字节)
TCP Flags参考表(TCP/IP 报文结构):
| Flag | 16进制 | 描述 |
|---|---|---|
| FIN | 0x01 | 连接终止 |
| SYN | 0x02 | 发起连接 |
| RST | 0x04 | 连接复位 |
| PSH | 0x08 | 推送数据 |
| ACK | 0x10 | 应答确认 |
| URG | 0x20 | 紧急数据 |
组合示例:
1 | tcpdump 'ip[9] = 6 and tcp[13] & 0x12 = 0x12 and port 80' |
四、tcpdump 输出
tcpdump 的输出格式可能看起来很复杂,但它遵循一定的模式。一般信息包括:
1 | 时间戳 协议 源IP.源端口 > 目的IP.目的端口 标志: [数据] 序列号 确认号 窗口大小 选项 [数据长度] |
例子:
1 | 14:30:00.123456 IP 192.168.1.10.54321 > 192.168.1.1.80: Flags [S], seq 1234567, win 29200, options [mss 1460,sackOK,TS val 123456 ecr 0], length 0 |
14:30:00.123456:数据包捕获的时间戳。IP:网络层协议(IPv4)。192.168.1.10.54321:源 IP 地址和源端口。>:方向指示符。192.168.1.1.80:目的 IP 地址和目的端口。Flags [S]:TCP 标志。S表示 SYN (同步)。常见标志有S(SYN),.(ACK),P(PSH),F(FIN),R(RST)。seq 1234567:TCP 序列号。win 29200:TCP 窗口大小。options [...]:TCP 选项,如 MSS (最大段大小), SACK (选择性确认) 等。length 0:应用层数据长度(不包括头部)。
五、Tcpdump 实践:常见网络问题诊断
核心理念:通过观察数据包的进出、序列号、标志位和时间戳来判断问题。
常用诊断用例与命令示例:
1 |
|
六、优化 Tcpdump 使用体验与进阶技巧
- 屏幕输出控制:
Ctrl+S(暂停) /Ctrl+Q(恢复):最简单的实时控制。- 通过管道传输到
less:sudo tcpdump -l -i eth0 | less(分页查看)。
- 实时保存与文件轮换:
-w <filename.pcap>:保存到文件。-C <size>/-W <count>/-G <seconds>:实现文件自动轮换,管理存储空间。- 示例:
sudo tcpdump -n -i eth0 -w /var/log/tcpdump/capture_%Y%m%d_%H%M.pcap -G 3600 -W 24
- 与 Wireshark 结合:
- 强调
tcpdump捕获.pcap文件后,使用 Wireshark 进行可视化和深度分析是最佳实践。
- 强调
- 远程抓包:
- 通过 SSH 结合
tcpdump进行远程服务器上的抓包。 - 示例:
ssh user@host "sudo tcpdump -i eth0 -w - 'not port 22'" | wireshark -k -S -i -
- 通过 SSH 结合
