我正在尝试模拟许多网络跃点,类似于Star Wars Traceroute。作者提供了一个脚本here,但是它是使用vrf
而不是Linux而为Cisco路由器设计的。
这是我目前的尝试;
echo 1 > /proc/sys/net/ipv4/ip_forward
ifconfig br0 172.16.100.1 netmask 255.255.255.0
ifconfig br0:1 172.16.101.1 netmask 255.255.255.0
ifconfig br0:2 172.16.102.1 netmask 255.255.255.0
ifconfig br0:2 172.16.103.1 netmask 255.255.255.0
ip rule add iif br0 table 100
ip rule add iif br0:1 table 101
ip rule add iif br0:2 table 102
ip route add default table 100 dev 172.16.101.1
ip route add default table 101 dev 172.16.102.1
ip route add default table 102 dev 172.16.103.1
ping -I br0 172.16.103.2
我尝试使用Source Based Routing完成相同的操作,显然会重现vrf
的效果,请参阅here,但附加tcpdump -i br0
根本没有显示任何流量,然后在lo0
上拾取数据包。
替代解决方案似乎包括使用iptables
来破坏源IP和其他欺骗行为,感觉很脏,所以我不确定在哪里集中精力。
任何提示/指示都将不胜感激
答案 0 :(得分:2)
我能够使用Linux命名空间,它目前是Linux等效的vrf
。这只是一个手写的POC,您可能希望将其包装在脚本中并在程序上生成。
我花了8个多小时才弄明白,希望将来能帮助别人。
$ ping 172.16.101.2
PING 172.16.101.2 (172.16.101.2) 56(84) bytes of data.
64 bytes from 172.16.101.2: icmp_seq=1 ttl=63 time=0.064 ms
64 bytes from 172.16.101.2: icmp_seq=2 ttl=63 time=0.043 ms
$ traceroute 172.16.101.2
traceroute to 172.16.101.2 (172.16.101.2), 30 hops max, 60 byte packets
1 172.16.100.2 (172.16.100.2) 0.055 ms 0.006 ms 0.004 ms
2 172.16.101.2 (172.16.101.2) 0.059 ms 0.009 ms 0.009 ms
# add the namespaces
ip netns add hop1
ip netns add hop2
ip netns exec hop1 ip link set lo up
ip netns exec hop2 ip link set lo up
ip netns exec hop1 sysctl net.ipv4.ip_forward net.ipv4.ip_forward=1
ip netns exec hop2 sysctl net.ipv4.ip_forward net.ipv4.ip_forward=1
# create host link to first hop
ip link add hop1 type veth peer name veth1
ip addr change 172.16.100.1/24 dev hop1
ip link set hop1 up
ip link set veth1 netns hop1
ip netns exec hop1 ip link set veth1 name eth0
ip netns exec hop1 ip link set eth0 up
ip netns exec hop1 ip addr change 172.16.100.2/24 dev eth0
# create hop2 (link to hop1)
ip link add veth0 type veth peer name veth1
ip link set veth0 netns hop1
ip netns exec hop1 ip link set veth0 name eth1
ip netns exec hop1 ip link set eth1 up
ip netns exec hop1 ip addr change 172.16.101.1/24 dev eth1
ip link set veth1 netns hop2
ip netns exec hop2 ip link set veth1 name eth0
ip netns exec hop2 ip link set eth0 up
ip netns exec hop2 ip addr change 172.16.101.2/24 dev eth0
# set namespace routing
ip netns exec hop1 route add default gw 172.16.101.2
ip netns exec hop2 route add default gw 172.16.101.1
# set host routing
route add -net 172.16.101.0/24 gw 172.16.100.2
答案 1 :(得分:2)
对于那些仍在尝试使用Linux制作自己的《星球大战追踪路线》的人,我把这个想法写成脚本。
#!/bin/bash
#
# traceroute fun with linux namespaces
# each namespace is basically a router we connect
# to each other using fancy /32 networking
#
# scott nicholas <scott@nicholas.one> 2018-10-27
#
# how many levels deep are we going?
depth=16
prefix=192.168.99.
# can change function easily or just pre-populate ip array
calcip() { printf '%s%d' "$prefix" $((63 + i)); }
# instead of special casing things, if we bind init's netns into a name
# all of the code can use "-n ns"
touch /var/run/netns/default
mount --bind /proc/1/ns/net /var/run/netns/default
ns[0]=default if[0]=root ip[0]=${prefix}1
for ((i = 1; i <= depth; i++)); do
ns[i]=hop$i if[i]=hop$i ip[i]=$(calcip $i)
ip netns add "${ns[i]}"
# interfaces are named by whom is on the other side
# so it's kinda flip-flopped looking.
ip -n "${ns[i-1]}" link add "${if[i]}" type veth peer name "${if[i-1]}" \
netns "${ns[i]}"
ip -n "${ns[i]}" a a "${ip[i]}"/32 dev "${if[i-1]}"
# interfaces must be up before adding routes
ip -n "${ns[i-1]}" link set "${if[i]}" up
ip -n "${ns[i ]}" link set lo up
ip -n "${ns[i ]}" link set "${if[i-1]}" up
ip -n "${ns[i-1]}" route add "${ip[i ]}" dev "${if[i]}"
ip -n "${ns[i ]}" route add "${ip[i-1]}" dev "${if[i-1]}"
ip -n "${ns[i ]}" route add default via "${ip[i-1]}"
# tell everyone above my parent that i'm down here in this mess
for ((j = i - 2; j >= 0; j--)); do
ip -n "${ns[j]}" route add "${ip[i]}" via "${ip[j+1]}"
done
done