TCPDump
概述
参考:
TCPDump 是一个在命令行界面下的 Packet analyzer(数据包分析器)。tcpdump 适用于大多数类 Unix 操作系统,在这些系统中,tcpdump 使用 libpcap 库来捕获数据包。对于 Windows 操作系统来说,tcpdump 使用的 pcap API 是 WinPcap(即 libpcap 的 Windows 版本)。
tcpdump 最初由Van Jacobson、Sally Floyd、Vern Paxson和Steven McCanne于 1988 年编写,他们当时在劳伦斯伯克利实验室网络研究小组工作。到 1990 年代后期,有许多版本的 tcpdump 作为各种操作系统的一部分分发,以及许多没有很好协调的补丁。 Michael Richardson (mcr)和Bill Fenner于 1999 年创建 www.tcpdump.org
说明:Dump 有 转出,倾卸;转储;内容全部打印 的含义,在官方文档中,通过 TCPDump 程序输出的数据包,通常称为 dump line,转储的行。说白了就是程序抓到的包,每个包都是一行
Syntax(语法)
tcpdump [OPTIONS] [Filter-Expression]
OPTIONS
- -A # 以 ASCII 打印每个数据包 (减去其链接级别标头)。方便捕捉网页。
- -c <INT> # 指定程序将会捕获的数据包数量。
- -D, –list-interfaces # 列出可用于抓包的接口。将会列出接口的数值编号和接口名,它们都可以用于"-i"后
- -e # 在每条 dump 出来的行上显示二层头信息。这个选项可以输出 以太网 和 IEEE802.11 等协议的 MAC 层信息。
- Notes: 通常用来抓取 VLAN 的 Tag。
- -F <FEIL> # 指定一个包含 Filter-Expression 语法的文件。程序将会使用该文件的内容作为过滤表达式,并忽略命令行给出的过滤表达式。
- -i, –interface <DEV> # 抓取指定网卡 DEV 的包,
默认值:any,即抓取所有设备 - -l # 使用标准输出列的缓冲区;
- -n # 不把主机的网络地址转换成 IP。可以多次指定,-nn 表示不转换 IP 地址和端口号的名称
- -O # 不将数据包编码最佳化
- -p # 不让网络界面进入混杂模式
- -q # 快速输出,仅列出少数的传输协议信息
- -r <FILE> # 从 FILE 读取数据包。FILE 是通过 -w 选项保存的文件,或者任何使用 pcap API 的应用程序生成的文件。
- -s <数据包大小> # 设置每个数据包的大小;
- -S, –absolute-tcp-sequence-numbers # 输出 TCP sequence 号的绝对值,而不是相对值
- -tt # 显示每个抓到的包的时间戳(自 1970 年 1 月 1 日 00:00:00 以来)
- -tttt # 显示每个抓到的包的绝对时间
- -ttttt # 显示每个抓到的包的相对时间,单位微妙,第一个包是
00:00:00.000000, - -T <数据包类型> # 强制将表达方式所指定的数据包转译成设置的数据包类型;
- -v[vv] # 从一个 v 开始,每多一个 v 则抓出的包的信息则做出一部分最多 3 个 v,包信息最多
- -w </Path/TO/FILE> # 把数据包数据写入指定的文件
[!tip] -i 选项说明:
- 在有 Bond 的服务器上,不要抓所有设备的包,否则使用 Wireshark 读取抓包文件时,会显示出很多乱序和重传,这是因为 Bond 设备和 Bond Salve 设备的包是相同的,但是咱都抓了。相同的包,时间不同,Wireshark 就识别成乱序了。
- 若使用 any,则用 -w 生成的 .pcap 文件中,所有包的二层信息(i.e. Mac 信息)是异常的,显示为
Linux cooked capture v1
Filter-Expression(过滤表达式)
Filter Expression(过滤表达式) 用于过滤抓取到的数据包。可以让 tcpdump 程序只输出通过表达式匹配到的数据包。
过滤表达式由一个或多个 Primitives(原语) 组成。原语通常是一个具有一个或多个 Qualifiers(限定词) 的 ID。ID 就是 端口号、主机名、IP 地址 等等
Qualifiers(限定词)
一共有三种类型的限定词:
- TYPE # 类型限定词。指定 ID 的类型。默认值:
host- host # 匹配主机名称或 IP 地址
- net # 匹配网段,CIDR 模式。比如:1.2.3.0/24
- port # 匹配端口号
- portrange # 匹配端口号的范围。两个端口号中间以
-连接
- DIR # direction(方向) 限定词。指定 ID 的传输方向。默认值:
src or dst- src
- dst
- …… 等等
- PROTO # 协议限定词。指定要匹配的协议
- icmp
- ip
- ip6
- arp
- tcp
- udp
- ……等等
不同类型的限定符之间可以互相组合,以实现更复杂的描述,比如:
- 类型匹配和方向匹配组合
- src host 1.1.1.1 # 匹配源主机为 1.1.1.1 的数据包
- 类型匹配、方向匹配、协议匹配全部组合在一起
- udp dst portrange 100-400 # 匹配 目的端口范围在 100-400 之间的 UDP 协议的数据包
相同类型的限定符之间也可以互相组合,但是需要使用逻辑表达式 and、or、not(或者用符号表示 &&、||、!) 来连接两个限定符,比如:
- icmp or tcp # 匹配 icmp 或 tcp 的数据包
- ip host 1.1.1.1 and ! 2.2.2.2 # 匹配 1.1.1.1 主机,但不包括 2.2.2.2 主机之间的通信
- src and dst port 1111 # 匹配 源端口 和 目的端口 都是 1111 的数据包
- tcp src or dst portrange 1111-2222 # 匹配 源 或者 目的 任意一个方向的端口范围在 1111-2222 之间的 TCP 协议的数据包
- 注意:为了节省输入,可以省略相同的限定符,下面两个表达式的作用完全相同:
- tcp dst port 21 or 22 or 23
- tcp dst port 21 or tcp dst port 22 or tcp dst port 33
- icmp or tcp dst port 23 and host 1.1.1.1 # 匹配 icmp 或 tcp,目的端口为 23 且主机为 1.1.1.1 的数据包
对于比较复杂的过滤器表达式,为了逻辑的清晰,可以使用括号。不过默认情况下,tcpdump 把 () 当做特殊的字符,所以必须使用单引号 ’ 来消除歧义:
- tcpdump -nvv -c 20 ‘src 10.0.2.4 and (dat port 3389 or 22)’
TYPE 限定词
DIR 限定词
PROTO 限定词
各种协议的数据包,都有其各自的包头,tcpdump 可以根据包头中的字段的值进行过滤,比如只抓 TCP 标志为 SYN 的包,只抓 HTTP 的包,等等。
协议限定词扩展语法如下:
- PROTO[EXPR:SIZE]
- PROTO # 协议名
- EXPR # 表达式
- SIZE #
简单示例:
- 匹配 TCP 头中标志为 tcp-syn 的包
- tcp[tcpflags] & tcp-syn != 0
- 匹配 TCP 头中标志为 SYN 或 FIN 的包。也就是说一个 TCP 会话的开始和结束的包。
- tcp[tcpflags] & (tcp-syn|tcp-fin) != 0
应用示例
https://cloud.tencent.com/developer/article/1858612
从 bond0 网卡抓取 源地址为 10.10.10.10 且 端口号为 18999 的 UDP 的包,每个包大小为 500
- tcpdump -i bond0 udp port 18999 and src host 10.10.10.10 -s 500 0nvvvSe -T snmp
抓取 eth9 网卡,到 111.30.199.159 的包,记录到/tmp/srcIP 中
- tcpdump -i eth9 host 111.30.199.159 -Avns 0 -w /tmp/srcIP
- tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F”.” ‘{print $1"."$2"."$3"."$4"."}’ | sort |uniq -c | sort -nr | head-5
获取 vnet1 网卡的 icmp 的包,i.e.抓 ping 命令的包
- tcpdump icmp -i vnet1
在 eth0 上抓取目的端口是 53 的 udp 包
- tcpdump -i eth0 udp dst port 53
抓取多个 host 的数据包
- tcpdump -i any host 172.19.42.202 or 172.19.42.201 -nn
从 192.168 网段到 10 或者 172.16 网段的数据报
- tcpdump -nvX src net 192.168.0.0/16 and dat net 10.0.0.0/8 or 172.16.0.0/16
抓取 LACP 包,是否有用待验证?
tcpdump -i bond1 ether host 01:80:c2:00:00:02- 注意:ether 只能在某些设备上运行,需要指定具体网络设备,不能用 any
使用 tcpdump 截取数据报文的时候,默认会打印到屏幕的默认输出,你会看到按照顺序和格式,很多的数据一行行快速闪过,根本来不及看清楚所有的内容。不过,tcpdump 提供了把截取的数据保存到文件的功能,以便后面使用其他图形工具(比如 wireshark,Snort)来分析。
-r 可以读取文件里的数据报文,显示到屏幕上。
tcpdump -nXr capture_file.pcap host web30
NOTE:保存到文件的数据不是屏幕上看到的文件信息,而是包含了额外信息的固定格式 pcap,需要特殊的软件来查看,使用 vim 或者 cat 命令会出现乱码。
从 Mars 或者 Pluto 发出的数据报,并且目的端口不是 22
tcpdump -vv src mars or pluto and not dat port 22
高级过滤
匹配 TCP 标志为 RST 的所有包。
- 意思就是数据包的包头中,tcpflags 字段的 tcp-rst 的值为 1
tcpdump 'tcp[tcpflags] & (tcp-rst) != 0' -nn
抓 HTTP 的包
抓取 HTTP 的包
tcpdump -AnnSs 70 'tcp[20:4]=0x48545450'tcp[20:4]# 由 TCP Header 可知,TCP 的首部长度为 20 字节,那么 TCP 首部后面的 4 字节通常用来标识
- 或者
tcpdump -AnnSs 70 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48545450'tcp[((tcp[12:1] & 0xf0) >> 2):4]# 首先确定我们感兴趣的字节的位置 (在 TCP 头之后),然后选择我们希望匹配的 4 个字节。TODO: 还没搞明白这个描述0x47455420# 0x 表示 16 进制,47455420 是 ASCII 中以 16 进制表示的GET这四个字符(G、E、T、空格)。
Notes: 其中 -s 选项的值设为 70 是为了避免输出过多数据信息干扰。70 长度一般足够看到请求的 PATH,如果 PATH 太长,可以适当提高 -s 的值。
抓取 HTTP 的 GET 请求的包
tcpdump -AnnSs 0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854- 这里是用了 TCP 首部后两位进行匹配,即 GE 和 HT
- 或者
tcpdump -AnnSs 0 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
抓取 HTTP 的 GET 或 POST 请求的包
tcpdump -nnAs 0 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420 or tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504F5354'
为什么要用 -Xe 选项?
tcpdump -XvvennSs 0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854
tcpdump 输出内容详解
截取数据只是第一步,第二步就是理解这些数据,下面就解释一下 tcpdump 命令输出各部分的意义。
21:27:06.995846 IP (tos 0x0, ttl 64, id 45646, offset 0, flags [DF], proto TCP (6), length 64)
192.168.1.106.56166 > 124.192.132.54.80: Flags [S], cksum 0xa730 (correct), seq 992042666, win 65535, options [mss 1460,nop,wscale 4,nop,nop,TS val 663433143 ecr 0,sackOK,eol], length 0
21:27:07.030487 IP (tos 0x0, ttl 51, id 0, offset 0, flags [DF], proto TCP (6), length 44)
124.192.132.54.80 > 192.168.1.106.56166: Flags [S.], cksum 0xedc0 (correct), seq 2147006684, ack 992042667, win 14600, options [mss 1440], length 0
21:27:07.030527 IP (tos 0x0, ttl 64, id 59119, offset 0, flags [DF], proto TCP (6), length 40)
192.168.1.106.56166 > 124.192.132.54.80: Flags [.], cksum 0x3e72 (correct), ack 2147006685, win 65535, length 0
最基本也是最重要的信息就是数据报的源地址/端口和目的地址/端口,上面的例子第一条数据报中,源地址 ip 是 192.168.1.106,源端口是 56166,目的地址是 124.192.132.54,目的端口是 80。 > 符号代表数据的方向。
此外,上面的三条数据还是 tcp 协议的三次握手过程,第一条就是 SYN 报文,这个可以通过 Flags [S] 看出。下面是常见的 TCP 报文的 Flags:
- [S] # SYN(开始连接)
- [.] # 没有 Flag
- [P] # PSH(推送数据)
- [F] # FIN (结束连接)
- [R] # RST(重置连接)
而第二条数据的 [S.] 表示 SYN-ACK,就是 SYN 报文的应答报文。
tcpdump 很详细的 http://blog.chinaunix.net/uid-11242066-id-4084382.html
http://www.cnblogs.com/ggjucheng/archive/2012/01/14/2322659.html Linux tcpdump 命令详解
Tcpdump usage examples(推荐) http://www.rationallyparanoid.com/articles/tcpdump.html
使用 TCPDUMP 抓取 HTTP 状态头信息 http://blog.sina.com.cn/s/blog_7475811f0101f6j5.html
衍生品
https://github.com/mozillazg/ptcpdump # ptcpdump 是一个使用 eBPF 技术实现的、类 tcpdump 的网络流程抓包工具。 在尽可能的情况下,以包注释的形式,为每个数据包流量关联发起方或接收方的进程信息
反馈
此页是否对你有帮助?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.
