Isso pode realmente ser feito com namespaces de rede. Suponha que você tenha todas as informações a seguir (que são atribuídas pelo processo na outra extremidade do dispositivo de encapsulamento ou pelo programa controlador):
-
$namespaceum rótulo para o namespace de rede -
$devicedo dispositivo de túnel a ser atribuído ao namespace -
$mtuo MTU para o dispositivo de túnel -
$addressdo endereço IP a ser atribuído ao dispositivo de túnel -
$netmaskda máscara de rede para atribuir ao dispositivo de túnel -
$broadcastdo endereço de transmissão a ser atribuído ao dispositivo de túnel -
$gatewayo gateway padrão para usar dentro do namespace -
$dns_serversuma lista de servidores DNS para usar dentro do namespace
Em seguida, o seguinte pseudo-script de shell configurará o namespace:
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
}
E para derrubá-lo novamente, você faz
kill $(ip netns pids $namespace)
ip netns delete $namespace
rm -rf /etc/netns/$namespace
E para executar um programa dentro do namespace, use apenas ip netns exec .
Uma implementação real em funcionamento desse mecanismo para os túneis do OpenVPN pode ser encontrada aqui ; infelizmente, porque para o que eu preciso, pois tem que ser setuid, o acima se transforma em 1200 linhas de C.