Iptables docker and VPN

Hi,

I’m having an issue with docker and iptables rules. I’m trying to allow few containers to access some servers behind VPN with no luck…

I’m running on Ubuntu 20.04 and iptables. The docker host is connected office’s VPN using Shrew Soft with custom routes.

This is my routing table:

default via 192.168.10.1 dev enp4s0 proto static metric 100 
10.10.10.0/24 via 10.100.63.12 dev tap0 proto static 
10.10.11.0/24 via 10.100.63.12 dev tap0 proto static 
10.10.12.0/24 via 10.100.63.12 dev tap0 proto static 
10.10.13.0/24 via 10.100.63.12 dev tap0 proto static 
10.10.110.0/24 via 10.100.63.12 dev tap0 proto static 
10.10.112.0/24 via 10.100.63.12 dev tap0 proto static 
10.10.113.0/24 via 10.100.63.12 dev tap0 proto static 
10.18.64.0/24 via 10.100.63.12 dev tap0 proto static 
10.18.102.0/24 via 10.100.63.12 dev tap0 proto static 
10.100.63.0/24 dev tap0 proto kernel scope link src 10.100.63.12 
10.100.65.0/24 via 10.100.63.12 dev tap0 proto static 
10.100.165.0/24 via 10.100.63.12 dev tap0 proto static 
[VPN_PUBLIC_IP] via 192.168.10.1 dev enp4s0 proto static 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 
172.18.0.0/16 dev br-fa7636971f2b proto kernel scope link src 172.18.0.1 linkdown 
172.19.0.0/16 dev br-b1ffa37c0bf8 proto kernel scope link src 172.19.0.1 
172.23.0.0/16 dev br-308704a0f729 proto kernel scope link src 172.23.0.1 linkdown 
192.168.10.0/24 dev enp4s0 proto kernel scope link src 192.168.10.20 metric 100 
192.168.12.0/24 dev virbr1 proto kernel scope link src 192.168.12.1 linkdown 
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown 

iptables -S output

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-USER
-N DOCKER-ISOLATION-STAGE-2
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o br-b1ffa37c0bf8 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-b1ffa37c0bf8 -j DOCKER
-A FORWARD -i br-b1ffa37c0bf8 ! -o br-b1ffa37c0bf8 -j ACCEPT
-A FORWARD -i br-b1ffa37c0bf8 -o br-b1ffa37c0bf8 -j ACCEPT
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A FORWARD -o br-fa7636971f2b -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-fa7636971f2b -j DOCKER
-A FORWARD -i br-fa7636971f2b ! -o br-fa7636971f2b -j ACCEPT
-A FORWARD -i br-fa7636971f2b -o br-fa7636971f2b -j ACCEPT
-A FORWARD -o br-308704a0f729 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-308704a0f729 -j DOCKER
-A FORWARD -i br-308704a0f729 ! -o br-308704a0f729 -j ACCEPT
-A FORWARD -i br-308704a0f729 -o br-308704a0f729 -j ACCEPT
**-A FORWARD -i tap+ -j ACCEPT**
-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 -i br-b1ffa37c0bf8 -o br-b1ffa37c0bf8 -p tcp -m tcp --dport 9000 -j ACCEPT
-A DOCKER -d 172.19.0.4/32 ! -i br-b1ffa37c0bf8 -o br-b1ffa37c0bf8 -p tcp -m tcp --dport 9000 -j ACCEPT
-A DOCKER -d 172.19.0.5/32 ! -i br-b1ffa37c0bf8 -o br-b1ffa37c0bf8 -p tcp -m tcp --dport 80 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i br-b1ffa37c0bf8 ! -o br-b1ffa37c0bf8 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i br-fa7636971f2b ! -o br-fa7636971f2b -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i br-308704a0f729 ! -o br-308704a0f729 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-USER -j ACCEPT
**-A DOCKER-USER -i docker0 -o enp4s0 -j ACCEPT**
**-A DOCKER-USER -i enp4s0 -o docker0 -j ACCEPT**
**-A DOCKER-USER -i enp4s0 -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT**
-A DOCKER-USER -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o br-b1ffa37c0bf8 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o br-fa7636971f2b -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o br-308704a0f729 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN

iptables -S -t nat

-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P POSTROUTING ACCEPT
-P OUTPUT ACCEPT
-N LIBVIRT_PRT
-N DOCKER
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.19.0.0/16 ! -o br-b1ffa37c0bf8 -j MASQUERADE
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.18.0.0/16 ! -o br-fa7636971f2b -j MASQUERADE
-A POSTROUTING -s 172.23.0.0/16 ! -o br-308704a0f729 -j MASQUERADE
-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A POSTROUTING -s 172.19.0.4/32 -d 172.19.0.4/32 -p tcp -m tcp --dport 9000 -j MASQUERADE
-A POSTROUTING -s 172.19.0.5/32 -d 172.19.0.5/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A LIBVIRT_PRT -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
-A LIBVIRT_PRT -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
-A LIBVIRT_PRT -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE
-A DOCKER -i br-b1ffa37c0bf8 -j RETURN
-A DOCKER -i docker0 -j RETURN
-A DOCKER -i br-fa7636971f2b -j RETURN
-A DOCKER -i br-308704a0f729 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 5001 -j DNAT --to-destination 172.17.0.2:80
-A DOCKER ! -i br-b1ffa37c0bf8 -p tcp -m tcp --dport 9000 -j DNAT --to-destination 172.19.0.4:9000
-A DOCKER ! -i br-b1ffa37c0bf8 -p tcp -m tcp --dport 8004 -j DNAT --to-destination 172.19.0.5:80

I tried to allow tracking for docker0 and my NIC (enp4s0)

-A DOCKER-USER -i docker0 -o enp4s0 -j ACCEPT
-A DOCKER-USER -i enp4s0 -o docker0 -j ACCEPT
-A DOCKER-USER -i enp4s0 -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j 

using tcpdump, the container is actually able to ping the server behind the VPN and the latter is echoing back the reply to tap0 IP and it stops there