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 # # 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.