I had a weird problem recently that I solved, and it was mostly due to my mis-configuring of my Ubuntu laptop. I finally figured it out when setting up my new Dell XPS Developer Edition laptop, so I wanted to share.

The situation: I would go to my local library and couldn’t connect to their wireless internet. But if I disabled dnsmasq and restarted the network-manager service, it would work fine.

What I didn’t realize was happening is dnsmasq was taking over local DNS control from the systemd-resolved service. What is systemd-resolved and why is it important? The man page reads:

systemd-resolved is a system service that provides network name resolution to local applications. It implements a caching and validating DNS/DNSSEC stub resolver, as well as an LLMNR and MulticastDNS resolver and responder.

My library uses a captive portal. When you connect to their network it brings up a page that makes you agree before actually being able to use the network. systemd-resolved has all the know-how to handle that – dnsmasq doesn’t.

I love dnsmasq and don’t want to lose it’s functionality. I want to use both the system resolved (pronounced resolve-D) and dnsmasq. Here’s how to have your cake and eat it too.

DNSMasq via NetworkManager

To use the dnsmasq plugin that is installed with NetworkManager, I just needed to add the bold line to the main section of NetworkManager.conf via sudo vi /etc/NetworkManager/NetworkManager.conf

[main]
plugins=ifupdown,keyfile
dns=dnsmasq

Local sites

This section is optional, I do it to create a local domain name that only exists on my local computer for web development purposes. Anything that ends in .test resolves to localhost. Also, I use a loopback IP address for my .test addresses in case I need to access them through a virtual machine (usually to test IE).

Then add this file, by running sudo vi /etc/NetworkManager/dnsmasq.d/01-dot-test.conf

address=/test/10.254.254.254

Why do I use .test? See this post.

Chaining DNSMasq & resolveconf

To really make things work I wanted to keep both resolved and dnsmasq working together in tandem. I found the answer in this thread on ubuntuforums.org. resolved just needs to know to use dnsmasq as its upstream provider. You can do this by adding the following bold lines via sudo vi /etc/systemd/resolved.conf

[Resolve]
DNS=127.0.1.1
FallbackDNS=127.0.1.1
Domains=lan local test

The Domains line is present in Ubuntu 18.04 as lan local and it works like that. In 20.04 it is not present, but needs to be there with your dnsmasq domain(s) (test in my case) in order to pass queries for that domain to dnsmasq upstream – otherwise resolved ignores them.

You can restart network-manager and systemd-resolved services to apply your changes, or simply reboot your system.

Test it out

To make sure that it’s working, first check your resolv.conf file by running cat /etc/resolv.conf

# This file is managed by man:systemd-resolved(8). Do not edit.
...
# Run "systemd-resolve --status" to see details about the uplink DNS servers
# currently in use.
...

nameserver 127.0.0.53
...

This file should be managed by resolved and use the resolved IP of 127.0.0.53. Then use the hint given in that file to check the upstream server: systemd-resolve --status

Global
         DNS Servers: 127.0.1.1
          DNSSEC NTA: 10.in-addr.arpa
                      ...
                      corp
                      d.f.ip6.arpa
                      home
                      internal
                      intranet
                      lan
                      local
                      private
                      test

Ping a couple of domain names, both local and remote, and you should be good to go!

2 thoughts on “Chaining DNSMasq and resolved

  1. Pingback: XPS 13 Developer Edition Settings - Justin Foell

  2. Pingback: Improved Connection Checking in Ubuntu - Justin Foell

Leave a Reply