Traceroute 是一个很常用的网络 debug 工具,它(应该)会列出你的数据包在到达最终目的地的路上经过的所有路由节点,如果你 traceroute 我的网站,你会得到看起来像这样的内容:
traceroute通过 Time To Live
或者 IPV6 下的 Hop Limit
实现追踪的效果
这个数值的用意是通过限制数据包能通过的最长「逻辑距离」(最多能通过几个节点),防止数据包在网络故障的情况下在网络上被无限循环广播。每当数据包经过一个节点,这个数值就会减少,这个值减小到0时,路由节点就会丢弃这个数据包:举个例子,网络故障的情况下,一个 IPV4 数据包的 TTL 为65,经过64个节点时,其TTL会等于65-64=1,经过第65个节点时,TTL 会降为0,那么,第66个节点在发现这个数据包的 TTL 为0时就会将其直接丢弃。
但做到这一步并没有解决所有问题:出于礼貌原因,当一个数据包丢失了,我们还要想办法通知发送这个数据包的人——既然一个数据包能够从发送者到达丢弃它的服务器,那么丢弃它的服务器和发送者之间一定是可以通信的。
那么 traceroute 的设计思想是:首先设置一个极低的 TTL,并向目标服务器发包,小幅增加这个 TTL,再次向服务器发包,重复这个步骤,直到可以到达目标服务器为止,通过这个做法,traceroute就可以通过前面提到的,数据包被丢弃后的「回执」向我们展示我们与目标服务器之间的「路径」。
traceroute 工具通常还会贴心的帮你查询好对应 IP 的反向 DNS,便于我们查看途径节点的相关信息。尽管设置 IP 的反向 DNS 并非必须,大多数运营商都会设置反向 DNS 以方便用户或者他们自己 Debug。
重要的是,如果买下一个 IP 区段,你便可以将这个区段内的 IP 的反向 DNS 改成 Whatever you want。于是乎,一位仁兄突发奇想,买下了一个 IP 区段,于是就有了下面的 TraceRoute 民谣:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| PS C:\Users\l3zc> tracert -h 100 bad.horse
通过最多 100 个跃点跟踪
到 bad.horse [162.252.205.157] 的路由:
1 <1 毫秒 <1 毫秒 <1 毫秒 192.168.0.1
2 2 ms 1 ms 1 ms 192.168.1.1
3 5 ms 4 ms 4 ms 100.66.128.1
4 4 ms 4 ms 4 ms 58.20.125.137
5 5 ms 4 ms 4 ms 119.39.126.117
6 * 27 ms 27 ms 219.158.98.69
7 32 ms 30 ms 30 ms 219.158.5.158
8 29 ms 30 ms 31 ms 219.158.16.66
9 172 ms 175 ms 174 ms 219.158.98.10
10 179 ms 175 ms 174 ms ix-xe-8-2-5-0.tcore1.sqn-sanjose.as6453.net [63.243.205.93]
11 226 ms 225 ms 236 ms if-ae-1-2.tcore2.sqn-sanjose.as6453.net [63.243.205.2]
12 222 ms 222 ms * if-ae-51-2.tcore2.ct8-chicago.as6453.net [64.86.79.14]
13 224 ms 225 ms 225 ms if-ae-22-2.tcore1.ct8-chicago.as6453.net [64.86.79.2]
14 223 ms 223 ms 223 ms if-ae-8-2.tcore2.tnk-toronto.as6453.net [66.110.48.1]
15 223 ms 223 ms 223 ms if-ae-2-2.tcore1.tnk-toronto.as6453.net [64.86.33.89]
16 225 ms 224 ms 225 ms 64.86.33.58
17 223 ms 223 ms 223 ms 67.223.96.90 [67.223.96.90]
18 225 ms 224 ms 224 ms bad.horse [162.252.205.130]
19 228 ms 228 ms 229 ms bad.horse [162.252.205.131]
20 239 ms 237 ms 235 ms bad.horse [162.252.205.132]
21 244 ms 245 ms 248 ms bad.horse [162.252.205.133]
22 243 ms 243 ms 243 ms he.rides.across.the.nation [162.252.205.134]
23 248 ms 249 ms 249 ms the.thoroughbred.of.sin [162.252.205.135]
24 263 ms 259 ms 261 ms he.got.the.application [162.252.205.136]
25 267 ms 268 ms 267 ms that.you.just.sent.in [162.252.205.137]
26 266 ms 266 ms 266 ms it.needs.evaluation [162.252.205.138]
27 267 ms 266 ms 267 ms so.let.the.games.begin [162.252.205.139]
28 275 ms 274 ms 274 ms a.heinous.crime [162.252.205.140]
29 280 ms 280 ms 280 ms a.show.of.force [162.252.205.141]
30 292 ms 293 ms 292 ms a.murder.would.be.nice.of.course [162.252.205.142]
31 293 ms 290 ms 290 ms bad.horse [162.252.205.143]
32 301 ms 302 ms 302 ms bad.horse [162.252.205.144]
33 297 ms 296 ms 297 ms bad.horse [162.252.205.145]
34 308 ms 307 ms 307 ms he-s.bad [162.252.205.146]
35 309 ms 309 ms 308 ms the.evil.league.of.evil [162.252.205.147]
36 314 ms 314 ms 313 ms is.watching.so.beware [162.252.205.148]
37 322 ms 323 ms 322 ms the.grade.that.you.receive [162.252.205.149]
38 327 ms 326 ms 326 ms will.be.your.last.we.swear [162.252.205.150]
39 327 ms 329 ms 330 ms so.make.the.bad.horse.gleeful [162.252.205.151]
40 331 ms 331 ms 331 ms or.he-ll.make.you.his.mare [162.252.205.152]
41 339 ms 339 ms 339 ms o_o [162.252.205.153]
42 345 ms 346 ms 346 ms you-re.saddled.up [162.252.205.154]
43 348 ms 348 ms 348 ms there-s.no.recourse [162.252.205.155]
44 351 ms 350 ms 350 ms it-s.hi-ho.silver [162.252.205.156]
45 363 ms 363 ms 361 ms signed.bad.horse [162.252.205.157]
跟踪完成。
PS C:\Users\l3zc>
|
这是这首民谣的原曲:
某位仁兄甚至用这个做了一份他的简历:
如何实现?
看起来很美好,但是这如何实现?
我们可以轻松的更改 Reverse DNS 的设置。最大的问题是,如何让数据包按照我们希望的路线穿行。
在物理上将节点按顺序连接显然不现实,现在能被想到的有两种办法:要么在单个节点上将很多虚拟的接口按顺序分配 IP 并串联起来并将他们用作「节点」,要么在用户网络层上做手脚,生成假的「超限」消息,凭空生成一条不存在的路由线路。
https://github.com/benjojo/traceroute-haiku
这个仓库是 benjojo 进行实验的项目,利用了第二种方法,用GO语言写一个TUN/TAP,接管所有的网络流量,并生成假的「超限」消息。
自己动手
我们来写一个程序,彻底理解这个项目。
我之前没有使用过 Go 语言。已知的 Go 项目里我最熟悉的是 Clash 的 Mac 版本。Clash 有强大的分流功能,以及为了兼容性,编写了一套 TUN 模式。用来作为切入点学习非常合适。
参考
https://blog.benjojo.co.uk/post/traceroute-haikus