@gaoxiaoyunwei2017
2020-10-13T16:13:22.000000Z
字数 5196
阅读 797
未分类
说明:本文根据高效运维最新一期线上小课堂整理而成。
作者简介
宋广明,高效运维社区资深 DevOps 专家,从事运维工作多年,熟悉 Linux 系统管理、公有云、产品运维、监控、持续交付等相关工作。
今天跟大家分享一些 Tcpdump 的应用案例。通过 Tcpdump 学习网络协议,验证一些配置,还有解决一些实际问题。
首先我们先看一下安装和用法,安装在 Linux 下是非常简单的,可以通过 yum、dnf、apt-get 去安装,这个很简单,不做过多介绍。
以下是它的基本用法,
第一是基于IP抓包,就是基于源IP又是基于目标IP抓包;第二个是基于源IP抓包,第三是基于目标IP抓包,第四个是基于网段抓包,第五个是基于端口范围抓包,第六个是基于源地址和目标端口抓包,第七个是基于某种协议抓包,这里有抓 FTP 相关的数据包。
这个是找到明文密码,这是一个命令的组合,Tcpdump 去抓 HTTP、FTP、SMTP,通过管道输出传给egrep
,egrep 去查关键字,然后就能得到密码了。所以明文传输没有加密是很不安全的。
tcpdump -nn -v -i eth1 -s 0 port 443
这个命令就是抓 HTTPS 的包,默认情况下如果没有改的话就是 443,我们一般情况下可以通过命令去验证我们的传输是不是加密了。举个例子,比如说内部系统跟 LDAP 集成了,前端有 LB,这样加密是分成三段,第一段是从客户端到 LB,第二段是从 LB 到后台的 real server,第三段是从 real server 到 LDAP server 这段也要加密。
一般情况下,假如从客户端到 LB 没有加密,那么就在浏览器端我们看到比如说这个链接是不安全的,但是如果是 LB 客户端做了加密,但是 real server 到 LB 这段没有加密,那其实这个密码还是可以抓到的,所以说 HTTPS 加密过程要是全链路的,有任何一段没有加密就可能被抓过来,这个大家有兴趣可以自己去试一下。
我记得当时那个应用有个字段叫[00:04:04],字段后面存的是明文密码,如果你用 HTTPS 加密的话,那段数据就显示全部都是 TLS、VER,VR 都是加密过的数据,这个看不到密码的。
通过 tcpdump 找到对应的交换机端口
Tcpdump -nn -v -i eth1 -s 1500 -c 1 'ether[20:2] == 0x2000'
这块是通过 Tcpdump 找到对应交换机的端口,这个命令我认为是一个非常实用的命令,因为有一些情况我们总要找到服务器对应交换机哪个端口,一种方法是可以请网络管理员上交换机上查一下,另外就是我们自己去机房顺着网线一直找到交换机对应的端口。
这两种方法尤其是第二种都很麻烦,如果我们有了这个命令,这个信息可以输出你当前所连交换机的名字,还有连接交换机的端口,这些信息都有,这些我就列出来了,我觉得这个命令还是比较实用的。
更多的用法我们可以参考Man Tcpdump
就可以了,这里面有更多的介绍。
下面介绍一下应用场景。第一个问题解决 DNS 问题,背景是,当时办公室用 MAC 笔记本的同事配置了两个DNS ,突然有一天说,解析域名出现错误了,然后错误提示:
Got recursion not available from 192.168.0.100, try next server
就是说这个不能查询了,这个时候我们通过 Tcpdump 抓包就可以去找到这个问题是什么原因。
下面是它的命令,这个命令很简单,抓 53 端口就可以了。
tcpdump -i en0 -vvv -s0 port 53
最后一轮我们发现,因为 dns server A 可以正常解析,dns server B 不能提供解析。
dns B 不提供办公室的递归查询,仅仅返回了该域名的 NS 记录,也就是迭代查询。解决办法就是将该办公室的 IP 网段加入到 dns B 的递归查询白名单里面,然后把 DNS reload,问题就解决了。
其实现在看这个问题其实很简单,尤其对于 DNS 特别熟的人,可能一下就知道是什么问题,不用抓包去解决,但是可能当时还不是那么熟悉,所以说也是印象比较深刻,总结了三点。
第一、这个问题出现了是因为IT管理员改了本地办公室客户端 DNS 信息。他改了这个信息导致用户端解析出现问题。
第二、DNS 支持两种查询:递归和迭代。默认所有的都支持迭代,递归默认都是不支持的。
第三、mac 系统它的 dns 跟 Linux 不太一样,它采用的是负载均衡的方式。 Linux 如果配了两个DNS的话,把请求转到第一个 nameserver,如果第一个 nameserver 不响应超时了,那么才把请求转到下面那个nameserver,然后 mac 不是,是采用负载均衡的这种方式。
第二问题解决 DB 连接的问题。背景是生产服务器 Mysql Slave 定时会生成一些文件,然后通过 rsync 把生成文件拷贝到其他应用服务器上面,rsync,因为它是 Mysql Slave,所以通过还提供了只读的服务,也是突然之间就发现某天 Mysql Slave 连接超时了,之前是没有的,这种情况有监控看监控,然后顺带抓包看看,这个其实也是抓3306 的包,跟前面有点类似。
故障现象,当 rsync 拷贝数据到其他机器的时候,带宽就满了,然后连接就超时了。
初步得到结论,rsync 拷贝数据到其他机器的时候,带宽满了,因为带宽被占满,导致 Mysql 连接超时。初步解决办法增加服务器带宽。
但是这个问题不是跟想的那么简单,因为服务器数量没有变,rsync 拷贝命令也没有变,文件大小也没有变,所以说什么都没有变,关键是之前是一直可以正常工作的。还有一个问题,之前带宽也是满的,那Mysql也没有超时,所以很显然不是问题的根本原因。
所以只能继续查找问题,说实话这个问题也不太好找,现象就是带宽满的时候数据库连接会超时,带宽不满的时候连接不超时,这就是现象。所以说很容易让人想到它跟带宽满有关系。但是不好解释的是之前带宽满它就没有超时,所以说想来想去可能跟 Linux QOS 有一定关系。
继续找了一个问题发现,我们通过 Tcpdump 抓包还是有些发现,我们发现 rsync 的tos值和默认值不一样,我们发现因为rsync的QOS比Mysql的高了,所以造成Mysql的流量需要一直等待,等待rsync完成了才轮到Mysql这边流量被系统处理。
所以说这个问题找到了,首先rsync的优先级不一样,是因为sshd的配置文件被改了,导致SSh的应用tos优先级变高了。因为rsync是用ssh这种方式传输的,所以说ssh的tos变高了,相当于 rsync 的 tos 也变高了。
Linux QOS 默认的策略就是先处理高优先级的任务,低优先级的必须等待高优先级处理完成才会被处理。这个时候就很好解释了,之前为什么带宽满了可以正常工作,那后来带宽满了就不能工作了,其实之前它们优先级都是一样的,不用等,Mysql 不用等,后来优先级 rsync 变高了,所以 Mysql 必须要等。
关于 Linux 高级路由和流量控制这块,咱们可以参考一下官方上大家可以搜索 Linux 的高级路由和流量控制这块就可以了。
所以说这个问题,当你解决这个问题你发现这个问题其实很好解决,很简单,但是你当时没有解决的时候发现很不好找,所以我在总结一下这个问题,就是因为ssh配置被改了,导致ssh的tos值变高了,优先级变高了,Linux的QOS策略先处理的rsync的流量,然后再处理了 Mysql 的流量。
那解决办法就是通过我们和相关修改sshd的配置文件团队成员,问一下原因,后来他把配置文件还原了,这个问题就彻底解决了,也没有加带宽,也用也都恢复正常了,这个是第二个分享。
第三个分享,也是应用连接超时的问题,就是生产环境某应用服务一直稳定运行。突然某天开始不定时超时错误,开始不定时的,log 里面也没有相关的日志,因为为了查这个问题还特意发了一版,把 debug 日志打开了,最后也没有发现有价值的线索,后来我们用了 Tcpdump 的抓包分析问题。
这个问题其实就比较好找了,因为我们当时抓包的时候发现,有好多大量的 tcp retransmission 这样的连接,你点开进去发现对应都是统一的IP和端口,因为这个有些问题我没有办法重现,所以没有办法截图,这个 tcp retransmission 链接,如果把抓包的结果存到本地分析的时候都是黑的,所以很明显快速过一下就知道这种连接tcp retransmission 全部都是黑的,很明显你能够看见的。然后发现同一个IP和端口,这个时候就怀疑是不是网络有问题,然后这个时候我们把问题反馈给网络组,网络组的同事找了半天最后终于在日志里面找到了,后来找到问题根本原因,是因为防火墙他们更新了,更新的防火墙有设置把 tcp 断连接掉了,所以说这个就是这个问题的根本原因。
对这个问题的总结,因为应用是使用的是长连接连的DB数据库,然后因为网络部门更新了防火墙策略,然后里面有一条策略是把空闲时间超过1小时的 tcp 连接关掉,应用端是按需连接DB的,并不清楚连接池里面的连接是不能用的,因为它是长连接,认为这个连接是一直可以用的,所以说每次连DB的时候,还是这个tcp连接,这就是为什么时不时就报错了。如果是一个新的连接,如果在一个小时之内保持激活,这个时候就不会出现这个问题了,所以说这个问题相对于前面第二个问题其实还是比较好发现的,用这个抓包工具确实能够提供一些有价值的线索,因为有些时候你怀疑是这个问题,但是你没有明显的证据的话,也不太好找,可能我这边没有什么改动,我这边很正常,什么都没有改,那你可能把这个问题提供给对方之后,可能更能够加速这个问题被解决了,咱们还是想把这个问题快点解决了,因为毕竟这个是生产环境,所以说这个场景比上一个场景简单,但是这个场景给我们提供了比较有利的证据,比较有说服力的证据,而且确实能够快速帮我们定位问题和解决问题的。
还有一个分享就是会议掉线。这个背景我介绍一下,有一个会议系统分了手机端、固定电话端和IP电话端入会,IP电话端就是用IP,然后入会的接入场景是语音的网段系统是一个集群系统。
这个现象在入会时,IP端是不会掉线的,手机端或是固定电话端通话一分钟左右就会掉线,这个问题也是我们能够找log的时候就找log,如果没有找log实在没有办法的情况下,只能是通过抓log。
tcpdump -i eth1 -t -n -s 0 port 5060
这个也是抓 5060 的包,这个也是通过端口来开包。
这个问题其实有一个区别,IP电话端入会是直接访问接入层,手机端还有固定电话端是通过语音转了一下,然后到开源接入层,语音的集群负载均衡。
我们一开始提示找这个问题的时候,抓包的时候也没有发现什么问题,因为这个包抓完说实话也挺长的,也不太好找这个问题,但是没有办法有问题就要尝试多方面尝试解决,然后最后发现,我们想的办法手机端还有IP电话端分别同时抓包,然后对比分析,一个个分析,发现语音网关语音集群系统负载均衡向语音网关发了一条消息之后,这个连接就断了,是因为语音网关设备不识别这个信息,所以说最后就掉线了。
最后解决办法,我们在配置文件里面把这个信息给strip掉了之后,这个问题就得到解决了。
这个问题其实我总结了一下,正常情况下两边都是一样的,都不会掉线,那不同的地方电话端入会经过一个语音网关的设备,然后语音网关的请求转到集群负载均衡设置上,这是唯一的不同,然后语音网关设置是一个硬件的设置,然后集群负载均衡是因为开源,问题就是开源负载均衡设备给语音网关发了一条消息,识别,最终掉线,这个就是问题的原因。这是它的解决办法,把信息给去掉,在配置文件当中关键字就strip就可以了。
最后我想总结一下,其实 Tcpdump,有时候我们解决问题的途径还是通过应用日志,如果说 log 不能帮我们解决问题,我们可以尝试用 Tcpdump 抓包去分析一下,Tcpdump 有时候可以帮助我们找到解决问题的线索。我前面分享4个场景其实都是 Tcpdump 给我们提供的线索,根据这些线索我们可以分析问题,找到问题的原因,解决问题。
Tcpdump 还是有助于我们巩固学习到的知识,比如说 HTTPS 会话建立其实有好多步骤,如果我们自己抓包去分析,可能更直接一些。还有刚才 DNS 的问题,我自己感受来说我看书的时候说了一句,所有 DNS 都支持迭代查询,我当时不是特别理解,后来我才明白通过抓包才明白,通过抓包明白确实都支持迭代查询。
还有一个 Tcpdump 有的时候可以帮我们验证一些配置,前面说的 HTTPS,我们自己配之后可以抓包试一下,然后可以验证一下,加密之前我们可以抓到密码,加密之后密码就看不见,因为是被加密了。
这是我分享的就结束了,希望能给大家带来一些解决问题的思路,然后咱们也可以一起交流,一起学习,那我今天的分享就到这了,谢谢大家!