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
sudo vi /etc/NetworkManager/NetworkManager.conf
[main] plugins=ifupdown,keyfile dns=dnsmasq
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
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
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
# 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:
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!