1

I'm running an openvpn service in a docker container. Linked to this container are some other containers, including a gitlab container. I want to be able to reach this gitlab container using its container name as host from VPN clients. I like the idea to use docker networks to manage what containers will be reachable through VPN.

Since docker has its embedded DNS feature, I think this should be possible by forwarding DNS packets to it (127.0.0.11:53), so I can use the VPN server's address as name server on the clients.

At least, executed locally in the OVPN container, it seems like there is a working DNS service:

bash-4.3# nslookup gitlab 127.0.0.11             
Server:    127.0.0.11
Address 1: 127.0.0.11

Name:      gitlab
Address 1: 172.19.0.2 gitlab_gitlab_1.gitlab_default

However, my iptables routes won't work:

iptables -t nat -I PREROUTING 1 -p udp -s 192.168.255.0/24 --dport 53 -j DNAT --to-destination 127.0.0.11:53
iptables -t nat -I PREROUTING 1 -p tcp -s 192.168.255.0/24 --dport 53 -j DNAT --to-destination 127.0.0.11:53

Where 192.168.255.0/24 is my VPN net.

This is the entire iptables list:

bash-4.3# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  192.168.255.0/24     anywhere             tcp dpt:domain to:127.0.0.11:53
DNAT       udp  --  192.168.255.0/24     anywhere             udp dpt:domain to:127.0.0.11:53

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER_OUTPUT  all  --  anywhere             127.0.0.11          

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER_POSTROUTING  all  --  anywhere             127.0.0.11          
MASQUERADE  all  --  192.168.255.0/24     anywhere            

Chain DOCKER_OUTPUT (1 references)
target     prot opt source               destination         
DNAT       tcp  --  anywhere             127.0.0.11           tcp dpt:domain to:127.0.0.11:36429
DNAT       udp  --  anywhere             127.0.0.11           udp dpt:domain to:127.0.0.11:33172

Chain DOCKER_POSTROUTING (1 references)
target     prot opt source               destination         
SNAT       tcp  --  127.0.0.11           anywhere             tcp spt:36429 to::53
SNAT       udp  --  127.0.0.11           anywhere             udp  spt:33172 to::53

All rules except of the two mentioned above are created automatically by docker. What am I doing wrong?

2

The destination port of dockers embedded DNS change with every start (to:127.0.0.11:36429). Try to dispatch the incoming traffic to the DOCKER_OUTPUT rule:

iptables -t nat -A PREROUTING -p udp --dport 53 -j DOCKER_OUTPUT
iptables -t nat -A PREROUTING -p tcp --dport 53 -j DOCKER_OUTPUT

To forward the response to the original requester add the masquerade rule to any package that had its origin outside your localhost:

iptables -t nat -A POSTROUTING ! -s 127.0.0.1 -p udp --dport 53 -j MASQUERADE
iptables -t nat -A POSTROUTING ! -s 127.0.0.1 -p tcp --dport 53 -j MASQUERADE
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.