Como encaminhar o tráfego entre namespaces da rede Linux?

3

Consegui configurar um namespace de rede e iniciar um servidor que escuta 127.0.0.1 dentro do namespace:

# ip netns add vpn
# ip netns exec vpn ip link set dev lo up
# ip netns exec vpn nc -l -s 127.0.0.1 -p 80 &

# ip netns exec vpn netstat -tlpn

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:80            0.0.0.0:*               LISTEN      5598/nc

Depois disso, posso conectar-me ao servidor dentro do namespace:

# ip netns exec vpn nc 127.0.0.1 80 -zv
localhost [127.0.0.1] 80 (http) open

Mas não consigo me conectar ao servidor fora do namespace:

# nc 127.0.0.1 80
(UNKNOWN) [127.0.0.1] 80 (http) : Connection refused

Como configurar o iptables ou namespace para encaminhar o tráfego do namespace global para o namespace vpn?

    
por Sha000 08.09.2017 / 18:56

1 resposta

5

Primeiro: Eu não acho que você pode conseguir isso usando 127.0.0.0/8 e / ou uma interface de loopback (como lo). Você tem que usar alguns outros IPs e interfaces, porque existem coisas específicas para 127.0.0.0/8 e loopback.

Então, certamente há mais de um método, mas aqui está um exemplo:

# ip netns add vpn
# ip link add name vethhost0 type veth peer name vethvpn0
# ip link set vethvpn0 netns vpn
# ip addr add 10.0.0.1/24 dev vethhost0
# ip netns exec vpn ip addr add 10.0.0.2/24 dev vethvpn0
# ip link set vethhost0 up
# ip netns exec vpn ip link set vethvpn0 up
# ping 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.134 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.100 ms

O primeiro comando cria, a partir do ar, um par de interfaces ethernet virtuais conectadas por um cabo ethernet virtual. O segundo comando move uma dessas interfaces para o netns vpn. Considere o equivalente a coisas como socketpair (2) ou pipe (2): um processo cria um par e, em seguida, garfos, e cada processo mantém apenas uma extremidade do par e eles podem se comunicar.

Normalmente (LXC, virt-manager, ...) há também uma ponte envolvida para colocar tudo na mesma LAN quando você tem muitos netns.

Uma vez que isto está no lugar, para o host é como qualquer roteador. Habilite o encaminhamento de ip (seja mais restritivo se você puder: você precisa dele pelo menos para vethhost0 e a interface principal):

# echo 1 > /proc/sys/net/ipv4/conf/all/forwarding

Adicione alguma regra DNAT, como:

# iptables -t nat -A PREROUTING ! -s 10.0.0.0/24 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.0.2

Agora você pode adicionar uma rota padrão dentro da vpn com:

# ip netns exec vpn ip route add default via 10.0.0.1

Ou então, adicione uma regra SNAT para que tudo seja visto como proveniente de 10.0.0.1 dentro da VPN.

# iptables -t nat -A POSTROUTING -d 10.0.0.2/24 -j SNAT --to-source 10.0.0.1

Com isso, você pode testar de qualquer outro host, mas não do próprio host. Para fazer isso, adicione também uma regra DNAT semelhante à DNAT anterior, mas em OUTPUT e alterada (caso contrário, qualquer conexão HTTP de saída também seria alterada) para seu próprio IP. Digamos que seu IP seja 192.168.1.2:

# iptables -t nat -A OUTPUT -d 192.168.1.2 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.0.2

Agora ele vai funcionar mesmo se você se conectar do host a si mesmo se você não usar um ip de loopback, mas qualquer outro IP pertencente ao host com uma regra nat como acima. Digamos que seu IP seja 192.168.1.2:

# ip netns exec vpn nc -l -s 10.0.0.2 -p 80 &
[1] 10639
# nc -vz 192.168.1.2 80
nc: myhost (192.168.1.2) 80 [http] open
#
[1]+  Done                    ip netns exec vpn nc -l -s 10.0.0.2 -p 80
    
por 20.09.2017 / 20:16