4km3/docker-dnsmasq

Conflicts with systemd-resolved

RyanRamchandar opened this issue · 7 comments

Sometimes when the device is restarted the dnsmasq container will be stuck in a reboot loop with the logs showing the following error:

dnsmasq: failed to create listening socket for port 53: Address in use

Reason - it's conflicting with systemd-resolved on port 53

see: https://unix.stackexchange.com/questions/304050/how-to-avoid-conflicts-between-dnsmasq-and-systemd-resolved

Host device: Ubuntu 18.04

uname -a
Linux umbrela-bridge 4.15.0-23-generic #25-Ubuntu SMP Wed May 23 17:59:52 UTC 2018

I guess you'd have to heed the advice of the Stack Overflow article and disable systemd-resolved listener or run the container on a different external port with something like -p 5353:53/tcp -p 5353:53/udp. But neither of these are really something we can solve in the container or this image.

Is there something you are proposing we change in this image or documentation to help with this?

There still exists an issue after disabling systemd-resolved or setting DNSStubListener=no since now DNS lookups don't seem to be happening at all. For example, I can ping 8.8.8.8 but not ping google.com.

Is the container missing a config like --listen-address, a mount like /etc/resolv.conf or something else to allow DNS lookups?

For starts, how are you running the container and what is the output of ss -ntu on the host? The dnsmasq inside the container listens on 0.0.0.0 TCP and UDP by default. Assuming the container is mapping the host ports correctly, I don't see why it wouldn't work. Might be worth checking iptables and the NAT table specifically to see where port 53 is being sent.

Okay I think I figured out what was wrong... I was running the container with --network=host:

docker run \
    --network=host \
    --cap-add=NET_ADMIN \
    -d \
    --restart=always \
    andyshinn/dnsmasq:2.78 \
    --interface=eth0 \
    --dhcp-range=10.10.10.11,10.10.10.254,12h \
    --log-facility=-

And switching to -p port mapping seems to have fixed it. Though I don't entirely know why. It might have something to do with the container network being isolated from the host now.

docker run \
    -p 53:53/tcp \
    -p 53:53/udp \
    --cap-add=NET_ADMIN \
    -d \
    --restart=always \
    andyshinn/dnsmasq:2.78 \
    --interface=eth0 \
    --dhcp-range=10.10.10.11,10.10.10.254,12h \
    --log-facility=-

Now the log seems happy, and ping google.com resolves.

# docker logs dnsmasq
dnsmasq[1]: started, version 2.78 cachesize 150
dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP no-conntrack ipset auth no-DNSSEC loop-detect inotify
dnsmasq-dhcp[1]: DHCP, IP range 10.10.10.11 -- 10.10.10.254, lease time 12h
dnsmasq[1]: reading /etc/resolv.conf
dnsmasq[1]: using nameserver 8.8.8.8#53
dnsmasq[1]: using nameserver 8.8.4.4#53
dnsmasq[1]: read /etc/hosts - 7 addresses

It is possible that --network=host needs something more than just --cap-add=NET_ADMIN to listen properly. You'd probably just have to do some debugging with ss or netstat to figure out what is listening where. The port mapping way should accomplish the same thing.

I'd be happy to accept a README pull request that gives this as an example of how to use the container as a host forwarder.

Thanks Andy.

An unfortunate result of using the port mapping instead of --network=host is that the container can no longer see the interfaces of the host and the following commands no longer work:

    --interface=eth0 \
    --dhcp-range=10.10.10.11,10.10.10.254,12h \