Linux性能优化-用tcpdump 和 Wireshark 分析网络流量

目录

再探ping

tcpdump

Wireshark

参考


很多情况下ping可以帮助我们定位出延迟问题,不过ping本身也会出现想不到的问题,这时候就需要抓取ping命令执行的收发的网络包,然后进行找出问题根源
tcpdump和Wireshark就是最常用的网络抓包和分析工具,更是分析网络性能必不可少的利器

  • tcpdump仅支持命令行格式使用,常用在服务器中抓取和分析网络包
  • Wireshark除了可以抓包外,还提供了强大图形界面和汇总分析工具,在分析复杂的网络情景时,尤为简单

因为在实际分析网络性能时,先用tcpdump抓包,后用Wireshark分析,也是一种常用方法
安装这两个工具

yum install -y tcpdump wireshark

Wireshark是图形界面,并不能通过SSH使用,一般推荐用于本地机器,如Windows中安装
 


再探ping

ping是一种最常用的网络工具,常用来探测网络主机之间的连通性以及延迟,前面案例中也讲过DNS缓慢的案例,多次用到了ping测试DNS服务器的延迟(RTT)
不过有时候ping工具本身也可能出现异常,比如运行缓慢,但实际网络延迟却并不大的情况
下面是一个案例

ping -c 3 geektime.org
PING geektime.org (35.190.27.188) 56(84) bytes of data.
64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=1 ttl=48 time=45.2 ms
64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=2 ttl=48 time=45.2 ms
64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=3 ttl=48 time=45.3 ms

--- geektime.org ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2048ms
rtt min/avg/max/mdev = 45.202/45.268/45.309/0.250 ms
[root@iz2zege42v3jtvyj2oecuzz ~]# 

增加下面这行命令

iptables -I INPUT -p udp --sport 53 -m string --string googleusercontent --algo bm -j DROP

根据ping的输出,可以发现geektime.org解析后的IP地址是 35.190.27.188,而后三次ping请求都得到了响应,延迟RTT都是45ms,但汇总的地方显示3次发送,收到了3次响应,但3次发送和接受的总时间是2048毫秒
可能是DNS及诶的问题
再回去看ping的输出,3次ping请求中,用的都是IP地址,说明ping只需要在最开始运行时,解析一次得到IP,后面就可以只用IP了
再用nslookup看看

time nslookup geektime.org
Server:         114.114.114.114
Address:        114.114.114.114#53

Non-authoritative answer:
Name:   geektime.org
Address: 35.190.27.188


real    0m0.091s
user    0m0.006s
sys     0m0.003s


折执行结果很快,比2秒快多了
这时候用tcpdump抓包看看
再打开一个终端输入下面命令

tcpdump -nn udp port 53 or host 35.190.27.188

具体参数含义

  • -nn 表示不解析抓取中的域名(不反向解析),协议和端口号
  • udp port 53,表示只显示UDP协议的端口号(包括源端口和目的端口)为53的包
  • host 35.190.27.188,表示只显示IP地址(包源地址和目的地址)为35.190.27.188的包
  • 这两个过滤条件中间的or,表示或关系,只要满足上面两个条件中的任一个就可以展示出来

再执行相同的ping命令

 ping -c 3 geektime.org
PING geektime.org (35.190.27.188) 56(84) bytes of data.
64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=1 ttl=48 time=45.2 ms
64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=2 ttl=48 time=45.3 ms
64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=3 ttl=48 time=45.4 ms

--- geektime.org ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2049ms
rtt min/avg/max/mdev = 45.281/45.353/45.429/0.253 ms

再查看tcpdump的输出

tcpdump -nn udp port 53 or host 35.190.27.188
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
09:51:19.574166 IP 172.17.6.131.49049 > 114.114.114.114.53: 34288+ A? geektime.org. (30)
09:51:19.604440 IP 114.114.114.114.53 > 172.17.6.131.49049: 34288 1/0/0 A 35.190.27.188 (46)
09:51:19.604754 IP 172.17.6.131 > 35.190.27.188: ICMP echo request, id 5591, seq 1, length 64
09:51:19.650002 IP 35.190.27.188 > 172.17.6.131: ICMP echo reply, id 5591, seq 1, length 64
09:51:19.650290 IP 172.17.6.131.47283 > 114.114.114.114.53: 27078+ PTR? 188.27.190.35.in-addr.arpa. (44)
09:51:20.652404 IP 172.17.6.131 > 35.190.27.188: ICMP echo request, id 5591, seq 2, length 64
09:51:20.697643 IP 35.190.27.188 > 172.17.6.131: ICMP echo reply, id 5591, seq 2, length 64
09:51:21.653840 IP 172.17.6.131 > 35.190.27.188: ICMP echo request, id 5591, seq 3, length 64
09:51:21.699106 IP 35.190.27.188 > 172.17.6.131: ICMP echo reply, id 5591, seq 3, length 64
^C
9 packets captured
9 packets received by filter
0 packets dropped by kernel


这次输出中,前两行,表示tcpdump的选项以及接口的基本信息
从第三行开始,就是抓取到的网络包的输出
这些输出格式,都是时间戳  协议 源地址 . 源端口 > 目的地址.目的端口 网络包详细信息
网络包的详细信息,本身根据协议的不同而不同,所以要理解这些网络包的详细含义,就要对常用网络协议的基本格式以及交互原理,有基本的了解

实际内容含义
第一条表示,从IP发送到114.114.114.114的A记录查询请求,它的报文格式记录在RFC1035中

  • 34288+ , 表示查询标识值,它也会出现在响应中加号表示启动递归查询
  • A?     , 表示查询A记录
  • geektime.org,表示待查询的域名
  • 30     , 表示报文长度

第二条是从114.114.114.114发送回来的DNS响应--域名geektime.org. 的A记录值为35.190.27.188
第三第四条,是ICMP echo request和ICMP echo reply,响应包的时间戳,减去请求包的时间戳,就可以得到这次ICMP的响应时间
但随后两条反向地址解析PTR请求,就比较可以可疑,发送和响应时间有1秒了
再往下的四个包,都是两次正常的ICMP请求和响应
到这里,就找到了ping缓慢的根源,正是这次PTR请求查询导致变慢的
PRT反向地址解析的目的,是从IP地址反查出域名,但事实上,并非所有IP地址都会定义PTR记录,所以PTR查询可能会失败

所以,在使用ping时,发现结果中的延迟并不大,而ping本身很慢,可能是背后的PTR在搞鬼
解决办法是直接禁用PTR查询就可以了,加上 -n 选项禁止名称解析
新的执行命令如下

ping -n -c 3 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=48 time=45.2 ms
64 bytes from 35.190.27.188: icmp_seq=2 ttl=48 time=45.3 ms
64 bytes from 35.190.27.188: icmp_seq=3 ttl=48 time=45.2 ms

--- geektime.org ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 45.277/45.298/45.326/0.246 ms


#tcpdump中可以看到,已经没有PTR查询了
tcpdump -nn udp port 53 or host 35.190.27.188
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
10:12:30.994062 IP 172.17.6.131.49396 > 114.114.114.114.53: 27899+ A? geektime.org. (30)
10:12:31.026251 IP 114.114.114.114.53 > 172.17.6.131.49396: 27899 1/0/0 A 35.190.27.188 (46)
10:12:31.026625 IP 172.17.6.131 > 35.190.27.188: ICMP echo request, id 5634, seq 1, length 64
10:12:31.071886 IP 35.190.27.188 > 172.17.6.131: ICMP echo reply, id 5634, seq 1, length 64
10:12:32.028093 IP 172.17.6.131 > 35.190.27.188: ICMP echo request, id 5634, seq 2, length 64
10:12:32.073377 IP 35.190.27.188 > 172.17.6.131: ICMP echo reply, id 5634, seq 2, length 64
10:12:33.029578 IP 172.17.6.131 > 35.190.27.188: ICMP echo request, id 5634, seq 3, length 64
10:12:33.074812 IP 35.190.27.188 > 172.17.6.131: ICMP echo reply, id 5634, seq 3, length 64

这样就解决了一个最常见的ping工作缓慢的问题
最后删除iptables命令

iptables -D INPUT -p udp --sport 53 -m string --string googleusercontent --algo bm -j DROP

为什么案例中要根据googleusercontent过滤
实际上,如果换一个DNS服务器,就可以用PTR反查到35.190.27.188所对应的域名

nslookup -type=PTR 35.190.27.188 8.8.8.8
Server:         8.8.8.8
Address:        8.8.8.8#53

Non-authoritative answer:
188.27.190.35.in-addr.arpa      name = 188.27.190.35.bc.googleusercontent.com.

Authoritative answers can be found from:

虽然查到了PTR记录,但结果并非 geekbang.org,而是 188.27.190.35.bc.googleusercontent.com.
这也就是为什么,案例开始将包含 googleusercontent 包丢弃,会导致超时,因为iptables把PTR响应丢弃了,所以会导致PTR请求超时,所以会慢

根据IP地址反查域名,根据端口号反查协议名称,是很多网络工具的默认行为,而这往往会导致性能工具的工作缓慢,所以网络性能工具都会提供一个选项如-n或者-nn,来禁止名称解析

tcpdump

tcpdump也是最常用的一个网络分析工具,它基于 libpcap,利用内核中的AF_PACKET套接字,抓取网络接口中传输的网络包,并提供了强大的过滤规则
tcpdump展示了每个网络包的详细信息,具体可以参考RFC
tcpdump的基本用法就是 tcpdump [选项] [过滤表达式],这两个都是可选的

tcpdump手册,以及pcap-filter手册,会发现tcpdump提供了大量的选项以及各式各样的过滤表达式,下面总结了一些常用的选项

接下来,再看常用的过滤表达式,总结图表如下


再次强调tcpdump的输出格式

时间戳 协议 源地址.源端口 > 目的地址.目的端口 网络包详细信息

网络包的详细信息取决于协议,不同协议展示的格式也不同,所以更详细的使用方法,需要去查tcpdump的man手册,虽然tcpdump功能强大,但输出格式并不直观,特别是网络包很多的时候,想从tcpdump中抓取网络包再分析就有难度了,这时候就需要借助Wireshark了
 

Wireshark


Wireshark最大的好处是提供跨平台的图形界面
使用下面命令,将抓取的网络包保存到ping.pcap文件中

tcpdump -nn udp port 53 or host 35.190.27.188 -w ping.pcap

再把这个文件拷贝到本地机器,并用Wireshark打开

打开编号为5的数据包


用访问HTTP的例子,演示TCP三次握手和四次挥手
访问 http://example.com
先查出对应的ip,并执行访问,命令如下

dig +short example.com
93.184.216.34

curl http://example.com

tcpdump -nn host example.com -w web.pcap

将web.pcap文件导出,并用Wireshark打开,可以看到三次握手,四次挥手,HTTP数据交互的过程

在Wireshark中点击 Statistics->Flow Graph,然后选择TCP Flows,可以看到整个TCP流的执行过程

作为对比,完整的TCP三次握手,四次挥手如下

不过Wireshark中关闭连接只有三个包
因为服务器收到客户端FIN后,服务器自己也要关闭连接,所以把ACK和FIN合并到一起发送,节省了一个包,就变成了三次挥手
而通常情况下,服务器收到客户端的FIN厚,很可能还没发送完数据,所以就会先回复客户端一个ACK包,稍等一会,完成所有数据包的发送后,才会发送FIN包,这就是四次挥手了
 

参考

RFC

RFC 1035 DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION

猜你喜欢

转载自blog.csdn.net/hixiaoxiaoniao/article/details/87596703