Sono stato in grado di configurare uno spazio dei nomi di rete e avviare un server in ascolto su 127.0.0.1 all'interno dello spazio dei nomi:
# 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
Dopodiché, posso connettermi al server all'interno dello spazio dei nomi:
# ip netns exec vpn nc 127.0.0.1 80 -zv
localhost [127.0.0.1] 80 (http) open
Ma non riesco a connettermi al server al di fuori dello spazio dei nomi:
# nc 127.0.0.1 80
(UNKNOWN) [127.0.0.1] 80 (http) : Connection refused
Come configurare iptables o lo spazio dei nomi per inoltrare il traffico dallo spazio dei nomi globale allo spazio dei nomi VPN?
Risposta accettata:
Primo:non penso che tu possa ottenere questo risultato usando 127.0.0.0/8 e/o un'interfaccia di loopback (come lo). Devi usare altri IP e interfacce, perché ci sono cose specifiche cablate per 127.0.0.0/8 e per il loopback.
Poi c'è sicuramente più di un metodo, ma ecco un esempio:
# 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
Il primo comando crea dal nulla una coppia di interfacce ethernet virtuali collegate da un cavo ethernet virtuale. Il secondo comando sposta una di queste interfacce in netns vpn. Consideralo l'equivalente di cose come socketpair(2) o pipe(2):un processo crea una coppia, quindi si biforca e ogni processo mantiene solo un'estremità della coppia e possono comunicare.
Di solito (LXC, virt-manager,...) c'è anche un bridge coinvolto per mettere tutto nella stessa LAN quando hai molti netns.
Una volta che questo è a posto, per l'host è come qualsiasi router.
Abilita l'inoltro dell'ip (sii più restrittivo se puoi:ne hai bisogno almeno per vethhost0 e l'interfaccia principale):
# echo 1 > /proc/sys/net/ipv4/conf/all/forwarding
Aggiungi qualche regola DNAT, come:
# 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
Ora puoi aggiungere un percorso predefinito all'interno di VPN con:
# ip netns exec vpn ip route add default via 10.0.0.1
Oppure, invece, aggiungi una regola SNAT per vedere tutto come proveniente dalla 10.0.0.1 all'interno di vpn.
# iptables -t nat -A POSTROUTING -d 10.0.0.2/24 -j SNAT --to-source 10.0.0.1
Con questo in atto puoi testare da qualsiasi altro host, ma non dall'host stesso. Per fare ciò, aggiungi anche una regola DNAT simile alla precedente DNAT, ma in OUTPUT e modificata (altrimenti anche qualsiasi connessione http in uscita verrebbe modificata) al tuo IP. Supponiamo che il tuo IP sia 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
Ora funzionerà anche se ti connetti dall'host a se stesso se non usi un IP di loopback, ma qualsiasi altro IP appartenente all'host con una regola nat come sopra. Supponiamo che il tuo IP sia 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