mirror of
https://github.com/hwdsl2/docker-ipsec-vpn-server.git
synced 2026-04-26 10:05:48 +03:00
[GH-ISSUE #310] Return traffic from local DNS container not traversing VPN tunnel #286
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @diamondsw on GitHub (Sep 20, 2022).
Original GitHub issue: https://github.com/hwdsl2/docker-ipsec-vpn-server/issues/310
Summary: VPN and DNS containers on the same host; both work as expected independently, but DNS return traffic does not reach VPN clients. Seems like a docker networking issue, but I'm at my wits' end.
This is going to be a bit of a weird one; thank you for looking! Despite the amount of DNS detail, I swear it's not a DNS issue. The goal here is to provide an internal DNS server for private hostnames on the remote network. While this is my first time using this container, I've configured (painfully) several IPSEC/L2TP VPNs before, with mobileconfig, site-to-site tunnels, and private DNS. First time I've ever seen something quite like this, and I'm completely stumped.
Checklist
I don't know on that last one! If anything, it seems like a very weird Docker network thing.
Describe the issue
After establishing a VPN connection to the ipsec-vpn-server container, return traffic from a dnsmasq container on the same host does not arrive.
More detail below, but in short:
That's the weirdest thing - the DNS container works, and even sees the requests over the VPN and responds - but the client never gets the traffic back. Other protocols are working fine. The only difference I can see is this is traffic between containers, whereas ping, ssh, etc are all either to the host or headed outside the network.
Network details:
To Reproduce
Steps to reproduce the behavior:
Dockerfile
docker-compose.yml
dnsmasq.conf
Note here that I have specified an interface to listen to, which turns off the dnsmasq '--local-service' option.
hosts
(Note, I have changed the domain names to remove private information.)
Expected behavior
DNS responses should arrive back to the requestor (i.e. the VPN client machine).
Logs
Check logs and VPN status, and add error logs to help explain the problem, if applicable.
DNSmasq log when VPN connected (with a LOT of Apple services connection attempts cut out):
My dig attempts show up in the dnsmasq log as these lines:
Nothing much to show on the VPN side - it's happy:
Server (please complete the following information)
Client (please complete the following information)
Client (please complete the following information)
Additional context
Connecting to the DNS over the internet (restricted to allow my IP only; no open resolvers):
Connecting to the DNS from the server itself (i.e. connecting to localhost):
Connecting to the DNS once connected to the VPN (both macOS DNS resolution and dig):
connect vpn
disconnect vpn
Nothing. Weird!
@letoams commented on GitHub (Sep 21, 2022):
Two common issues could be affecting you
One is that the ip range you assign to the vpn clients isn’t fully routed to it from the dns server and the reply packet goes out the wrong way via a default gateway bypassing the ipsec server.
Two is that somewhere this reply packet is getting NATed and then no longer matches the ipsec policies and is getting dropped.
Sent using a virtual keyboard on a phone
@diamondsw commented on GitHub (Sep 21, 2022):
It looks like the reply is reaching the IPSEC container, but being dropped since it's appearing from a docker bridge subnet rather than the host IP as expected. The odd thing is 172.24.0.1 is the gateway IP of the IPSEC container, not the DNS container.
Although I just realized this may not be a valid test since the source IP of the DNS request is the VPN server, not a VPN client. Man, too many routing layers are involved here.
(Oh, and my apologies for not seeing the docker-specific repo!)
@diamondsw commented on GitHub (Sep 22, 2022):
Still honestly not sure if this is a bug, or just life with Docker container/host routing - I don't know if there's anything you can do to change how this is being networked between containers. So I'll close the issue, but here's my solution in case anyone else stumbles across this.
Given that this appears to be a complex routing issue between Docker containers, host networking, etc, I took the path of least resistance and removed the host from the equation. I created an external network:
subspace\docker-compose.yml
And then placed the DNS container on it:
And the VPN container as well:
And finally, set the VPN configuration to use the new IP address:
Regenerated the VPN container, reloaded the VPN profiles and finally, all is working.
@hwdsl2 commented on GitHub (Sep 22, 2022):
@diamondsw Thank you for sharing your solution with us.
@atdimitrov commented on GitHub (Feb 11, 2023):
@diamondsw Thank you for sharing your research and your solution on this.
I had the exact same setup as you did - DNS and VPN servers running on the same host machine in the default bridge network and of course I had the exact same problem. However, I don't think the problem is with the routing - the response seems to get back to the machine that initiates the
digcommand because of this log:reply from unexpected source: 172.24.0.1#53, expected 10.2.1.8#53. It looks like it is a security feature of the DNS resolvers and the NAT is tripping it.So the main problem seems to be having the DNS server in a bridge network. If other containers in the same bridge network try to use the DNS with the host IP they would fail the same way. The way I solved it is to put the DNS server on the host network avoiding going through NAT. Another solution that should work would be to use the bridge network IP instead of the host IP. Essentially, the same solution you found without the additional network.
I'm by no means a Docker networking expert but I don't think there's anything that has to be done in the VPN image, nor it has to do anything with it.