原理
程序利用增加存活时间(TTL)值来实现其功能的。每当数据包经过一个路由器,其存活时间就会减1。当其存活时间是0时,主机便取消数据包,并发送一个ICMP TTL数据包给原数据包的发出者。
程序发出的首3个数据包TTL值是1,之后3个是2,如此类推,它便得到一连串数据包路径。注意IP不保证每个数据包走的路径都一样。
实现
主叫方首先发出 TTL=1 的 UDP 数据包,第一个路由器将 TTL 减1得0后就不再继续转发此数据包,而是返回一个 ICMP 超时报文,主叫方从超时报文中即可提取出数据包所经过的第一个网关地址。然后又发出一个 TTL=2 的 UDP 数据包,可获得第二个网关地址,依次递增 TTL 便获取了沿途所有网关地址。
需要注意的是,并不是所有网关都会如实返回 ICMP 超时报文。出于安全性考虑,大多数防火墻以及启用了防火墻功能的路由器缺省配置为不返回各种 ICMP 报文,其余路由器或交换机也可被管理员主动修改配置变为不返回 ICMP 报文。因此 Traceroute 程序不一定能拿全所有的沿途网关地址。所以,当某个 TTL 值的数据包得不到响应时,并不能停止这一追踪过程,程序仍然会把 TTL 递增而发出下一个数据包。一直达到默认或用参数指定的追踪限制(maximum_hops)才请勿追踪。
依据上述原理,利用了 UDP 数据包的 Traceroute 程序在数据包到达真正的目的主机时,就可能因为该主机没有提供 UDP 服务而简单将数据包抛弃,并不返回任何信息。为了解决这个问题,程序设计者使用了一个技巧,因 UDP 协议规定端口号必须小于 30000 ,他故意违反协议设置了一个大于 30000 的端口号,所以目标主机收到数据包后唯一能做的事就是返回一个“端口不可达”的 ICMP 报文,于是主叫方就将端口不可达报文当作跟踪退出的标志。
隐藏此后的4跳路由
Iptables -t
mangle -A PREROUTING -m ttl --ttl-gt 1 -j TTL --ttl-inc 4
在PREROUTING链上抓数据包只要是TTL大于1的 将TTL加4.
验证配置
iptables -t mangle
-nvL
Chain PREROUTING
(policy ACCEPT 684G packets, 41T bytes)
pkts bytes target prot opt in out
source
destination
684G
41T TTL all -- * *
0.0.0.0/0
0.0.0.0/0 TTL match TTL
> 1 TTL increment by 4
Ttl (match TTL
value)
This module matches the time to live
field in the IP header.
--ttl-eq ttl
Matches the given TTL value.
--ttl-gt ttl
Matches if TTL is greater than
the given TTL value.
--ttl-lt ttl
Matches if TTL is less than the
given TTL value.
TTL (change TTL value)
This
is used to modify the IPv4 TTL header field. The TTL field determines how many hops
(routers) a packet can traverse
until it’s time to live is exceeded.
Setting or incrementing the TTL field
can potentially be very dangerous, so it should be avoided at any cost.
Don’t ever set or increment the value on
packets that leave your local network!
mangle table.
--ttl-set value
Set the TTL value to ‘value’.
--ttl-dec value
Decrement the TTL value ‘value’
times.
--ttl-inc value
Increment the TTL value ‘value’
times.
禁止PC机上tracert
iptables -A FORWARD -p icmp -m length --length 92 -j DROP
length
This
module matches the
length of the layer-3 payload (e.g. layer-4
packet) of a packet against a specific
value or range of values.
[!] --length length[:length]