traceroute 使用指南

nettools · 逐跳路径探测工具(ICMP/UDP/TCP)

Usage Guide — 并发探测多个 TTL 与多个目标,输出每跳 RTT 与丢包率;报文编解码全部基于 goscapy。

← 返回首页

目录

1. 概述

Probe ICMP/UDP/TCP Concurrent traceroute 是面向 IPv4 的逐跳路径探测工具,用于定位丢包/高时延发生在哪一跳、确认 ECMP 多路径下的实际转发路径。它支持 ICMP EchoUDPTCP SYN 三种探针,并发探测多个 TTL 与多个目标,无需服务端部署。

所有探测报文的构造与解析全部通过 smallnest/goscapy 完成,不存在手写的字节序或校验和逻辑。运行需要 raw socket,即 root / CAP_NET_RAW 权限。

2. 工作原理

traceroute 利用 IP 报文的 TTL(生存时间)字段:每经过一个路由器,TTL 减 1;当 TTL 减到 0 时,该路由器会丢弃报文并回送一个 ICMP Time Exceeded(类型 11)报文,其源 IP 就是这一跳的地址。

注意:ICMP 错误报文会引用原始探测包的 IP 头 + 前 8 字节负载。traceroute 用 goscapy 解析这段被引用的内层报文(内层目的 IP、ICMP id/seq、UDP/TCP 端口)来确认归属,并发时不会串包。

3. 三种探测协议

协议探针到达目标的判定适用场景
icmp(默认)ICMP Echo Request,id=pid、seq 编码 ttl/probe收到目标的 ICMP Echo Reply最通用
udpUDP,目的端口随 TTL 递增(默认 33434 起)收到目标的 ICMP Port Unreachable传统 traceroute 行为,穿透性好
tcpTCP SYN,固定目的端口(默认 80/443)收到目标的 SYN-ACK 或 RST穿越只放行特定 TCP 端口的防火墙

三者共用同一套「TTL 递增 + ICMP Time Exceeded 收集 + 多探针采样 + 逐跳统计」框架,仅探针发送与目标到达判定不同,用 --protocol 切换。

UDP/TCP 源目端口与源目 IP:UDP/TCP 探测下可用 --src-port 固定源端口、--fixed-dport 固定 UDP 目的端口(默认按 TTL 递增)、--src-ip 伪造源 IP、--dst-ip 覆盖写入探针的目的 IP(独立于显示的目标),便于验证特定五元组/转发策略。这些选项对 ICMP 无效。源端口为 0 时按 (ttl,probe) 自动分配,保证并发探针可区分;固定源端口会牺牲源端口维度的区分(仍按内嵌头其余字段匹配)。

4. 并发模型

每个探针通过 goscapy 的 Sr1 发送并等待首个匹配回包;匹配函数依据内嵌原始报文的标识字段(ICMP id/seq、UDP/TCP 端口)路由回包,确保并发下回包归属正确。

5. goscapy 编解码

探针用 goscapy builder 构造,IP/ICMP/UDP/TCP 校验和自动计算:

// ICMP 探针,TTL 递增
ip := layers.NewIP()
ip.Set("src", srcIP); ip.Set("dst", dstIP); ip.Set("ttl", uint8(ttl))
icmp := layers.NewICMPEcho(pid, uint16(ttl)<<8|uint16(probe))
pkt := ip.Over(icmp)

// 回包解析(含 ICMP 错误内嵌的原始报文头)
resp, _ := packet.DissectByProto(raw, "IP")
icmpType, _ := resp.GetLayer("ICMP").Get("type")

6. 快速开始

编译:

go build -o traceroute ./cmd/traceroute/
# 或
make build-traceroute

运行(raw socket 需要 root / CAP_NET_RAW):

# ICMP traceroute(默认)
sudo ./traceroute example.com

# UDP traceroute,指定起始端口
sudo ./traceroute -p udp --port 33434 8.8.8.8

# TCP SYN traceroute 到 443 端口(适合穿越防火墙)
sudo ./traceroute -p tcp --port 443 example.com

# 一次并发探测多个目标
sudo ./traceroute 8.8.8.8 1.1.1.1 example.com

7. 命令行参数

默认说明
-p--protocolicmp探测协议:icmp / udp / tcp
-m--max-hops30最大跳数(TTL)
-q--queries3每跳探针数量
--port33434(udp)/80(tcp)UDP/TCP 目标端口
--src-port0UDP/TCP 源端口(0 = 按探针自动分配)
--fixed-dportfalseUDP 目标端口固定为 --port(不随 TTL 递增)
--src-ipauto覆盖 UDP/TCP 探针源 IPv4(伪造源 IP)
--dst-iptarget覆盖写入 UDP/TCP 探针的目的 IPv4
-w--timeout1s单探针超时
--no-dnsfalse关闭反向 DNS 解析
--asnfalse经 Team Cymru DNS 为每跳标注起源 ASN / AS 名 / BGP 前缀(仅出站 DNS,无需 API key)
--geofalse经 ipinfo.io 为每跳标注归属地/运营商(会把每跳 IP 发往第三方)
--geo-tokenipinfo.io API token(可选;为空则用匿名额度)
-t--tos0IP TOS/DSCP 值
--parallel16并发在途探针上限
-I--interfaceauto出向网卡(自动探测)
-l--local-addrauto本地源 IPv4(自动探测)
-V--versionfalse打印版本并退出

8. 输出格式

输出风格对齐传统 traceroute / aeden/traceroute,每跳一行,附带各探针 RTT;无响应的探针显示为 *,ECMP 同 TTL 多个回源就地展示。

traceroute to example.com (93.184.216.34), 30 hops max, ICMP probes, 60 byte packets
1   gateway (192.168.1.1)   1.234ms  1.301ms  1.122ms
2   10.0.0.1 (10.0.0.1)   5.678ms  5.521ms  *
3   * * *
4   core1.isp.net (203.0.113.5)   12.345ms  12.201ms  12.503ms

9. IP 信息增强(ASN / 归属地)

可选地为每跳 IP 附加 ASN / AS 名 / BGP 前缀地理归属地信息,类似 NextTrace 的可视化效果。数据来源做成可插拔的 Provider 接口traceroute/enrich 包),默认两种实现,未来可替换为离线 MaxMind、bgp.tools、内部服务等。

开关数据源提供字段依赖
--asnTeam Cymru IP-to-ASN DNS起源 ASN、AS 名、覆盖 BGP 前缀仅出站 DNS,无需 API key
--geoipinfo.io HTTP API国家、省/州、城市、运营商需访问外网,可选 --geo-token

两者均默认关闭,不开启时行为与原版完全一致。查询在所有探测完成后统一并发执行,并按 IP 去重(同一 ASN 的 AS 名也会缓存),不影响探测路径本身。

隐私提醒:--geo 会把每个命中跳的 IP 发送给第三方(ipinfo.io)。在敏感网络环境中请优先只用 --asn(纯 DNS),或接入离线数据源。
# 标注 ASN / BGP 前缀(纯 DNS)
sudo ./traceroute --asn 8.8.8.8

# 同时标注归属地(带 token 提升额度)
sudo ./traceroute --asn --geo --geo-token <your-token> example.com

输出会在每跳行尾追加方括号注释,格式 [ASN AS名 前缀 | 国家 省 城市]

traceroute to dns.google (8.8.8.8), 30 hops max, ICMP probes, 60 byte packets
1   gateway (192.168.1.1)   1.234ms  1.301ms  1.122ms
2   core1.isp.net (203.0.113.5) [AS4134 CHINANET-BACKBONE 203.0.113.0/24 | CN Beijing]   12.3ms  12.2ms
3   dns.google (8.8.8.8) [AS15169 GOOGLE 8.8.8.0/24 | US Mountain View]   30.1ms  29.8ms

10. 使用场景

11. FAQ

为什么需要 root? 构造自定义 IP/ICMP/UDP/TCP 报文并设置 TTL 需要 raw socket,需 root 或 CAP_NET_RAWsudo setcap cap_net_raw+ep ./traceroute)。

支持 IPv6 吗? 当前实现优先 IPv4;包结构预留了 IPv6(HopLimit)扩展,与 ping/ping6 的双栈风格保持一致。

某些跳一直是 * 该跳路由器可能对 ICMP Time Exceeded 限速或不回送,属正常现象,不一定代表丢包。