Skip to content

Instantly share code, notes, and snippets.

@madumlao
Created November 15, 2018 05:37
Show Gist options
  • Save madumlao/68fd4a32e97321e16549287b97f2d1f4 to your computer and use it in GitHub Desktop.
Save madumlao/68fd4a32e97321e16549287b97f2d1f4 to your computer and use it in GitHub Desktop.
dnsmasq workaround to prevent systemd-resolved from overwriting my DNS
#!/bin/bash
# place as your /etc/NetworkManager/dispatcher.d/dnsmasq and make executable
INTERFACE=$1
ACTION=$2
DNSMASQ_RESOLVCONF=/run/dnsmasq/resolv.conf
SYSTEMD_RESOLVCONF=/run/resolvconf/interface/systemd-resolved
if [ "$ACTION" = "up" ]; then
(
if [ "$DHCP4_DOMAIN_NAME" ]; then
echo search $DHCP4_DOMAIN_NAME
fi
for ns in $IP4_NAMESERVERS $DHCP4_DOMAIN_NAME_SERVERS $IP6_NAMESERVERS $DHCP6_DOMAIN_NAME_SERVERS; do
echo nameserver $ns
done
) | tee $DNSMASQ_RESOLVCONF $SYSTEMD_RESOLVCONF >/dev/null
fi
@madumlao
Copy link
Author

madumlao commented Nov 15, 2018

Under Ubuntu 18.04, if you want advanced local DNS behavior, you may opt to disable the default systemd-resolved and install/customize/enable dnsmasq. However, naively doing so leads to a problem: dnsmasq WILL look for the systemd resolver, which, since you disabled it, it won't find, thus your system's Internet breaks. Manually editing your resolv.conf (either /etc/resolv.conf or /run/dnsmasq/resolv.conf) will not help as it will be overwritten on each restart / reconnection.

This is because the default dnsmasq behavior is to look for DNS entries under /run/resolvconf/interface and basically merge / create a resolv.conf file from there, which dnsmasq can then read. The problem, however, is that systemd installs a record there pointing to its own resolver, 127.0.0.53, which remains there even if systemd-resolved is off. In other words, every restart, network change, etc will cause resolvconf to overwrite your dnsmasq resolver entries with the systemd entry.

This is not systemd's fault per se, but an inevitable consequence of having multiple local resolvers on your machine, as each one basically wants to tell "all other programs" to use IT as the resolver. This would be helped greatly if systemd removes the resolvconf entry when systemd-resolved itself is down (though I'm not sure what creates the resolvconf entry).

Above is my workaround to get advanced behavior using dnsmasq after disabling systemd-resolved. It is a network-manager dispatcher script that overwrites the systemd-resolved entry upon network start. I discovered this issue while disabling systemd-resolved as noted here (systemd/systemd#10779).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment