在和朋友一起吃饭的时候,A 提了一个有意思的问题:怎样可以把一个机房内的路由设备从互联网「隐藏」呢?
「隐藏就是没有人可以知道这个设备的 IP 地址,这还不简单,只要禁用 ICMP 就可以了」, B说。
A 说,这样是可以。很多安全团队在实施起来也确实是这么做的,但是这样并不好:机房内所有的 IP 都无法 ping 通了。这样会增加 debug 的难度,得不偿失呀!
C 说,那就依然转发 ICMP 包,但是如果是 TTL=1 的包,就不要回复 ICMP Time Exceeded 了。
B 说,人家要的是「隐藏」,要是像你说的这么做,别人还是知道中间有一个设备的存在,没有完全符合要求。

事实是这样的。假设一个简单的物理拓扑是 A -> B -> C,B 不回复 ICMP Time Exceeded,那么 traceroute 看起来就是 A ? C,可以猜测得到中间有一个路由器,但是已经禁止回复 ICMP Time Exceeded。看起来像下面这样。
C 说,traceroute 的原理是发送 TTL=1, 2, 3, … 的包,不断让路由器回复 ICMP Time Exceeded 信息,来得到每一跳的 IP 地址。要想完全隐藏,只需要:
- 自己不回复
ICMP Time Exceeded; - 让下一跳回复,仿佛下一跳就在自己的位置;
这样就可以完全隐藏了。要达到这个目的,只需要:
- 对于 TTL=1 的包,不是丢弃,而是转发给下一跳,并且 TTL 依然保持为 1,即可。
A ---[TTL=1]---> B ---[TTL=1]---> C, 对于客户端的 traceroute,看起来就像:A → C。
这样(理论上)好像确实可行了。三人对这个结论满意了。
后来我把这个讨论记录在了博客上(你现在正在阅读的一个),一位读者马上就发现了问题:可是这样 C 会出现两次吧!
确实是这样,假设在 A -> B -> C 的链路中:
- TTL = 1 从 A 进入的时候,A 会在 ICMP 中回复自己的 IP;
- TTL = 2 从 A 进入的时候,B 会直接转发给 C,C 会在 ICMP 中回复自己的 IP;
- TTL = 3 从 A 进入的时候,B 会 TTL -1 转发给 C,C 会在 ICMP 中回复自己的 IP;
这样 C 就出现了 2 次!
看来,B 必须完全不减 TTL,直接转发,才能隐藏自己。不过这样就有出现环路2的风险了。
可是这样 C 会出现两次吧
说的对哦,那是不是全部都不减 TTL 直接转发,就可以了?
小心打环哦(
是有风险,不过严格只有一台设备这么做的话是没有风险的。
好像可以在网络都正常的情况,不减 TTL 直接转发好像就可以隐藏了
谢谢,我更新一下原文。
原文已更新,现在应该没有问题了。