tcpdump 也是最常用的一个网络分析工具。它基于 libpcap ,利用内核中的 AF_PACKET 套接字,抓取网络接口中传输的网络包;并提供了强大的过滤规则,帮你从大量的网络包中,挑出最想关注的信息
安装
# Ubuntu apt-get install tcpdump # CentOS yum install -y tcpdump
使用
tcpdump [选项] [过滤表达式]。 当然,选项和表达式的外面都加了中括号,表明它们都是可选的。
提示:在 Linux 工具中,如果你在文档中看到,选项放在中括号里,就说明这是一个可选选项。这时候就要留意一下,这些选项是不是有默认值。
常用选项
常用过滤
tcpdump 的输出格式
时间戳 协议 源地址.源端口 > 目的地址.目的端口 网络包详细信息
案例介绍--ping 域名
在终端1上执行命令如下:
$ ping -c3 geektime.org ... --- geektime.org ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 11095ms rtt min/avg/max/mdev = 81.473/81.572/81.757/0.130 ms
注意:最后的time 11095ms 指的是ping 命令的整个过程用时,而下面的rtt平均只有81ms 一共3个包那么只有240多ms ,所以ping 执行的过程还有其他的操作,比如PRT解析。
终端2抓包
$ tcpdump -nn udp port 53 or host 35.190.27.188
注:已经事先知道geektime.org 对应地址是 35.190.27.188所以地址去解析,-nn 既不解析源头地址和目的地址的对应的域名,也不解析他们端口对应的协议
-nn ,表示不解析抓包中的域名(即不反向解析)、协议以及端口号。
udp port 53 ,表示只显示 UDP 协议的端口号(包括源端口和目的端口)为 53 的包。
host 35.190.27.188 ,表示只显示 IP 地址(包括源地址和目的地址)为 35.190.27.188 的包。
这两个过滤条件中间的“ or ”,表示或的关系,也就是说,只要满足上面两个条件中的任一个,就可以展示出来。
ping 命令结束后查看终端2的输出
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 14:02:31.100564 IP 172.16.3.4.56669 > 114.114.114.114.53: 36909+ A? geektime.org. (30) 14:02:31.507699 IP 114.114.114.114.53 > 172.16.3.4.56669: 36909 1/0/0 A 35.190.27.188 (46) 14:02:31.508164 IP 172.16.3.4 > 35.190.27.188: ICMP echo request, id 4356, seq 1, length 64 14:02:31.539667 IP 35.190.27.188 > 172.16.3.4: ICMP echo reply, id 4356, seq 1, length 64 14:02:31.539995 IP 172.16.3.4.60254 > 114.114.114.114.53: 49932+ PTR? 188.27.190.35.in-addr.arpa. (44) 14:02:36.545104 IP 172.16.3.4.60254 > 114.114.114.114.53: 49932+ PTR? 188.27.190.35.in-addr.arpa. (44) 14:02:41.551284 IP 172.16.3.4 > 35.190.27.188: ICMP echo request, id 4356, seq 2, length 64 14:02:41.582363 IP 35.190.27.188 > 172.16.3.4: ICMP echo reply, id 4356, seq 2, length 64 14:02:42.552506 IP 172.16.3.4 > 35.190.27.188: ICMP echo request, id 4356, seq 3, length 64 14:02:42.583646 IP 35.190.27.188 > 172.16.3.4: ICMP echo reply, id 4356, seq 3, length 64
分析:
第一条从本地 IP 发送到 114.114.114.114 的 A 记录查询请求,在这个 tcpdump 的输出中:
36909+ 表示查询标识值,它也会出现在响应中,加号表示启用递归查询。
A? 表示查询 A 记录。
geektime.org. 表示待查询的域名。
30 表示报文长度。
第三条和第四条,是 ICMP echo request 和 ICMP echo reply,响应包的时间戳 14:02:31.539667,减去请求包的时间戳 14:02:31.508164 ,就可以得到,这次 ICMP 所用时间为 30ms。
随后的两条反向地址解析 PTR 请求,就比较可疑了。因为我们只看到了请求包,却没有应答包。仔细观察它们的时间,你会发现,这两条记录都是发出后 5s 才出现下一个网络包,两条 PTR 记录就消耗了 10s。
再往下看,最后的四个包,则是两次正常的 ICMP 请求和响应,根据时间戳计算其延迟,也是 30ms。
关于PTR
PTR 反向地址解析的目的,是从 IP 地址反查出域名,但事实上,并非所有 IP 地址都会定义 PTR 记录,所以 PTR 查询很可能会失败。所以,在你使用 ping 时,如果发现结果中的延迟并不大,而 ping 命令本身却很慢,不要慌,有可能是背后的 PTR 在搞鬼。
知道问题后,解决起来就比较简单了,只要禁止 PTR 就可以
$ ping -n -c3 geektime.org PING geektime.org (35.190.27.188) 56(84) bytes of data. 64 bytes from 35.190.27.188: icmp_seq=1 ttl=43 time=33.5 ms 64 bytes from 35.190.27.188: icmp_seq=2 ttl=43 time=39.0 ms 64 bytes from 35.190.27.188: icmp_seq=3 ttl=43 time=32.8 ms --- geektime.org ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 32.879/35.160/39.030/2.755 ms
你可以发现,现在只需要 2s 就可以结束,比刚才的 11s 可是快多了。