2

I have been trying to follow multiple guides to setup a veth-pair for 2 namespaces which can communicate with each other on alpine linux. So far I have communication between namespaces working but neither namespace can connect/ping to any external ip/url.

Here is the guides configuration that i use exactly:

  ip netns add namespace1
  ip netns add namespace2
  ip netns exec namespace1 ip address show
  ip link add veth1 type veth peer name br-veth1
  ip link add veth2 type veth peer name br-veth2
  ip link set veth1 netns namespace1
  ip link set veth2 netns namespace2
  ip netns exec namespace1 ip address show
  ip netns exec namespace1 ip addr add 192.168.1.11/24 dev veth1
  ip netns exec namespace1 ip address show
  ip netns exec namespace2 ip addr add 192.168.1.12/24 dev veth2
  
  # Create the bridge device naming it `br1`
  # and set it up:
  ip link add name br1 type bridge
  ip link set br1 up
  ip link | grep br1
  
  # Set the bridge veths from the default
  # namespace up.
  ip link set br-veth1 up
  ip link set br-veth2 up
  ip netns exec namespace1 ip link set veth1 up
  ip netns exec namespace2 ip link set veth2 up
  
  # Add the br-veth* interfaces to the bridge
  # by setting the bridge device as their master.
  ip link set br-veth1 master br1
  ip link set br-veth2 master br1
  bridge link show br1
  ip addr add 192.168.1.10/24 brd + dev br1
  ip -all netns exec ip route add default via 192.168.1.10
  iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE

I have also verified that /etc/sysctl.conf contains

net.ipv4.ip_forward = 1

and i have run this command also just in-case

sysctl -w net.ipv4.ip_forward=1

my resolv.conf contains :

nameserver 8.8.8.8

when i run

ip netns exec namespace1 ip route

I get the results:

192.168.1.0/24 dev veth1 proto kernel scope link src 192.168.1.11

If i run a regular ip route list i get:

192.168.56.0 eth0 proto kernel scope link src 192.168.56.217
192.168.1.0/24 dev br1 proto kernel scope link src 192.168.1.10

I have no idea why the setup above wont work as most guides seems to suggest that the host and namespaces should be capable of communicating after performing the MASQUERADE and setting the default route of the namespaces however networking isnt my core field of study so any suggestions would be extremely useful. If there is any information missing please feel free to drop a comment and I will try to provide it in-case I have missed something.

D3181
  • 123
  • 3

1 Answers1

1

I applied your setup verbatim and it's working.

You must have made a typo somewhere or didn't follow exactly what you wrote in your question.

Two remarks:

bridge link show br1

is an invalid syntax. man bridge was amended in recent versions probably because it was a common mistake:

bridge link show - list ports configuration for all bridges. This command displays port configuration and flags for all bridges.

To display port configuration and flags for a specific bridge, use the "ip link show master <bridge_device>" command.

So you should use instead:

ip link show master br1

or you'd get extra interfaces on other bridges. Of course it doesn't matter.

What matters is that:

  ip -all netns exec ip route add default via 192.168.1.10

should have set default routes in the network namespaces (and did for me), but you write later:

when i run

ip netns exec namespace1 ip route

I get the results:

192.168.1.0/24 dev veth1 proto kernel scope link src 192.168.1.11

Here the default route is missing. Doing the same on my system, I get, as you should have but didn't:

# ip netns exec namespace1 ip route
default via 192.168.1.10 dev veth1 
192.168.1.0/24 dev veth1 proto kernel scope link src 192.168.1.11 

So figure out what is missing. Retest your commands exactly as given, manually, without changing any order, and verify you get the default route. For example this route would be lost if the interface is brought down then up again (but it's not done in OP's script). If needed don't use -all but repeat twice the command once for namespace1 once for namespace2.


UPDATE: from further discussion in comments it appears also that OP had iptables' with a FORWARD policy set as DROP.

If one intends to enable inter-namespace traffic (should br_netfilter be activated, see at the end) and any outgoing traffic from the namespaces, one could simply use for example:

iptables -I FORWARD -i br1 -j ACCEPT

Likewise for the namespaces to reach the host if needed:

iptables -I INPUT -i br1 -j ACCEPT

Security about this should really be pondered, and the rules integrated in the existing firewall solution.

Things can become more complex if other tools like Docker are running because it might enable br_netfilter, as can be seen in my answer to this Q/A.

A.B
  • 9,037
  • 2
  • 19
  • 37
  • Thank you so much for the lengthy response. I went through it all again, and fixed the bridge link command. I now receive the same output for the ip route for both namespaces, it seems something else may have happend as netstat -nr actually showed a default gateway. However now i actually have both default gateways set and still i cannot ping doing ip netns exec namspace1 ping 8.8.8.8, however i can ping from host...is there anything else required to get br1 internet access? i.e do i need to add eth0 as a gateway for br1? – D3181 Nov 04 '20 at 14:24
  • Disable any firewall (to enable all traffic) while testing. Don't run anything else: don't run Docker etc. – A.B Nov 04 '20 at 14:29
  • Thanks that actually solved it. The problem was else-where. Another network security script had iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT which was blocking the ping – D3181 Nov 04 '20 at 14:31
  • 1
    I completed my answer with an example to fix this. – A.B Nov 04 '20 at 14:49
  • After reading your update, although the question has been answered with your help im now wondering if there is a way to enable safer communication from externally over port 80, to an application running inside a namespace? Im using traefik not on host but inside the namespace in containerd so need to allow req/response so can i somehow avoid br1 having to communicate with host if a response is required? – D3181 Nov 04 '20 at 15:58
  • You probably need port forwarding using iptables. There are plenty of information on Internet or Q/A on SE, SU or UL SE etc. about this, it's really something basic, looking like iptables -t nat -A PREROUTING (insert additional conditions like interface or address) -p tcp --dport 80 -j DNAT --to-destination 10.0.0.X – A.B Nov 04 '20 at 16:22