Using the NetworkManager’s DNSMasq plugin

The dnsmasq plugin is a hidden gem of NetworkManager. When using the plugin, instead of using whatever DNS nameserver is doled out by DHCP, NetworkManager will configure a local copy of dnsmasq that can be customized.

You may ask, why would you want to do this? For me personally, I have two use cases:

First, on my laptop, I run a full OpenShift installation for testing purposes. In order to make this work, I really need to be able to add DNS records. I can run a local dnsmasq without NetworkManager, but this config is easier than managing my own.

Second, when I’m at home, I still want to use my home network’s DNS while on VPN. Many VPNs are configured to only route specific traffic through the VPN tunnel and leave my default route in place. This means I can access my local network’s printer and still connect to resources on the VPN.

This is very nice, as it means I can still access my network printer or listen to music from my media server while doing work. However, the VPN connection overwrites my resolv.conf with DNS servers from the VPN network. Therefore, my home network’s DNS is no longer accessible.

The dnsmasq plugin solves this by running a local dnsmasq server that is controlled by NetworkManager. My resolv.conf always points to localhost. For records defined locally (e.g. for my OpenShift Cluster), dnsmasq resolves these correctly. Using more advanced dnsmasq config, I can selectively forward requests for certain domains to specific servers (e.g. to always correctly resolve my home network hosts). And for all other requests, dnsmasq will forward to the DNS servers associated with my current network or VPN.

Here’s how to configure it in Fedora 29:

For some context, my domain on my laptop is called ‘laplab’ and my home domain is ‘.homelab’. At home my DNS server is 172.31.0.1. For DNS entries in laplab, most of those are defined in /etc/hosts. dnsmasq can then slurp them up. I also have some additional DNS entries defined for a wildcard DNS and some aliases.

Below are the five files that need to be added. The files in dnsmasq.d could be combined, but are split up to hopefully better show the example.

  • /etc/NetworkManager/conf.d/00-use-dnsmasq.conf
  • /etc/NetworkManager/dnsmasq.d/00-homelab.conf
  • /etc/NetworkManager/dnsmasq.d/01-laplab.conf
  • /etc/NetworkManager/dnsmasq.d/02-add-hosts.conf
  • /etc/hosts
# /etc/NetworkManager/conf.d/00-use-dnsmasq.conf
#
# This enabled the dnsmasq plugin.
[main]
dns=dnsmasq
# /etc/NetworkManager/dnsmasq.d/00-homelab.conf
#
# This file directs dnsmasq to forward any request to resolve
# names under the .homelab domain to 172.31.0.1, my 
# home DNS server.
server=/homelab/172.31.0.1
# /etc/NetworkManager/dnsmasq.d/01-laplab.conf
# This file sets up the local lablab domain and 
# defines some aliases and a wildcard.
local=/laplab/

# The below defines a Wildcard DNS Entry.
address=/.ose.laplab/192.168.101.125

# Below I define some host names.  I also pull in   
address=/openshift.laplab/192.168.101.120
address=/openshift-int.laplab/192.168.101.120
# /etc/NetworkManager/dnsmasq.d/02-add-hosts.conf
# By default, the plugin does not read from /etc/hosts.  
# This forces the plugin to slurp in the file.
#
# If you didn't want to write to the /etc/hosts file.  This could
# be pointed to another file.
#
addn-hosts=/etc/hosts
# /etc/hosts
#  
# The hostnames I define in that will be brought in and resolvable
# because of the config in the 02-add-hosts.conf file. 
#
127.0.0.1   localhost localhost.localdomain 
::1         localhost localhost.localdomain 

# Notice that my hosts be in the .laplab domain, like as configured 
# in 01-laplab.conf file
192.168.101.120  ose-lap-jumphost.laplab
192.168.101.128  ose-lap-node1.laplab

# Name not in .laplab will also get picked up.  So be careful 
# defining items here.
172.31.0.88     overwrite.public.domain.com

After all those files are in place, restart NetworkManager with systemctl restart NetworkManager. If everything is working right, you should see that your resolv.conf points to 127.0.0.1 and a new dnsmasq process spawned.

$ ps -ef | grep dnsmasq
dnsmasq   1835  1188  0 08:01 ?        00:00:00 /usr/sbin/dnsmasq --no-resolv 
--keep-in-foreground --no-hosts --bind-interfaces --pid-file=/var/run/NetworkManager/dnsmasq.pid 
--listen-address=127.0.0.1 --cache-size=400 --clear-on-reload --conf-file=/dev/null 
--proxy-dnssec --enable-dbus=org.freedesktop.NetworkManager.dnsmasq 
--conf-dir=/etc/NetworkManager/dnsmasq.d
$ cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 127.0.0.1
$ host ose-lap-jumphost.laplab
ose-lap-jumphost.laplab has address 192.168.101.120

This configuration will survive reboots and, in my testing, works with almost every network and VPN I’ve tried it with.

Fedora Project community

11 Comments

  1. What if you don’t rely on local DNS servers but mDNS? Would you still require solutions like this to properly resolve .local domains when using a VPN?

    • This is a good question and is worth experimenting with!

      I use DNS because I work with software that integrates with traditional DNS (e.g. Red Hat Satellite), so I need to run a real DNS server, so I’m kind of stuck in that regard.

  2. hey! clark! it’s good to see you posting to fedora magazine!

    hope all is well with you, man.

    • Mark! Long time no see. Glad to see you’re still involved with Fedora. I’m all good and hope you are, too 😀

      • mark mcintyre

        Definitely! Your post was a good one. As always, your insights into systems is very sharp! I look forward to more posts from you!

  3. Dmytro Nech

    Great article! Thanks! I really like ales too!

  4. phocean

    Interesting, but systemd-resolve does pretty the same automatically, out of the box.

    It handles DNS config per interface, which can be seen with systemd-resolve –status.

  5. Joao Rodrigues

    DNSMasq is an amazing piece of software.

    I use it at home on a Raspberry Pi for DHCP and DNS resolving.

    As a bonus, I also use the ad server list from pgl.yoyo.org/adservers to block ad servers

  6. Emilio

    hi,

    excellent article,
    I like the idea of the local configuration but I wanted to know if it could be added that the dnsmaq also solves external domains.
    ha, and these lines are repeated
    f everything is working right, you should see that your resolv.conf points to 127.0.0.1 and a new dnsmasq process spawned.

    best regards.

    • Yes. It will pick up anything in /etc/hosts. So if you have an entry like:

      10.10.10.1 service.example.com

      Then, it will resolve correctly. This is because of the addn-hosts=/etc/hosts option. This adds everything in the hosts file to dnsmasq, but that may be too much for some folks.

      Also, thanks for pointing out the typo…it’s been corrected.

  7. I really like this approach. I have added a libvirt conf file which points to my VMs running on a network local to my system. I can now use host names to log into my virtuals without having to find IP addresses.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

The opinions expressed on this website are those of each author, not of the author's employer or of Red Hat. Fedora Magazine aspires to publish all content under a Creative Commons license but may not be able to do so in all cases. You are responsible for ensuring that you have the necessary permission to reuse any work on this site. The Fedora logo is a trademark of Red Hat, Inc. Terms and Conditions

%d bloggers like this: