网络连接情况的调试思路:从实践中理解ICMP协议

本文介绍了在网络连接出现问题时的调试思路,重点讲解了ICMP协议,以及如何使用ping和traceroute进行排查。通过理解ping的工作原理,分析了ping不通的可能原因,并探讨了traceroute在定位网络问题中的作用。同时,文章指出,即使ping和traceroute不通,也不能断定两台机器完全不可达,因为特定的iptables规则可能阻止了这些连接,但其他协议和端口可能仍能通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ABSTRACT:

网络连接问题在后台开发中最常见的问题之一。本文总结了定位网络连接问题的思路及常用工具 ping和traceroute(traceroute是Linux命令,在windows中是tracert),并从ICMP网络协议的角度来解释 ping和traceroute的实现原理。假如学有余力的读者,还可以看看扩展部分,一起来钻一下牛角尖:“机器通不通”这个描述到底准不准确?


阅读本文大概需要15min。

0. 问题描述

在一个比较大的网络中,如果两台机器不通,你知道应该用什么方式调试吗?
比如,两台机器均以开机,并且都连接上了网络,但是一台机器调用另一台机器的服务时,发现出现了较大的时延, 我们第一反应是,机器A与机器B不通?那么,我们应该如何排查问题呢?

1. 背景知识:ICMP协议

ICMP全称Internet Control Message Protocol,就是互联网控制协议。
ICMP是封装在IP包里面的。
在这里插入图片描述
在这里插入图片描述
ICMP报文有很多类型,不同的类型有不同的Message type。最常用的类型如下:
在这里插入图片描述

2. 排查思路

Created with Raphaël 2.2.0 开始 local host 与remote host之间网络连接时延较长 ping remote host的ip地址 ping请求是否超时? traceroute remote host的ip地址 根据traceroute 的结果定位问题 结束 yes no

为方便演示,我先采用处于不同局域网的两台机器为例进行讲解。
假设local host的IP地址为219.223.192.155,remote host的IP地址为219.223.220.20。
目前,两台机器均已经开机并且连上网。

2.1 ping

「ping」是用来探测两台机器是否可达的命令,是确认网络连接情况最常用的命令。

现在,local host来ping remote host:
在这里插入图片描述
可以看到,local host能够ping通remote host,说明两台机器是可达的。


那么,ping不通的话,local host会收不到任何response:
在这里插入图片描述

图中虽然显示了google的“IP地址”,但是这个IP地址可能是国内ISP DNS解析出来的一个虚拟IP地址。(GFW拦截原理概析

ping不通可能是由以下原因导致的:

  1. 网络本身存在物理因素故障。比如,本地DNS故障,路由器故障。
  2. 该ip地址/域名可能不正确或无法使用。比如,GFW会为一些网站解析成一个虚拟的IP地址
  3. 路由表有问题
  4. ping请求被防火墙阻止。比如,通过iptables drop掉所有的ICMP request

所以,ping不通remote host,但是remote host仍然有可能正常工作。


ping实现原理

ping 是基于 ICMP 协议工作的,利用了ICMP中的查询报文,即,主动请求Echo request(Message Type = 8),主动请求的应答Echo reply(Message Type = 0)


那么,ping的过程如下:

  1. ping 命令执行的时候,源主机首先会构建 ICMP 请求数据包,ICMP 数据包内包含多个字段。最重要的是两个,第一个是类型字段(Message type),对于请求数据包而言该字段为 8;另外一个是顺序号(Seq.num),主要用于区分连续 ping 的时候发出的多个数据包。每发出一个请求数据包,顺序号会自动加 1。为了能够计算往返时间 RTT,它会在报文的数据部分插入发送时间。
  2. ICMP协议把这个数据包交给IP层构建一个IP数据包,MAC再把这个IP数据包加入MAC头构建一个数据帧,传送给目的主机。
  3. 当目的主机收到了这个数据帧,会构建一个ICMP应答包,应答数据包的类型字段为0,顺序号为接收到的请求数据包中的顺序号,然后再发送出去给主机 A。
  4. 在规定的时候间内,源主机如果没有接到 ICMP 的应答包,则说明目标主机不可达;如果接收到了 ICMP 应答包,则说明目标主机可达。此时,源主机会检查,用当前时刻减去该数据包最初从源主机上发出的时刻,就是 ICMP 数据包的时间延迟。

了解了ping的实现原理,那么想要阻止ping请求,只需要让源主机没有收到ICMP应答包即可。 可以通过添加很简单的 [iptables规则](https://wangchujiang.com/linux-command/c/iptables.html):
  • iptables -I INPUT -p ICMP --icmp-type 8 -j DROP 收到主动请求的ICMP包就Drop掉
  • iptables -I OUTPUT -p ICMP --icmp-type 0 -j DROP 将所有要发送出去的主动请求的应答包Drop掉

以上两条规则有一即可。

2.2 traceroute

「traceroute」能够提供两台主机的网络连接的详细信息,能够比ping提供更多的信息。traceroute能够显示有关数据包从local host到remote host的每一“跳”的信息。因此,traceroute命令常常用于定位网络连接问题和查明网络瓶颈。


现在local host开始ping remote host:
在这里插入图片描述

记录按序列号从1开始,每个纪录就是一跳 ,每跳表示一个网关,我们看到每行有三个时间,单位是ms,其实就是-q的默认参数。探测数据包向每个网关发送三个数据包后,网关响应后返回的时间;如果用traceroute -q 4 www.58.com,表示向每个网关发送4个数据包,此时每行就会显示4个时间。
在这里插入图片描述

其中 !X指明网络不可达的原因“communication administratively prohibited”,意指该机器由于内部设定的转发规则,无法转发该数据包。

「traceroute」命令默认使用UDP协议的,当然也可以使用ICMP协议(-I)和TCP协议(-T)
在这里插入图片描述
在这里插入图片描述
星号“*”表示收不到任何的返回数据,也就没有办法计算响应返回时间。此外,每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一样,但基本上来说大部分时候所走的路由是相同的。

所以,traceroute通过追踪数据包所经过的网关,定位问题是主机问题还是网关问题。

traceroute的实现

traceroute命令默认使用UDP协议的,并且利用了ICMP的差错报文(Message Type=3,目的地不可达;Message Type=11,TTL超时)。在基于UDP的实现中,客户端发送的数据包是通过UDP协议来传输的,使用了一个大于30000的端口号,服务器在收到这个数据包的时候会返回一个端口不可达的ICMP错误信息(Message Type=3),客户端通过判断收到的错误信息是TTL超时还是端口不可达来判断数据包是否到达目标主机,具体的流程如图:
在这里插入图片描述

  1. 客户端发送一个TTL为1,端口号大于30000的UDP数据包,到达第一站路由器之后TTL被减去1,返回了一个超时的ICMP数据包,客户端得到第一跳路由器的地址。
  2. 客户端发送一个TTL为2的数据包,在第二跳的路由器节点处超时,得到第二跳路由器的地址。
  3. 客户端发送一个TTL为3的数据包,数据包成功到达目标主机,返回一个端口不可达错误,traceroute结束。

那么,想要阻止remote host阻止基于UDP的traceroute,只要让源没有收到ICMP的端口不可达的错误类型报文即可:

  • iptables -I OUTPUT -p ICMP --icmp-type 3 -j DROP


    traceroute命令当然也可以使用ICMP协议。此时,源主机会直接向目的主机发送ICMP echo request数据包,服务器收到这个请求之后会返回一个echo reply数据包。路由器/网关返回给源主机依然是TTL超时的ICMP差错报文(Message Type=11)。

那么想要阻止基于ICMP的traceroute请求,只需要让源主机没有收到ICMP应答包即可。 可以通过添加很简单的 iptables规则

  • iptables -I INPUT -p ICMP --icmp-type 8 -j DROP 收到主动请求的ICMP包就Drop掉
  • iptables -I OUTPUT -p ICMP --icmp-type 0 -j DROP 将所有要发送出去的主动请求的应答包Drop掉即可。

以上两条规则有一即可。traceroute使用ICMP协议时的原理跟ping相同,故通过iptables阻止基于ICMP协议的traceroute命令的过滤规则也是相同的。使用了这类型规则后,也会让目的主机ping不通。

3. 扩展

ping/traceroute不通,是不是就能够说明两台机器之间不可达了呢?其实不一定。

通过第2章的实践,可以发现,目的主机通过iptables设定专门禁止ping/trace的过滤规则,使其他机器ping/traceroute不通这台主机。假如iptables没有禁止ssh服务,那么,你依然可以通过ssh连接上这台机器。

这时候,直接得出目的主机“不通”的判断就太简单粗暴了。

一次网络连接,往往需要关心这样的一个5元组:<local_ip,local_port, remote_ip,remote_port, protocol>,五元组里任何一个元素变了,这个连接就无法建立,无法通信。这5个元素也是我们研究网络层/传输层的最关心的元素。

所以,只要找到目的主机对外开放的端口和协议,并且源主机IP地址在目的主机开放的白名单了,那么源主机是可以跟目的主机通信的。


然而,我们常常说的两台机器通不通并没有关注地那么细。 假如机器A通过ping/traceroute均不可到达机器B,那么可以断定从机器A到机器B的通讯路径中的某个节点设置了一定的访问限制,也就是我们常说的“不通”。

参考文献

【ICMP与ping,traceroute相关的协议知识】
【traceroute用法】
【traceroute的原理解析】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值