进程组A默认路由tun0,B默认路由tun1等

进程组A默认路由tun0,B默认路由tun1等

我有一台 Linux 机器隧道接口、、tun0等等tun1

我希望设置一些事情,以便特定的一组进程,A,其默认(也是唯一的)路由指向tun0。与此同时,第二组进程,,其默认(且唯一)路线指向tun1,等等。A等不一定是 POSIX 意义上的“进程组”;理想情况下,配置应该提前建立,之后任何进程都可以声明自己是A或者或者 ... 在启动时。(如果只有正在运行的进程可以这样做,那就没问题root。)

如果这些进程组中的任何一个曾经将流量从错误的隧道接口或真实的网络接口发送出去eth0,那么这是一个错误。如果同一主机上的不相关进程曾经将流量从任何隧道接口;他们应该继续eth0直接使用。

我的印象是这可以通过“网络命名空间”来完成,但我一直无法弄清楚如何操作;我正在寻求分步说明。

答案1

这确实可以通过网络命名空间来实现。假设您拥有以下所有信息(由隧道设备另一端的进程或您的控制器程序分配):

  • $namespace网络命名空间的标签
  • $device 要分配给命名空间的隧道设备
  • $mtu 隧道设备的 MTU
  • $address 分配给隧道设备的 IP 地址
  • $netmask 分配给隧道设备的网络掩码
  • $broadcast分配给隧道设备的广播地址
  • $gateway 命名空间内使用的默认网关
  • $dns_servers 命名空间内使用的 DNS 服务器列表

然后下面的伪 shell 脚本将设置命名空间:

mkdir /etc/netns/$namespace
for dns_server in $dns_servers {
    echo "nameserver $dns_server" >> /etc/netns/$namespace/resolv.conf
}

ip netns add $namespace
ip link set dev $device netns $namesapce

ip netns exec $namespace {
    ip link set dev lo up
    ip addr add dev $device local $address/$netmask broadcast $broadcast
    ip link set dev $device mtu $mtu up
    ip route add default via $gateway dev $device
}

而为了再次拆除它,你需要

kill $(ip netns pids $namespace)
ip netns delete $namespace
rm -rf /etc/netns/$namespace

要在命名空间内运行程序,只需使用ip netns exec

可以找到此 OpenVPN 隧道机制的实际工作实现这里;不幸的是,因为需要它,因为它必须是 setuid,上面的代码变成了 1200 行 C 代码。

相关内容