Pude configurar un espacio de nombres de red e iniciar un servidor que escucha en 127.0.0.1 dentro del espacio de nombres:
# 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
Después de eso, puedo conectarme al servidor dentro del espacio de nombres:
# ip netns exec vpn nc 127.0.0.1 80 -zv
localhost [127.0.0.1] 80 (http) open
Pero no puedo conectarme al servidor fuera del espacio de nombres:
# nc 127.0.0.1 80
(UNKNOWN) [127.0.0.1] 80 (http) : Connection refused
¿Cómo configurar iptables o espacio de nombres para reenviar tráfico desde el espacio de nombres global al espacio de nombres vpn?
Respuesta aceptada:
Primero:no creo que pueda lograr esto usando 127.0.0.0/8 y/o una interfaz de bucle invertido (como lo). Tiene que usar otras IP e interfaces, porque hay cosas específicas cableadas para 127.0.0.0/8 y loopback.
Entonces ciertamente hay más de un método, pero aquí hay un ejemplo:
# 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
El primer comando crea de la nada un par de interfaces ethernet virtuales conectadas por un cable ethernet virtual. El segundo comando mueve una de estas interfaces a netns vpn. Considéralo el equivalente a cosas como socketpair(2) o pipe(2):un proceso crea un par, luego se bifurca, y cada proceso mantiene solo un extremo del par y pueden comunicarse.
Por lo general (LXC, virt-manager,...) también hay un puente involucrado para poner todo en la misma LAN cuando tiene muchas redes.
Una vez que esto está en su lugar, para el host es como cualquier enrutador.
Habilite el reenvío de IP (sea más restrictivo si puede:lo necesita al menos para vethhost0 y la interfaz principal):
# echo 1 > /proc/sys/net/ipv4/conf/all/forwarding
Agregue alguna regla 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
Ahora puede agregar una ruta predeterminada dentro de vpn con:
# ip netns exec vpn ip route add default via 10.0.0.1
O bien, en su lugar, agregue una regla SNAT para que todo se vea como proveniente de 10.0.0.1 dentro de vpn.
# iptables -t nat -A POSTROUTING -d 10.0.0.2/24 -j SNAT --to-source 10.0.0.1
Con esto en su lugar, puede probar desde cualquier otro host, pero no desde el propio host. Para hacer esto, agregue también una regla DNAT similar a la DNAT anterior, pero en OUTPUT y cambiada (de lo contrario, cualquier conexión http saliente también se cambiaría) a su propia IP. Digamos que su IP es 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
Ahora incluso funcionará si se conecta desde el host a sí mismo si no usa una IP de bucle invertido, sino cualquier otra IP que pertenezca al host con una regla nat como la anterior. Digamos que su IP es 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