traceroute,现代 Linux 系统上的 tracepath,还有Windows 系统上的 tracert,均是用于同一目的的网络调试工具。它们用于显示数据包在IP网络中经过的路由器的IP地址。
原理
这些程序是利用IP数据包的存活时间(TTL)值来实现其功能的。当一台计算机发送IP数据包时,会为数据包设置存活时间(TTL)值。每当数据包经过一个路由器,其存活时间值就会减 1。当存活时间减到 0 时,路由器将不再转发数据包,而是发送一个 ICMP TTL 数据包给最初发出数据包的计算机。
Traceroute 程序首先向目标主机发出 TTL 为 1 的数据包,发送数据包的计算机与目标主机之间的路径中的第一个路由器,在转发数据包时将数据包的 TTL 减 1,它发现 TTL 被减为了 0,于是向最初发出数据包的计算机发送一个 ICMP TTL 数据包,Traceroute 程序以此获得了与目标主机之间的路径上的第一个路由器的IP地址。后面 traceroute 程序依次向目标主机发送 TTL 为 2、3、4 . . . 的数据包,逐个探测出来与目标主机之间的路径上每一个路由器的 IP 地址。
实现
默认条件下,traceroute 首先发出 TTL = 1 的UDP 数据包,第一个路由器将 TTL 减 1 得 0 后就不再继续转发此数据包,而是返回一个 ICMP 超时报文,traceroute 从超时报文中即可提取出数据包所经过的第一个网关的 IP 地址。然后又发送了一个 TTL = 2 的 UDP 数据包,由此可获得第二个网关的 IP 地址。依次递增 TTL 便获得了沿途所有网关的 IP 地址。
需要注意的是,并不是所有网关都会如实返回 ICMP 超时报文。处于安全性考虑,大多数防火墙以及启用了防火墙功能的路由器缺省配置为不返回各种 ICMP 报文,其余路由器或交换机也可能被管理员主动修改配置变为不返回 ICMP 报文。因此 Traceroute 程序不一定能拿到所有的沿途网关地址。所以,当某个 TTL 值的数据包得不到响应时,并不能停止这一追踪过程,程序仍然会把 TTL 递增而发出下一个数据包。这个过程将一直持续到数据包发送到目标主机,或者达到默认或用参数指定的追踪限制(maximum_hops)才结束追踪。
依据上述原理,利用了 UDP 数据包的 Traceroute 程序在数据包到达真正的目的主机时,就可能因为该主机没有提供 UDP 服务而简单将数据包抛弃,并不返回任何信息。为了解决这个问题,Traceroute 故意使用了一个大于 30000 的端口号,因 UDP 协议规定端口号必须小于 30000 ,所以目标主机收到数据包后唯一能做的事就是返回一个 “端口不可达” 的 ICMP 报文,于是主叫方就将端口不可达报文当作跟踪结束的标志。
Wireshark 抓包分析
我们通过 Wireshark 抓包来看一下这个过程。我们追踪从我们的 PC 机到 www.163.com
之间的网络路径。打开 Wireshark,以如图所示的选项开始抓包:
然后我们在命令行执行 traceroute
程序:
这个过程中我们总共抓到了 67 个数据包。
我们选中第 1 号包,也就是用于探测路径中第一个网关的 UDP 包,在下方的数据包详情中,可以看到 Time to live
值为 1。我们再选中用于探测路径中第二个网关的 UDP 包,即第 5 号包,可以看到 Time to live
值为 2:
同时还能看到数据包发送的源端口为 UDP 34341
,目的端口为 33438
。
第 17 ~ 29 号包为中间路由节点发送回来的 TTL 超时 ICMP包。数据包被发送到目标主机时,目标主机将发回目标不可达的 ICMP 包,如下图:
第 62 ~ 64 号包即为目标主机发回的数据包。
UDP 之外的选择
使用 UDP 的 traceroute,失败还是比较常见的。这常常是由于,在运营商的路由器上,UDP 与 ICMP 的待遇大不相同。为了利于 troubleshooting,ICMP ECHO Request/Reply 是不会封的,而 UDP 则不同。UDP 常被用来做网络攻击,因为 UDP 无需连接,因而没有任何状态约束它,比较方便攻击者伪造源 IP、伪造目的端口发送任意多的 UDP 包,长度自定义。所以运营商为安全考虑,对于 UDP 端口常常采用白名单 ACL,就是只有 ACL 允许的端口才可以通过,没有明确允许的则统统丢弃。比如允许 DNS/DHCP/SNMP 等。
UNIX/Linux 下的 traceroute 还提供了如下的选项:
除了 UDP 之外,我们还可以用 TCP 或 ICMP 来探测网络路径。
Traceroute 使用 TCP 探测网络路径的原理是,不断发出 TTL 逐渐增大的 TCP [SYN] 包,在收到目标主机发回的 TCP [SYN ACK] 或达到默认或设置的追踪限制(maximum_hops)时结束追踪。我们用这种方法来探测到 www.qq.com
的网络路径。适当修改 Wireshark 的抓包选项,并在命令行中执行:
我们将抓到如下的网络数据包:
首先是一堆的 TCP [SYN] 包,然后是中间网关返回的 ICMP TTL 超时。最后收到目标主机发回的 TCP [SYN ACK] 结束整个探测过程:
如图中的第 82 和 第 84 号 TCP [SYN ACK] 包。从第 71 号包,可以看到,数据包都被发向了目标主机的 80 端口。
如果我们以 -I
参数启动 traceroute
,用 ICMP 来探测网络路径的话,抓到的包将如下面这样:
这个过程将不断发送 TTL 递增的 ICMP ECHO Request (Ping) 的包,中间网关在发现数据包的 TTL 减到 0 时,向源主机发回 ICMP TTL 超时。
整个过程以收到 ICMP Echo reply结束:
如图中的第 87 ~ 93 号包。
总结一下,traceroute 主要利用 IP 数据包的 TTL 字段值 + ICMP 来实现,它发送的用于探测网络路径的数据包的 IP 之上的协议可以是 UDP、TCP或ICMP。不同模式下,探测过程中设计的数据包如下:
UDP 模式
UDP 探测数据包(目标端口大于 30000) + 中间网关发回 ICMP TTL 超时数据包 + 目标主机发回 ICMP Destination Unreachable 数据包
TCP 模式
TCP [SYN] 探测数据包(目标端口为 Web 服务的 80) + 中间网关发回 ICMP TTL 超时数据包 + 目标主机发回 TCP [SYN ACK] 数据包
ICMP 模式
ICMP Echo (ping) Request 探测数据包 + 中间网关发回 ICMP TTL 超时数据包 + 目标主机发回 ICMP Echo (ping) reply 数据包
参考文档
使用tracert命令时,在一个节点后所有的节点都没有数据,这是为什么?
联通的网络, traceroute 显示全是星号, tracert 什么都不显示,怎样才能跟踪路由?
traceroute显示星号,但是wireshark抓包显示返回了icmp type 11
traceroute 全返回*,我的网络是怎么了?
USG6680 V5R1C00 tracert 显示星号解决方法
traceroute 命令