I was able to set up a network namespace and start a server that listens on 127.0.0.1 inside the 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
After that, I can connect to the server inside the namespace:
# ip netns exec vpn nc 127.0.0.1 80 -zv
localhost [127.0.0.1] 80 (http) open
But I can't connect to the server outside the namespace:
# nc 127.0.0.1 80
(UNKNOWN) [127.0.0.1] 80 (http) : Connection refused
How to configure iptables or namespace to forward traffic from the global namespace to the vpn namespace?
Best Answer
First: I don't think you can achieve this by using 127.0.0.0/8 and/or a loopback interface (like lo). You have to use some other IPs and interfaces, because there are specific things hardwired for 127.0.0.0/8 and for loopback.
Then there is certainly more than one method, but here's an example:
The first command creates out of thin air a pair of virtual ethernet interfaces connected by a virtual ethernet cable. The second command moves one of these interfaces into the netns vpn. Consider it the equivalent of things like socketpair(2) or pipe(2): a process creates a pair, then forks, and each process keeps only one end of the pair and they can communicate.
Usually (LXC, virt-manager,...) there's also a bridge involved to put everything in the same LAN when you have many netns.
Once this is in place, for the host it's like any router. Enable ip forwarding (be more restrictive if you can: you need it at least for vethhost0 and the main interface):
Add some DNAT rule, like:
Now you can either add a default route inside vpn with:
Or else, instead, add a SNAT rule to have everything be seen as coming from 10.0.0.1 inside vpn.
With this in place you can test from any other host, but not from the host itself. To do this, also add a DNAT rule similar to the previous DNAT, but in OUTPUT and changed (else any outgoing http connexion would be changed too) to your own IP. Let's say your IP is 192.168.1.2:
Now it will even work if you connect from the host to itself if you don't use a loopback ip, but any other IP belonging to the host with a nat rule as above. Let's say your IP is 192.168.1.2: