如何在 Linux 上使用 traceroute 命令

使用 Linux traceroute 命令排查网络连接问题

您可以使用 Linux traceroute 命令来检测网络数据包在传输过程中遇到的瓶颈,并帮助您解决网络连接缓慢的问题。接下来,我们将详细介绍如何使用这个工具。

traceroute 的工作原理

理解 traceroute 的工作原理有助于您更好地解读其结果。网络数据包到达目的地需要经过的路由越复杂,就越难确定速度减慢的具体位置。例如,小型组织的 局域网 (LAN) 结构可能相对简单,通常包含至少一台服务器和几个路由器。而广域网 (WAN) 的复杂性则更高,因为它涉及不同位置之间的通信,或者通过互联网进行通信。这意味着您的网络数据包在传输过程中会遇到许多硬件设备,如路由器和网关,这些设备负责转发和路由数据。

每个数据包都包含一个元数据头部,其中描述了数据包的长度、来源、目的地以及使用的协议等信息。协议的规范定义了这些头部的结构。通过识别协议,您可以确定头部中每个字段的起始和结束位置,并读取其中的元数据。

traceroute 利用 TCP/IP 协议套件,并发送 用户数据报协议 (UDP) 数据包。数据包头部包含一个名为 生存时间 (TTL) 的字段,该字段的值为一个 8 位整数。尽管其名称暗示时间,但实际上它表示的是计数,而非持续时间。

数据包从其源地址通过路由器传输到目的地。每当数据包到达一个路由器时,TTL 计数器就会递减。如果 TTL 值降至 1,路由器会将其减 1 并发现 TTL 值变为 0。此时,数据包会被丢弃,不会转发到下一跳,因为它已“超时”。

路由器会向数据包的来源发送一条 互联网控制消息协议 (ICMP) 超时消息,通知发送方数据包已超时。此消息包含原始数据包的头部以及原始数据包数据的前 64 位。这些信息在 RFC 792 的第六页中进行了定义。

因此,当 traceroute 发送一个 TTL 值为 1 的数据包时,该数据包仅能到达第一个路由器,然后被丢弃。路由器会返回 ICMP 超时消息,traceroute 可以记录往返时间。

traceroute 随后会将 TTL 值设置为 2,重复上述过程,数据包会在两跳后超时。接着,traceroute 将 TTL 值增加到 3,再次尝试。此过程会重复进行,直到到达目的地或达到最大跳数限制(默认为 30)。

某些路由器可能存在问题

某些路由器可能存在错误,它们会尝试转发 TTL 值为零的数据包,而不是丢弃它们并发送 ICMP 超时消息。

根据 思科 的说法,一些互联网服务提供商 (ISP) 会对其路由器中继的 ICMP 消息数量进行速率限制。

有些设备被配置为从不发送 ICMP 数据包,这通常是为了防止设备在不知不觉中被卷入 分布式拒绝服务攻击,例如“蓝精灵攻击”

traceroute 的默认响应超时时间为 5 秒。如果在 5 秒内没有收到响应,则会放弃尝试。这意味着来自非常慢的路由器的响应可能会被忽略。

安装 traceroute

traceroute 在 Fedora 31 中已预先安装,但在 Manjaro 18.1 和 Ubuntu 18.04 上需要手动安装。要在 Manjaro 上安装 traceroute,请使用以下命令:

sudo pacman -Sy traceroute

要在 Ubuntu 上安装 traceroute,请使用以下命令:

sudo apt-get install traceroute

使用 traceroute

如前所述,traceroute 的目的是引发从您的计算机到目的地的每一跳的路由器的响应。有些路由器可能会保持沉默,而另一些则会提供详细的信息。

例如,我们将运行一个跟踪路由到爱尔兰 布拉尼城堡 网站,它是著名的 布拉尼之石的所在地。传说亲吻布拉尼之石会得到“口才的恩赐”。我们希望沿途遇到的路由器能够提供足够的响应。

我们输入以下命令:

traceroute www.blarneycastle.ie

第一行提供了以下信息:

目的地及其 IP 地址。
traceroute 在放弃之前尝试的最大跃点数。
我们发送的 UDP 数据包的大小。

后续行包含了有关每个跃点的信息。在深入研究细节之前,我们可以看到我们的计算机和布拉尼城堡网站之间有 11 个跃点。11 跳也表示我们已成功到达目的地。

每一跳的格式如下:

设备的名称(如果设备可以识别自身,否则为 IP 地址)。
IP 地址。
三次测试中每次的往返时间。星号表示该次测试没有响应。如果设备完全没有响应,您将看到三个星号,并且没有设备名称或 IP 地址。

让我们回顾一下我们得到的内容:

跳 1:第一个停靠点是本地网络上的 DrayTek Vigor 路由器。这是我们的 UDP 数据包离开本地网络并进入互联网的入口点。
跳 2:此设备没有响应。这可能是因为它被配置为不发送 ICMP 数据包,或者可能响应速度太慢,导致 traceroute 超时。
跳 3:设备响应了,但我们只得到了它的 IP 地址,没有设备名称。请注意,此行中有一个星号,表示我们没有收到所有三次请求的响应。这可能表明存在数据包丢失。
跳 4 和 5:更多匿名跳跃点。
跳 6:此跳提供了大量文本,因为不同的远程设备处理了我们的三个 UDP 请求中的每一个。输出了每个设备的(相当长的)名称和 IP 地址。当您遇到“拥挤”的网络时,可能会发生这种情况,该网络上有大量的硬件来处理大量的流量。此跃点位于英国最大的 ISP 之一的网络内。因此,如果同一个远程硬件处理我们所有的三个连接请求,那才是一个小奇迹。
跳 7:这是我们的 UDP 数据包离开 ISP 网络时的跳跃点。
跳 8:同样,我们只得到了 IP 地址,没有设备名称。所有的三次测试都成功返回。
跳 9 和 10:另外两个匿名跳跃点。
跳 11:我们已经到达了布拉尼城堡网站。虽然这座城堡位于爱尔兰科克,但根据IP 地址地理位置,该网站位于伦敦。

总的来说,这是一个混合的结果。有些设备提供了回应,有些回应但没有透露名称,还有一些则完全匿名。

尽管如此,我们确实到达了目的地,并且知道它有 11 个跃点,往返时间在 13.773 到 14.715 毫秒之间。

隐藏设备名称

如我们所见,设备名称有时会导致输出信息混乱。为了更方便地查看数据,您可以使用 -n(不进行映射)选项。

在我们的示例中,要实现此操作,我们需要输入以下内容:

traceroute -n blarneycastle.ie

这样可以更容易地定位可能指示瓶颈的往返时间数值。

跳 3 开始看起来有些可疑。上次它只响应了两次,而这次只响应了一次。在这种情况下,我们当然无法控制它。

但是,如果您正在调查公司的网络,那么深入调查该节点是值得的。

设置 traceroute 超时值

如果我们延长默认的超时时间(5 秒),或许会得到更多的响应。为此,我们将使用 -w(等待时间)选项将其更改为 7 秒。(请注意,这是一个浮点数。)

我们输入以下命令:

traceroute -w 7.0 blarneycastle.ie

这并没有产生太大的差异,因此响应可能确实超时了。匿名跳跃点很可能是故意保持隐私的。

设置测试次数

默认情况下,traceroute 会向每个跳跃点发送三个 UDP 数据包。我们可以使用 -q(查询次数)选项来增加或减少此值。

为了加快 traceroute 测试速度,我们输入以下内容以将我们发送的 UDP 探测数据包的数量减少到一个:

traceroute -q 1 blarneycastle.ie

这会向每个跃点发送一个探测。

设置初始 TTL 值

我们可以将初始 TTL 值设置为 1 以外的值,从而跳过一些跃点。通常,第一组测试的 TTL 值设置为 1,下一组设置为 2,以此类推。如果我们将其设置为 5,则第一个测试将尝试跳到第 5 跳,跳过第 1 到第 4 跳。

因为我们知道布拉尼城堡网站距离这台计算机有 11 个跃点,所以我们输入以下内容以直接进入第 11 个跃点:

traceroute -f 11 blarneycastle.ie

这将为我们提供一份简洁的关于与目的地连接状态的报告。

考虑周到

traceroute 是一款用于调查网络路由、检查连接速度和识别瓶颈的优秀工具。Windows 系统也有一个类似功能的 tracert 命令。

然而,您不应该使用大量的 UDP 数据包轰炸未知的设备,并且应该谨慎在脚本或无人值守作业中包含 traceroute

网络上的负载跟踪路由可能会对网络的性能产生不利影响。除非您需要立即进行修复,否则您可能希望在正常工作时间之外使用它。