0

I'm trying to ping an external ip (in this case google) from inside a network namespace.

  ip netns add ns1
# Create v-eth1 and v-peer1: v-eth1 is in the host space whereas peer-1 is supposed to be in the ns
  ip link add v-eth1 type veth peer name v-peer1
# Move v-peer1 to ns
  ip link set v-peer1 netns ns1
# set v-eth1
  ip addr add 10.200.1.1/24 dev v-eth1
  ip link set v-eth1 up
# Set v-peer1 in the ns
  ip netns exec ns1 ip addr add 10.200.1.2/24 dev v-peer1
  ip netns exec ns1 ip link set v-peer1 up
# Set loopback interface in the ns
  ip netns exec ns1 ip link set lo up
# Add defaut route in the ns
  ip netns exec ns1 ip route add default via 10.200.1.1
# Set host routing tables
  iptables -t nat -A POSTROUTING -s 10.200.1.0/24 -j MASQUERADE
# Enable routing in the host
sysctl -w net.ipv4.ip_forward=1
#
  ip netns exec ns1 ping 8.8.8.8

For some reasons this is working fine inside a VM in virtualbox (on my laptop), it's working on my desktop (ubuntu 18.04) but it does not work on my host os on laptop (which is too Ubuntu 18.04).

I tried traceroute and this is what I got:

on laptop

faulty traceroute on laptop

on desktop

correct traceroute on desktop

Does any of you have any idea on what should I investigate in order to find the problem? I don't have a firewall set as far as I know (ufw is disabled)

EDIT: this is what I get with iptables-save -c:

# Generated by iptables-save v1.6.1 on Fri Jan 17 18:05:36 2020
*filter
:INPUT ACCEPT [3774:2079111]
:FORWARD DROP [5:420]
:OUTPUT ACCEPT [3053:308301]
:DOCKER - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
:DOCKER-USER - [0:0]
[16984:18361691] -A FORWARD -j DOCKER-USER
[16984:18361691] -A FORWARD -j DOCKER-ISOLATION-STAGE-1
[12139:18094316] -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A FORWARD -o docker0 -j DOCKER
[4761:260319] -A FORWARD -i docker0 ! -o docker0 -j ACCEPT
[0:0] -A FORWARD -i docker0 -o docker0 -j ACCEPT
[0:0] -A FORWARD -o br-6a72e380ece6 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A FORWARD -o br-6a72e380ece6 -j DOCKER
[0:0] -A FORWARD -i br-6a72e380ece6 ! -o br-6a72e380ece6 -j ACCEPT
[0:0] -A FORWARD -i br-6a72e380ece6 -o br-6a72e380ece6 -j ACCEPT
[4761:260319] -A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
[0:0] -A DOCKER-ISOLATION-STAGE-1 -i br-6a72e380ece6 ! -o br-6a72e380ece6 -j DOCKER-ISOLATION-STAGE-2
[16984:18361691] -A DOCKER-ISOLATION-STAGE-1 -j RETURN
[0:0] -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
[0:0] -A DOCKER-ISOLATION-STAGE-2 -o br-6a72e380ece6 -j DROP
[4761:260319] -A DOCKER-ISOLATION-STAGE-2 -j RETURN
[16984:18361691] -A DOCKER-USER -j RETURN
COMMIT
# Completed on Fri Jan 17 18:05:36 2020
# Generated by iptables-save v1.6.1 on Fri Jan 17 18:05:36 2020
*nat
:PREROUTING ACCEPT [406:111092]
:INPUT ACCEPT [9:703]
:OUTPUT ACCEPT [29:2283]
:POSTROUTING ACCEPT [28:2114]
:DOCKER - [0:0]
[253:19770] -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
[0:0] -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
[4:249] -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
[0:0] -A POSTROUTING -s 172.18.0.0/16 ! -o br-6a72e380ece6 -j MASQUERADE
[1:169] -A POSTROUTING -s 10.200.1.0/24 -j MASQUERADE
[0:0] -A DOCKER -i docker0 -j RETURN
[0:0] -A DOCKER -i br-6a72e380ece6 -j RETURN
COMMIT
# Completed on Fri Jan 17 18:05:36 2020
1
  • iptables-save -c
    – A.B
    Jan 17, 2020 at 15:53

1 Answer 1

1

You have Docker which itself alters the firewall rules. I can't tell if that's because of Docker, but you have iptables' default policy for filter/FORWARD set to DROP preventing any routing not explicitly allowed.

EDIT: added the return direction.

To make your experiment work this should be enough (including the return traffic which must also be enabled):

iptables -A FORWARD -i v-eth1 -j ACCEPT
iptables -A FORWARD -o v-eth1 -j ACCEPT

Note that those could be complemented with the interface to/from internet but I don't have its name.

Usually using rules below is prefered, letting the return traffic be allowed by stateful tracking: conntrack, thus having to care only about initial traffic. Feel free to try it.

iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i v-eth1 -j ACCEPT

As a side note kernels >= 4.7 usually require/allow a few more settings to have conntrack helpers (ftp...) to work correctly/securely, but that's not needed for your experiment (ICMP is handled). Some informations in this blog: Secure use of iptables and connection tracking helpers.

In case of doubt (like interaction with Docker) use -I instead to be sure to insert your rules before anything else. Just be aware restarting Docker might alter the rules again. Now you know where the problem is, it's up to you to integrate this along boot and Docker.

You might be interested in reading Docker's documentation about its use of iptables: Docker and iptables.

4
  • Thank you, it's probably caused by Docker which is not present neither on Desktop or VM, but apparently adding iptables -I FORWARD -i v-eth1 -j ACCEPT it's not enough Jan 17, 2020 at 17:55
  • can you run iptables-save -c again (or iptables-save -c | fgrep v-eth1 )? It's just to see if there are hit counters on the newly added rule (ie: there's not [0:0]). That will tell if at least this rule is ok or not (and then look elsewhere).
    – A.B
    Jan 17, 2020 at 18:07
  • 1
    silly me, I forgot the other way around... I'll edit the answer
    – A.B
    Jan 17, 2020 at 18:09
  • oh yes, added the second one and worked as a charm, thank you very much! Jan 17, 2020 at 20:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .