I need to do a setup like this (with Linux):
- I want to have a network namespace (let's say
weth_ns
) with a network interface connected to internet (weth0
) - I want to have a different network interface as a default route in the host namespace (
eth0
) - I want to somehow be able to use things like
curl
, with some kind of interface, to transparently use the network inside that namespace to connect to internet.
So, like this.
I cannot seem to get it work. What I did so far:
ip netns add weth_ns
ip link set weth0 netns weth_ns
ip netns exec weth_ns ip link set dev weth0 up
ip netns exec weth_ns ip a # to see list to make sure it's there
ip netns exec weth_ns dhclient weth0
ip netns exec weth_ns curl website.com # works as expected
This sets up the namespace and puts the interface there. That makes curl work inside the namespace. Now I want to somehow use the isolated namespace connection from the host.
What I tried to do is set up a bridge, and set up iptables inside the namespace. So what I run:
ip link add veth0_left type veth peer veth0_right
ip link add bridge0 type bridge
ip link set bridge0 up
ip addr add 10.9.0.0/24 dev bridge0 # 10.9.0.0 is address I came up with
ip link set veth0_left master bridge0 up
ip link set dev veth0_right netns weth_ns
ip netns exec weth_ns ip link set dev veth0_right up
ip netns exec mobile_ns ip addr add 10.9.0.1/24 dev veth0_right
This adds a brige; I can now successfully ping from namespace to namespace. So the bridge itself works.
ping 10.9.0.1 # works
ip netns exec mobile_ns ping 10.9.0.0 # works
And now I need to set up iptables to use the connection inside the namespace. I suspect this is where I do some kind of mistake. This is what I gathered from various online sources:
ip netns exec mobile_ns bash
# all following inside the namespace bash:
iptables -t nat -A POSTROUTING -s 10.9.0.0/255.255.255.0 -o weth0 -j MASQUERADE
iptables -A FORWARD -i weth0 -o veth0_right -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -o weth0 -i veth0_right -m state --state ESTABLISHED,RELATED -j ACCEPT
(all the involved networks have /proc/sys/net/ipv4/conf/<network>/forwarding
set to 1. From both inside and outside of the namespace.)
And… it does not work. My network should look like this now; but I cannot connect through curl. With either veth0_left
or bridge0
network interface.
I must be doing something wrong somewhere.
edit:
To specify what "does not work mean".
curl --interface bridge0 8.8.8.8
curl: (7) Failed to connect to 8.8.8.8 port 80: No route to host
curl --interface veth0_left 8.8.8.8
curl: (7) Failed to connect to 8.8.8.8 port 80: No route to host
When I try to see tcpdump, inside the namespace, I see who-has
ARP requests, but only on the bridge interface. It seems to never "go" into the weth0 interface.
Best Answer
Ah. The thing is,
curl --interface
does not magically get around routing.As explained here
https://superuser.com/questions/1223177/why-does-curl-not-work-with-non-default-network-interface-in-centos-6