У меня есть Linux с N туннельные интерфейсы, tun0
, tun1
, и так далее.
Я хочу настроить так, чтобы определенная группа процессов А, имеет свой (и единственный) маршрут по умолчанию, указанный на tun0
. Между тем, вторая группа процессов, B, имеет свой (и единственный) маршрут по умолчанию, указанный на tun1
, и так далее. А, Bи т. д. не обязательно являются «группами процессов» в смысле POSIX; в идеале конфигурация должна быть установлена заранее, после чего любой процесс мог объявить себя членом А или B или ... при запуске. (Это нормально, если только процессы, запущенные как root
может это сделать.)
Это ошибка, если какая-либо из этих групп процессов когда-либо отправляет трафик из неправильного туннельного интерфейса или из реального сетевого интерфейса. eth0
. Это также ошибка, если несвязанные процессы на одном хосте когда-либо отправляют трафик любой туннельных интерфейсов; они должны продолжать использовать eth0
прямо.
У меня сложилось впечатление, что это можно сделать с помощью «сетевых пространств имен», но я не мог понять, как это сделать; Прошу пошаговую инструкцию.
Это действительно можно сделать с помощью сетевых пространств имен. Предположим, что у вас есть вся следующая информация (которая либо назначается процессом на другом конце туннельного устройства, либо программой вашего контроллера):
$namespace
метка для сетевого пространства имен$device
туннельное устройство, которое будет назначено пространству имен$mtu
MTU для туннельного устройства$address
IP-адрес для назначения туннельному устройству$netmask
сетевая маска для назначения туннельному устройству$broadcast
широковещательный адрес для назначения туннельному устройству$gateway
шлюз по умолчанию для использования внутри пространства имен$dns_servers
список DNS-серверов для использования внутри пространства именЗатем следующий сценарий псевдоболочки настроит пространство имен:
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 можно найти Вот; к сожалению, потому что для чего я нужно, чтобы он был установлен, приведенное выше превращается в 1200 строк C.