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):
-
$namespace
um rótulo para o namespace de rede -
$device
do dispositivo de túnel a ser atribuído ao namespace -
$mtu
o MTU para o dispositivo de túnel -
$address
do endereço IP a ser atribuído ao dispositivo de túnel -
$netmask
da máscara de rede para atribuir ao dispositivo de túnel -
$broadcast
do endereço de transmissão a ser atribuído ao dispositivo de túnel -
$gateway
o gateway padrão para usar dentro do namespace -
$dns_servers
uma 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.