【问题标题】:Simulating network hops on a single Linux box在单个 Linux 机器上模拟网络跃点
【发布时间】:2015-12-16 19:25:47
【问题描述】:

我正在尝试模拟许多网络跃点,类似于Star Wars Traceroute。作者提供了一个脚本here,但它是为 Cisco 路由器设计的,使用的是vrf,而不是 Linux。

这是我目前的尝试;

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 和其他诡计,感觉很脏,所以我不知道应该把精力放在哪里。

任何提示/指针将不胜感激

【问题讨论】:

  • 我实际上已经使用netns自己重现了这个,我将在早上分享最终解决方案

标签: linux networking routing iptables


【解决方案1】:

我将这个想法写成了一个脚本,供那些仍在寻找这个问题并试图使用 Linux 制作自己的星球大战 Traceroute 的人使用。

#!/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

【讨论】:

  • 干得好!我已将您的更改为可接受的答案。 @neutronscott
【解决方案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

【讨论】:

    猜你喜欢
    • 2017-09-27
    • 2018-02-12
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 2011-01-20
    相关资源
    最近更新 更多