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?
Best Answer
The destination port of dockers embedded DNS change with every start (
to:127.0.0.11:36429
). Try to dispatch the incoming traffic to theDOCKER_OUTPUT
rule:To forward the response to the original requester add the masquerade rule to any package that had its origin outside your
localhost
: