traceroute 的工作原理是什么?
最近,我一直在读 Radia Perlman 的《Interconnections》(有一个很棒的名字!)。这是一本关于低级网络技术如何工作的老书,例如以太网。这本书包含了众多见解和轶事。在第236页,我发现了这个亮点
traceroute 工具是一个巧妙的黑客技巧,旨在强制路径上的每个路由器依次返回错误报告。它通过首先将 TTL 设置为 1(导致第一个路由器将错误报告发送回源地址),然后将它设置为 2(导致下一个路由器发送错误报告)等等,直到数据包到达目的地。
我以前从未考虑过 traceroute
的工作原理,通过阅读那一段,我立刻就明白了。IP 头中的 生存时间 (TTL) 字段原本是用来保存 IP 数据包有效的秒数的,在此之后它可以被丢弃。在实践中,它被用作递减的跳数计数,即每个转发数据包的路由器都将 TTL 值减一。IPv6 数据包有一个“跳数限制”头部字段,其命名更好,并服务于相同的目的。
当路由器将数据包的跳数计数值减到零时,它会向数据包中的源 IP 地址发送一个 ICMP 超时错误消息,否则它将转发数据包。
尽管现代版本的 traceroute
程序一次只发送一个数据包,但为了加快速度,它会同时发送具有不同跳数的数据包,这样程序就不必等待每个路由器响应后再发送下一个数据包。
协议重要吗?
安装在我电脑上的 traceroute
程序默认发送 UDP 数据报,但也可以配置为发送 TCP 或 ICMP 消息。所有这些都依赖于将跳数设置为小数的相同原则,并等待 ICMP 超时错误消息。
但是,某些路由器可能会通过防火墙阻止某些端口,因此使用 TCP 在端口 80、ICMP 回显请求(ping)或 UDP 在端口 53(DNS)可能比在随机未使用的端口上发送 UDP 数据报更有可能成功。
使用 Perl 进行 Traceroute
模块 Net::Traceroute::PurePerl 在 Perl 中实现了 traceroute 功能。我从 CPAN 安装了该模块,并在 Perl.com 域上使用以下单行命令运行它
$ sudo $(which perl) -MNet::Traceroute::PurePerl -wE \
'my $n=Net::Traceroute::PurePerl->new(host=>"perl.com");$n->traceroute();$n->pretty_print'
因为脚本打开了一个原始套接字,所以需要以 root 权限运行。我使用的是本地管理的 perl,所以子命令 $(which perl)
确保运行的是我的本地 perl 而不是系统 perl。这是我所得到的输出
traceroute to perl.com (207.171.7.45), 30 hops max, 40 byte packets
1 192.168.1.1 1.98 ms 2.02 ms 1.96 ms
2 * * *
3 68.173.200.108 14.25 ms 15.03 ms 15.43 ms
4 68.173.198.32 21.36 ms 16.54 ms 16.77 ms
5 107.14.19.24 21.44 ms
5 66.109.6.78 21.68 ms 10.39 ms
6 66.109.6.27 12.58 ms 15.19 ms 14.55 ms
7 66.109.5.119 16.93 ms 13.88 ms 20.49 ms
8 154.54.10.209 14.68 ms 18.87 ms 13.28 ms
9 154.54.44.217 12.37 ms
9 154.54.80.177 19.20 ms 18.18 ms
10 154.54.40.106 32.09 ms
10 154.54.40.110 14.15 ms
10 154.54.40.106 14.30 ms
11 154.54.24.222 30.80 ms
11 154.54.7.158 30.87 ms
11 154.54.24.222 33.32 ms
12 154.54.28.70 42.33 ms 44.74 ms
12 154.54.28.130 41.91 ms
13 154.54.29.222 62.53 ms
13 154.54.30.162 60.21 ms 60.57 ms
14 154.54.42.65 72.04 ms 71.75 ms
14 154.54.42.77 70.90 ms
15 154.54.45.162 81.26 ms 81.30 ms 90.29 ms
16 154.54.42.102 80.39 ms
16 154.54.25.150 82.34 ms 83.04 ms
17 38.88.197.82 83.23 ms 91.67 ms 82.39 ms
18 207.171.30.62 83.17 ms 72.52 ms 77.83 ms
第一条记录是我的无线路由器。我猜测第二条是调制解调器,它没有响应(因此有星号)。你可以看到每个响应数据包的每个路由器(技术上,接口)的 IP 地址序列。第 18 条记录是最后一跳,因为 Perl.com(207.171.7.45)位于同一个网络(207.171.0.0/18)上。
模块 Net::Traceroute::PurePerl 目前缺少 IPv6 支持,并且已经有一段时间没有更新了。文档中将 IPv6 列为待办事项,因此如果您对 traceroute 编程感兴趣,这可能是一个发送补丁的好机会。如果作者没有回复,您始终可以 fork 发行版!
标签
反馈
这篇文章有什么问题吗?请通过在GitHub上创建问题或拉取请求来帮助我们。