云网络二三事 - GNU类工具

简介: 老实说,最开始排查网络问题,接触到的命令就是ping,当时也只是对ping有一个非常粗浅的理解,知道他可以探测本地到目标的链路是否是否正常,再往后就知道了traceroute和mtr,感叹网络的大佬们真的将三层、四层协议用的是淋漓尽致,很好的利用了ICMP、IP协议的各个字段,非常巧妙的实现了“窥一斑而知全豹”的能力,下面的内容,部分可能非常老套,但我建议大家可以一并参考一下,虽然这些工具都是老生常谈了,但每次碰到疑难问题去研究他们的实现时,都可以获得新的感悟。

本章序言

老实说,最开始排查网络问题,接触到的命令就是ping,当时也只是对ping有一个非常粗浅的理解,知道他可以探测本地到目标的链路是否是否正常,再往后就知道了traceroute和mtr,感叹网络的大佬们真的将三层、四层协议用的是淋漓尽致,很好的利用了ICMP、IP协议的各个字段,非常巧妙的实现了“窥一斑而知全豹”的能力,下面的内容,部分可能非常老套,但我建议大家可以一并参考一下,虽然这些工具都是老生常谈了,但每次碰到疑难问题去研究他们的实现时,都可以获得新的感悟。

探测元老——ping

说到ping,应该是无人不知无人不晓,最简单的方式,就是ping加上目标IP,在Windows下会连续发起4次ICMP request探测,类Linux下则会发起持续的ICMP request探测,直到Ctrl+C停止。但它其实还有很多高级功能,这里列举一二。

Flood ping

默认情况下,ping的探测逻辑是这样的:发出ICMP request-接收到ICMP reply-发送下一个ICMP request,每一个ICMP request都是串行的发送的,但有时候我们希望更快速的进行探测,这个时候就需要flood ping出马了,对应的参数为-f,加上后ping程序会并发的发出ICMP request,同时在接收远端回复的ICMP reply,每发出一个ICMP request,在屏幕上打印一个点,每收到一个ICMP reply,就打印一个退格,那么就可以很直观的知道到底丢了多少包,当然,这个方式下-i、-c参数依然可以使用,特别是-c参数,指定要发多少的ICMP包。

更直观的打印探测结果

默认情况下,ping程序只会打印出收到ICMP reply信息,如果其中丢了几个包,用肉眼很难在满屏的结果中找到,这个时候就需要让ping程序更直观的打印出每个sequence number的结果,对应参数-O,如果在规定的时间内没收到回复,会打印一行no answer yet for icmp_seq=xxx,这样可以非常直观的看到具体哪个包出现了丢包。另外,在使用这个参数时,一般还会合并使用-D参数,这个参数会在每一行输出结果前加上timestamp时间戳,可以用于一些持续性的网络监控。

mtr

相较于ping,mtr会更加实用一些,他利用了IP头字段里的TTL值,结合ICMP协议完成了整条网络链路的探测。默认情况下,他会使用ICMP type 0x00和0x08的包作为探测的报文,一般使用中我都会建议用户加上-n参数,禁止反解,这样可以最直观的看到每一跳的真实IP,另外,若需要将mtr的结果提供给第三方,建议可以使用-rc参数,r代表不使用交互界面,而是在最后给出一个探测结果报告;c参数指定需要作几次探测(一般建议是至少200个包,可以配合-i参数减少包间隔来加快得到结果的时间)。

除了ICMP,mtr也可以进行TCP和UDP协议的探测,当然依然得结合ICMP和TTL的特性来探测,不过由于链路哈希的存在,这个探测的结果不太可靠(读者朋友可以思考一下为什么,下一节讲到traceroute会详细说明),一般建议还是直接使用ICMP协议进行探测。

路由跟踪Traceroute

上一讲到了mtr,但其实traceroute才是更加“历史悠久”的路由跟踪程序,从mtr的全称My TraceRoute就可以看出来了,mtr是受到traceroute的启发诞生的,虽然mtr基本可以做到traceroute的绝大多数功能,但在一些特定的环境下(比如没有安装mtr),还是得要使用traceroute来进行排查。

traceroute的默认行为

和mtr不同的是,traceroute默认使用UDP作为四层协议,下层还是依靠IP头的TTL来控制中间的节点返回ICMP差错报文,来获得中间节点的IP和延时。唯一的区别是,在达到目标节点时,若是ICMP协议,目标大概率是会回复ICMP reply;如果是UDP协议,按照RFC协议规定,系统是要回复ICMP 端口不可达的差错报文,虽然三大平台Windows/MacOS/Linux都实现了这个行为,但出于某些原因,这个包可能还是会在链路上被丢弃,导致路由跟踪的结果无法显示出最后一跳。所以建议在一般的情况下,traceroute命令可以加上-I参数,让程序使用ICMP协议来发送探测数据包。

mtr的隐藏陷阱

我曾经接触过一个case,用户反馈业务上部署的监控,会时不时的出现“丢包”问题。我们查看了公网的大盘监控,反复查阅都没有看到任何匹配的异常报警,没法子只能和客户沟通,从问题表现着手分析,直到我们发现客户使用的是mtr给出报告的方式来监控是否丢包(mtr的报告最后一行是否包含目标IP),才发现客户一不小心踩到了mtr的一个陷阱中去了。

由于mtr本身存在一个缺陷,如果链路上有多跳都禁ICMP回显,那么MTR是大概率无法到达最终IP的(尽快实际测试,ping目标IP是通的)。这个问题在Linux上尤为突出,MacOS上的mtr没有这个问题,这个时候就需要traceroute出马了,加上-q参数,指定每一跳尝试发包的次数(最大10次),然后可以得到一个近似的mtr结果,若需要更多的结果,只能是不停的执行traceroute -q 10 -w 1 -n -I x.x.x.x ,来获取更准确的路由跟踪结果。站在这个角度,大家知道为什么mtr会诞生了吧:-)

传输层的Ping工具——tcpping2

上面说了很多基于ICMP的测试工具,但真实的业务下,多数都是基于TCP来实现的,比如业务上报Connection Timeout、Connection Reset By Peer等报错,对应到传输层面,往往是和建连、关闭连接相关,这个时候ping、mtr很难作为排查工具来辅助问题分析,同时当时市面上也未有比较方便的制造TCP建连、断连流量的工具,笔者利用空闲时间,基于Python写了一个tcpping2工具,可以实现一些高级功能,详细可以参考github的工具主页[1]

基本功能

  1. 连接指定的目标和端口(可指定本地源IP和源端口)
  2. 支持以FIN和RESET方式断开连接
  3. 默认情况下和linux下的ping类似,会持续的进行连接,可以通过-c参数来制定连接的次数
  4. 可输出日志文件,方便关闭程序后查看历史连接情况
  5. 还支持一些额外的参数,如-i可以调节连接的间隔,-D可以设置延迟发送FIN或RST包

程序的基本逻辑

  1. 以给定的参数构建五元组,使用TCP去连接目标
  2. 记录连接时间,打印在标准输出上,同时记录到同名的日志文件中(若指定了-c参数)
  3. 循环执行,或者在执行COUNT(给定参数)次退出
  4. 在收到TERM或INT信号后强制结束,同时输出此次运行的统计结果

命令示例

连接指定8.8.8.8的53端口

python tcpping2.py 8.8.8.8 53

指定本地源地址和源端口10086去连接8.8.8.8的53端口

python tcpping2.py -H 30.11.212.23 -P 10086 8.8.8.8 53

指定连接10次目标地址,同时输出日志文件到当前目录下

python tcpping2.py -c 10 -l 8.8.8.8 53

以RESET断开连接

python tcpping2.py -R 8.8.8.8 53

间隔1秒进行一次探测

python tcpping2.py -i 1 8.8.8.8 53

最佳实践

这个工具适合用于那些可以稳定复现的问题现场,根据我们的问题排查经验,绝大多数场景都是客户端和服务端建连出现了问题,比如SYN丢包、SYN_ACK丢包、特定五元组丢包等等,针对上面的场景,tcpping2提供了诸如-H、-P、-L等参数,可以非常灵活的决定使用什么源端口来进行连接。特别是“特定五元组丢包”这个场景,因为丢包的五元组不可知,使用这个工具传入-L参数后,tcpping2会快速的从指定的起始源端口开始,不停地自增源端口来连接,可以快速的发现不通的五元组,随后再使用-H和-P参数来固定这个不通的五元组,持续的打问题流量,以便在链路上通过抓包、流统来缩短问题链路,定位具体的问题模块。


[1]https://github.com/huigher/tcpping2

目录
相关文章
|
2月前
|
存储 JSON 前端开发
Django集成图片验证码功能:基于django-simple-captcha实现
在Web应用开发中,验证码是防止恶意攻击、自动化脚本滥用的重要手段。本文将介绍如何使用django-simple-captcha库在Django项目中快速集成图片验证码功能,包括安装配置、核心实现代码及使用方法。
81 0
|
11月前
|
SQL 存储 算法
优化银行预计算固定查询成实时灵活查询
W银行指标查询系统用于计算和展示各类汇总指标,支持银行经营决策。因数据量庞大,系统采用预计算方式,但随着指标数量激增,预计算方式逐渐成为瓶颈。文章详细介绍了系统面临的挑战及优化方案,包括列式存储、有序归并、多线程计算等技术,最终实现了从明细数据实时计算指标的目标,显著提升了系统性能。
|
Kubernetes Cloud Native API
自动扩缩容:Kubernetes Autoscaler的神奇魔法,让你的应用在云海中遨游!
【8月更文挑战第8天】在云原生环境中,容器化与微服务架构普及的同时,应用管理复杂度也随之提升。自动扩缩容作为解决资源动态调整的关键技术,可根据负载变化自动增减资源,从而优化成本和性能。本文以Kubernetes为例,介绍其Autoscaler组件如HPA如何基于CPU使用率等指标自动调整Pod数量,并探讨如何利用自定义指标实现更灵活的自动扩缩容策略,以满足现代应用的弹性需求。
435 9
|
JSON 持续交付 数据中心
基础设施即代码(IaC)的实现途径
【8月更文挑战第18天】基础设施即代码(IaC)是现代云计算和DevOps实践中不可或缺的一部分。通过编写代码来定义和管理基础设施,可以实现自动化、可重复性、易于维护和高度可扩展的基础设施管理。通过选择合适的工具和方法,遵循最佳实践,企业可以显著提升基础设施的部署效率和管理水平。
|
机器学习/深度学习 算法 大数据
云上智能风控:重塑金融风险管理的新篇章
随着金融科技的快速发展,监管机构对金融机构的监管要求也在不断提高。云上智能风控系统需要符合相关监管政策和法规的要求
|
存储 API 数据安全/隐私保护
​邮箱收不到验证码邮件是什么原因
在互联网应用中,未收到验证码邮件常令人困扰。原因包括邮件误入垃圾箱、邮箱设置不当、发件服务器故障、地址输入错误及ISP拦截。解决策略有检查垃圾邮件、清理邮箱、修正设置、确认地址准确及更换邮箱服务。推荐使用AOKSend提升邮件送达率,其优势在于高送达率、实时监测与易集成,通过注册、获取API、配置SMTP及测试,可有效解决验证码邮件送达问题,优化用户体验。
|
Linux Windows 虚拟化
【Linux环境搭建实战手册】:打造高效开发空间的秘籍
【Linux环境搭建实战手册】:打造高效开发空间的秘籍
|
JavaScript 前端开发 API
如何利用Python的Flask框架与Vue.js创建RESTful API服务
【4月更文挑战第10天】本文介绍了如何使用Flask和Vue.js创建一个前后端分离的RESTful API服务。Flask作为后端框架,负责提供CRUD操作,与SQLite数据库交互;Vue.js作为前端框架,构建用户界面并利用axios库与后端API通信。通过示例代码,展示了Flask设置路由处理用户数据以及Vue组件如何调用API获取和操作数据。此基础结构为构建更复杂的Web应用提供了起点。
478 4
|
XML JSON API
1688商品详情API接口获取商品信息
在电商领域,商品详情页面是用户了解商品详细信息的重要途径。为了方便开发者快速获取商品信息,阿里巴巴旗下的1688平台提供了商品详情API接口。本文将介绍如何使用1688商品详情API接口获取商品信息,并通过代码示例进行详细说明。
|
机器学习/深度学习 人工智能 搜索推荐
构建未来:基于AI的移动应用开发新趋势
【4月更文挑战第13天】 在这篇文章中,我们将探讨人工智能(AI)如何正在改变移动应用开发的面貌。我们将详细讨论AI在移动应用开发中的应用,包括预测用户行为、优化用户体验、提高安全性等方面。我们还将探讨AI对移动应用开发的未来影响,包括自动化开发过程、个性化应用和AI驱动的创新。