I'm struggling with this problem for two days.
Assumptions:
- Docker network (and interface) named docknet type bridge subnet 172.18.0.0/16
- Two interfaces eth0 (Gateway IP: 192.168.1.1, Interface Static IP: 192.168.1.100) and eth1 (Gateway IP:192.168.2.1, Interface Static IP: 192.168.2.100)
- Default routing goes through eth0
What I want:
- Outgoing traffic from container attached to docknet must go to eth1
What I tried:
- Default iptable rule created by docker left untouched:
-A POSTROUTING -s 172.18.0.0/16 ! -o docknet -j MASQUERADE
- My rules:
iptables -t mangle -I PREROUTING -s 172.18.0.0/16 -j MARK --set-mark 1
ip rule add from all fwmark 1 table 2
Where table 2 is:
default via 192.168.2.1 dev eth1 proto static
With this setup when I try to ping 8.8.8.8 from a container (172.18.0.2) attached to docknet the following happens:
- 172.18.0.2 gets translated to 192.168.2.1
- the packet goes through eth1
- the packet returns to eth1 with src addr 8.8.8.8 and dst 192.168.2.1
from here a reverse translation from 192.168.2.1 to 172.168.0.2 should happen but running tcpdump -i any host 8.8.8.8
there is not trace about this translation
I checked out also conntrack -L and this is the result:
icmp 1 29 src=172.18.0.2 dst=8.8.8.8 type=8 code=0 id=9 src=8.8.8.8 dst=192.168.2.1 type=0 code=0 id=9 mark=0 use=1
Useful info:
- eth1 is actually a 4G usb dongle
- ip forwarding is active
curl --interface eth1 ipinfo.io
works as expected
EDIT:
output from ip -d link show eth1
eth1: mtu 1500 qdisc fq_codel state UNKNOWN mode DEFAULT group default qlen 1000 link/ether 00:b0:d6:00:00:00 brd ff:ff:ff:ff:ff:ff promiscuity 0 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535