How to get networkmanager to configure domain specific name servers with openresolv + dnsmasq

dnsdnsmasqnetworkmanager

I often connect to multiple network simultaneously. Each of these networks provide nameserver configuration via dhcp. E.g. Network 1: (eth0):

domain company1.corp #
nameserver 192.168.0.253
nameserver 192.168.0.254

Network 2 (tun0):

domain company2.corp #
nameserver 10.102.204.51
nameserver 10.102.208.51

# Names changed

When connected to both networks simultaneously:

# resolv.conf from NetworkManager
domain company1.corp, company2.corp
nameserver 192.168.0.253
nameserver 192.168.0.254
nameserver 10.102.204.51
# NOTE: the libc resolver may not support more than 3 nameservers.
# The nameservers listed below may not be recognized.
nameserver 10.102.208.51

Resolving service.company2.corp does not work because the first name server only knows about company1.corp names.

So inspired by this article, I've setup openresolv (a resolvconf implementation) configuring a local dnsmasq service on my Arch linux install.

If I configure the nameservers manually using resolvconf:

# resolvconf -d NetworkManager
# echo "domain company1.corp
nameserver 192.168.0.253
nameserver 192.168.0.254
" | resolvconf -a eth0
# echo "domain company2.corp
nameserver 10.102.204.51
nameserver 10.102.208.51
" | resolvconf -a tun0

Then I am able to resolve names from both company1.corp and company2.corp (the local dnsmasq server handles this.)

Note that after the manual config, resolveconf -l shows the 2 configurations separately:

~ # resolvconf -l
# resolv.conf from tun0
domain company2.corp
nameserver 10.102.204.51
nameserver 10.102.208.51

# resolv.conf from eth0
domain company1.corp
nameserver 192.168.0.253
nameserver 192.168.0.254

However, when letting network manager do the configuration, the 2 configurations are not separate, as the would be if network manager was writing to /etc/resolve.conf

~ # resolvconf -l
# resolv.conf from NetworkManager
# Generated by NetworkManager
domain company1.corp, company2.corp
nameserver 192.168.0.253
nameserver 192.168.0.254
nameserver 10.102.204.51
# NOTE: the libc resolver may not support more than 3 nameservers.
# The nameservers listed below may not be recognized.
nameserver 10.102.208.51

My question is how can I get network manager to correctly call resolveconf so the the name servers for each interface are registered separately. (Unfortunately googling for this is useless because google thinks that "resolveconf" == "resolve.conf")

Best Answer

NetworkManager has the functionality to manage a local dnsmasq server built in. It is not necessary to use resolvconf/openresolv to do this.

To enable this:

  • Disable the resolvconf/openresolv dnsmasq configuration if it was previously enabled, and ensure there are no instances of dnsmasq running.
  • Ensure dnsmasq is installed
  • Add dns=dnsmasq to /etc/NetworkManager/NetworkManager.conf.
  • Restart NetworkManager

Once you have done this, you will see that NetworkManager has started a dnsmasq process:

$ pgrep dnsmasq -fl
1697 /usr/bin/dnsmasq --no-resolv --keep-in-foreground --no-hosts --bind-interfaces --pid-file=/var/run/nm-dns-dnsmasq.pid --listen-address=127.0.0.1 --conf-file=/var/run/nm-dns-dnsmasq.conf --cache-size=400 --proxy-dnssec

/etc/resolve.conf should be pointing to the local dnsmasq instance:

$ cat /etc/resolv.conf
# Generated by NetworkManager
domain company1.corp
search company1.corp
nameserver 127.0.0.1

and we can see what servers dnsmasq is using:

# cat /var/run/nm-dns-dnsmasq.conf 
server=/company2.corp/10.102.208.51
server=/10.in-addr.arpa/10.102.208.51
server=192.168.1.244
server=192.168.1.239
Related Question