我有一台 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 代码。