天天看点

抓包工具tcpdump使用方法汇总

作者:寒笛过霜天

(1)显示TCP包信息

> # tcpdump

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

18:00:27.716975 IP 202.10.42.18.44670 > miner.2345: Flags [P.], seq 1:586, ack 1, win 502, options [nop,nop,TS val 2436134732 ecr 1616400476], length 585

18:00:27.716987 IP miner.2345 > 202.10.42.18.44670: Flags [.], ack 586, win 505, options [nop,nop,TS val 1616400476 ecr 2436134732], length 0

18:00:27.716991 IP 202.10.42.18.44672 > miner.2345: Flags [S], seq 2659122594, win 64240, options [mss 1460,sackOK,TS val 2436134732 ecr 0,nop,wscale 7], length 0

18:00:27.717002 IP miner.2345 > 202.10.42.18.44672: Flags [S.], seq 2194100875, ack 2659122595, win 65160, options [mss 1460,sackOK,TS val 1616400476 ecr 2436134732,nop,wscale 7], length 0

18:00:27.717002 IP miner.2345 > 202.10.42.18.44668: Flags [F.], seq 188, ack 586, win 505, options [nop,nop,TS val 1616400476 ecr 2436134732], length 0

18:00:27.717019 IP 202.10.42.18.44668 > miner.2345: Flags [.], ack 188, win 501, options [nop,nop,TS val 2436134732 ecr 1616400476], length 0

18:00:27.717055 IP 202.10.42.18.44668 > miner.2345: Flags [F.], seq 586, ack 189, win 501, options [nop,nop,TS val 2436134732 ecr 1616400476], length 0

......

(2)显示指定数量包

> # tcpdump -c 20

(3)精简显示

> # tcpdump -c 10 -q //精简模式显示 10个包

(4)监视指定网络接口的数据包

> # tcpdump -i eth1

(5)监视指定主机和端口的数据包

> # tcpdump tcp port 22 and host hostname

(6)对本机的udp 123端口进行监视(123为ntp的服务端口)

> # tcpdump udp port 123

(7)监视指定网络的数据包,如本机与192.168网段通信的数据包,"-c 10"表示只抓取10个包

> # tcpdump -c 10 net 192.168

tcpdump / wireshark 抓包及分析

1 抓包:打到标准输出

用下面的 tcpdump 命令抓包,另一窗口执行 wget http://example.com,能看到如下类 似的输出。为了方便后面的讨论,这里将一些字段去掉了,并做了适当的对齐:

/ # tcpdump -n -S -i eth0 host example.com

1 02:52:44.513700 IP 172.17.0.9.41038 > 93.184.216.34.80: Flags [S] , seq 3310420140, length 0

2 02:52:44.692890 IP 93.184.216.34.80 > 172.17.0.9.41038: Flags [S.], seq 1353235534, ack 3310420141, length 0

3 02:52:44.692953 IP 172.17.0.9.41038 > 93.184.216.34.80: Flags [.] , ack 1353235535, length 0

4 02:52:44.693009 IP 172.17.0.9.41038 > 93.184.216.34.80: Flags [P.], seq 3310420141:3310420215, ack 1353235535, length 74: HTTP: GET / HTTP/1.1

5 02:52:44.872266 IP 93.184.216.34.80 > 172.17.0.9.41038: Flags [.] , ack 3310420215, length 0

6 02:52:44.873342 IP 93.184.216.34.80 > 172.17.0.9.41038: Flags [.] , seq 1353235535:1353236983, ack 3310420215, length 1448: HTTP: HTTP/1.1 200 OK

7 02:52:44.873405 IP 172.17.0.9.41038 > 93.184.216.34.80: Flags [.] , ack 1353236983, length 0

8 02:52:44.874533 IP 93.184.216.34.80 > 172.17.0.9.41038: Flags [P.], seq 1353236983:1353237162, ack 3310420215, length 179: HTTP

9 02:52:44.874560 IP 172.17.0.9.41038 > 93.184.216.34.80: Flags [.] , ack 1353237162, length 0

10 02:52:44.874705 IP 172.17.0.9.41038 > 93.184.216.34.80: Flags [F.], seq 3310420215, ack 1353237162, length 0

11 02:52:45.053732 IP 93.184.216.34.80 > 172.17.0.9.41038: Flags [.] , ack 3310420216, length 0

12 02:52:45.607825 IP 93.184.216.34.80 > 172.17.0.9.41038: Flags [F.], seq 1353237162, ack 3310420216, length 0

13 02:52:45.607869 IP 172.17.0.9.41038 > 93.184.216.34.80: Flags [.] ,

参数说明:

-n:打印 IP 而不是 hostname, 打印端口号而不是协议(例如打印 80 而不是 http)

-S:打印绝对时间戳

-i eth0:指定从 eth0 网卡抓包

host example.com:抓和 example.com 通信的包(双向)

更多 tcpdump 的常用命令,可以参考tcpdump: An Incomplete Guide。

2 抓包:存文件

-w 命令可以将抓到的包写到文件, 注意这和用重定向方式将输出写到文件是不同的。后者写的只是标准输出打印的 LOG, 而 -w 写的是原始包。

3 流量分析: tcpdump

如果不指定输出的话, tcpdump 会直接将信息打到标准输出, 就是我们上面看到的那样。从 这些输出里,我们看到很多信息。

3.1 每列说明

第 1 列是为了讨论方便而加的行号,实际的 tcpdump 输出并没有这一列。接下来将用 # 号加数字表示第几个包,例如 #3 表示第 3 个包。

接下来依次为:

packet 时间戳, 例如 02:52:44.513700 表示抓到这个包的时间是** 02 时 52 分 44 秒 513 毫秒**

packet 类型, 这里是 IP 包

源 (SRC) IP 和端口, 目的 (DST) IP 和端口

packet TCP flags,其中

S 表示 syn 包

. 表示 ack 包

F 表示 fin 包

P 表示 push 包(发送正常数据)

序列号(seq)

应答号(ack)

包的 payload 长度

包的部分内容(ASCII)

3.2 三次握手(1~3)

wget 是基于 HTTP 协议, 因此它在下载文件之前, 必定要和服务端建立一个连接。

而 TCP 建立连接的过程就是著名的三次握手 [4]:

client -> server: SYN

server -> client: SYN+ACK

client -> server: ACK

我们可以看到, 这刚好对应于前三个包:

1 02:52:44.513700 IP 172.17.0.9.41038 > 93.184.216.34.80: Flags [S] , seq 3310420140, length 0

2 02:52:44.692890 IP 93.184.216.34.80 > 172.17.0.9.41038: Flags [S.], seq 1353235534, ack 3310420141, length 0

3 02:52:44.692953 IP 172.17.0.9.41038 > 93.184.216.34.80: Flags [.] , ack 1353235535, length 0

第一次握手: SYN

#1 包含以下信息:

1. 02:52:44.513700 时刻, 客户端主动向 server(93.184.216.34)发起一个 SYN 请求, 请求建立连接

2. 客户端请求的服务端端口是 80(HTTP 服务默认 80 端口), 客户端使用的是临时端口(大于 1024) 41038

3. #1 序列号是 3310420140,这是客户端的初始序列号(客户端和服务端分别维护自己的序列号, 两者没有关系;另外, 初始序列号是系统选择的, 一般不是 0)

4. #1 length 为 0, 因为 SYN 包不带 TCP payload, 所有信息都在 TCP header

第二次握手: SYN+ACK

#2 的 ack 是 3310420140, 等于 #1 的 seq 加 1, 这就说明, #2 是 #1 的应 答包。

这个应答包的特点:

1. TCP flags 为 S., 即 SYN+ACK

2. length 也是 0, 说明没有 payload

3. seq 为 1353235534, 这是服务端的初始序列号

4. 到达 eth0 的时间为 02:52:44.692890, 说明时间过了 18ms

第三次握手: ACK

同理, #3 的 ack 等于 #2 的 seq 加 1, 说明 #3 是 #2 的应答包。

这个包的特点:

1. TCP flags 为 ., 即 ACK

2. 长度为 0, 说明没有 TCP payload

至此, 三次握手完成。

3.3 正常数据传输

三次握手完成后, client 和 server 开始 HTTP 通信, 客户端通过 HTTP GET 方法下载 index.html。

4 02:52:44.693009 IP 172.17.0.9.41038 > 93.184.216.34.80: Flags [P.], seq 3310420141:3310420215, ack 1353235535, length 74: HTTP: GET / HTTP/1.1

5 02:52:44.872266 IP 93.184.216.34.80 > 172.17.0.9.41038: Flags [.] , ack 3310420215, length 0

6 02:52:44.873342 IP 93.184.216.34.80 > 172.17.0.9.41038: Flags [.] , seq 1353235535:1353236983, ack 3310420215, length 1448: HTTP: HTTP/1.1 200 OK

7 02:52:44.873405 IP 172.17.0.9.41038 > 93.184.216.34.80: Flags [.] , ack 1353236983, length 0

8 02:52:44.874533 IP 93.184.216.34.80 > 172.17.0.9.41038: Flags [P.], seq 1353236983:1353237162, ack 3310420215, length 179: HTTP

9 02:52:44.874560 IP 172.17.0.9.41038 > 93.184.216.34.80: Flags [.] , ack 1353237162, length 0

这里可以看到:

1. #4: client 向 server 发起 HTTP GET 请求, 请求路径为根路径(/), 这个 packet 长度为 74 字节

2. #5: 发送了 ACK 包,对 #4 进行确认

3. #6: 发送了 1448 字节的数据给 client

4. #7: client 对 server 的 #6 进行应答

5. #8: server 向 client 端继续发送 179 字节数据

6. #9: client 对 server 的 #8 进行应答

3.4 四次挥手

最后是四次挥手 [5]:

1. client -> server: FIN (我们看到的是 FIN+ACK, 这是因为这个 FIN 包除了正常的关闭连接功能之外, 还被用于应答 client 发过来的前一个包)

2. server -> client: ACK

3. server -> client: FIN+ACK

4. client -> server: ACK

10 02:52:44.874705 IP 172.17.0.9.41038 > 93.184.216.34.80: Flags [F.], seq 3310420215, ack 1353237162, length 0

11 02:52:45.053732 IP 93.184.216.34.80 > 172.17.0.9.41038: Flags [.] , ack 3310420216, length 0

12 02:52:45.607825 IP 93.184.216.34.80 > 172.17.0.9.41038: Flags [F.], seq 1353237162, ack 3310420216, length 0

13 02:52:45.607869 IP 172.17.0.9.41038 > 93.184.216.34.80: Flags [.] , ack 1353237163, length 0

4 流量分析: wireshark

tcpdump 可以指定 -r 读取 pcap 文件, 并以指定的格式输出包的信息, 最后输出的内容 和上面看到的类似。我们上面的流量非常简单, 所以看 tcpdump 的输出就够了。

对于复杂的 pcap, 例如, 其中包含了上百个 IP 地址、上千个端口、上万个连接的 pcap, 通过 tcpdump 看输出可能就比较低效了。

这时, wireshark 这样带图形用户界面, 且功能强大的网络流分析工具就派上了用场。

wireshark 支持强大的过滤功能,支持按 IP、端口、协议、连接、TCP flag 以及它们的各 种组合进行过滤,然后进行分析,大大节省网络排障的时间。

wireshark 官方维护了一个 sample pcap列表 ,我们拿 iperf-mptcp-0-0.pcap 作为例子来展示如何使用 wireshark。

下载地址:

https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=iperf-mptcp-0-0.pcap

5 总结

tcpdump 和 wireshark 功能非常强大, 组合起来更是网络排障的首选利器。这里介绍的内 容只是九牛一毛, 更多的时候, 你需要 tcpdump+wireshark+google。

常用命令:

> # tcpdump port 3306

继续阅读