I want to get fast dns resolution with dnsmasq and keep the default systemd-resolved.
Looking for an elegant way to do this
55 Answers
I wanted to get fast dns resolution with dnsmasq and keep the default systemd-resolved/NetworkManager setup untouched for future use. Yes the huge dns caching of dnsmasq can improve browsing speed. Yes the goal was to keep the default featured dns setup of 18.04
- Install dnmasq
- Configure it (listen address and dns servers)
- Configure NetWorkManager for manual dns server address
- Check verify
1 - With sudo
apt-get -y install dnsmasq2 - With sudo
tee -a /etc/dnsmasq.conf << ENDdm
interface=lo
bind-interfaces
listen-address=127.0.0.1
# DNS server from OpenDns. Use yours...
server=208.67.222.222
server=208.67.220.220
ENDdm
systemctl restart dnsmasq
systemctl enable dnsmasq3 - With USER, configure NetworkManager
# Get NM first active profile name
NetManProfile=$(nmcli -t connection show --active | cut -f 01 -d ':')
# remove, if exists, current dns servers
nmcli con mod "$NetManProfile" ipv4.dns ""
# set 'manual' dns server
nmcli con mod "$NetManProfile" ipv4.ignore-auto-dns yes
# set dnsmasq as manually set dns server
nmcli con mod "$NetManProfile" ipv4.dns 127.0.0.1
# i also disabled ip6, do what u want
nmcli con mod "$NetManProfile" ipv6.method ignore
# reconnect to take effect
nmcli connection down "$NetManProfile"
nmcli connection up "$NetManProfile"4 - Check verify
- systemd-resolved listen on 127.0.0.53 as should by default
- dnsmasq listen on 127.0.0.1 as set in /etc/dnsmasq
- systemd-resolved took 127.0.0.1 from NetworkManager
0netstat -antup Proto Recv-Q Send-Q Adresse locale Adresse distante Etat PID/Program name tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 1036/dnsmasq tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 766/systemd-resolve cat /run/systemd/resolve/resolv.conf nameserver 127.0.0.1
I have a specific use case that works great. I run dnsmasq on my LAN router (an Ubuntu server machine, with no systemd-resolved), and let the LAN machines behind the router default to vanilla systemd-resolved DNS resolution. It's all possible and works elegantly, with a few tweaks to dnsmasq:
# Make clients that request IPs use this box for DNS
dhcp-option=option:router,192.168.0.1
domain=mydomain.lan
local=/
expand-hostsNow I can stand up a gazillion Ubuntu VMs inside my LAN and never have to fiddle with DNS any more - it just works.
The tweaks are required because systemd-resolved does not allow you to use "single-label" host names (with no dot in them), unlike dnsmasq and "classic DNS". Once you get dnsmasq to automatically extend LAN host names into FQDNs, everything is happy. This took me a LONG time to figure out, btw. These systemd-resolved issues 1 2 helped me crack the problem.
I tried to find a reasonable solution and looks that there are different approaches.
I wanted to stay at most within the distribution layout while keeping all business requirements fulfilled. This is what I collected around and tested to work on clean Ubuntu 18.04 and KDE Neon flavour:
# Install required package and reconfigure service plans (i.e. disablesystemd-resolved, enable dnsmasq
sudo apt-get install dnsmasq
sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
sudo systemctl enable dnsmasq
# These two lines should work on most environments, but .. :-) - so I kept them commented out for less experienced users
# Just add or change 'dns=dnsmasq' to your NetworkManager.conf to the section [main]
# and yes, the sed expression can be better :-)
#sudo cp /etc/NetworkManager/NetworkManager.conf /etc/NetworkManager/NetworkManager.conf.backup
#sudo bash -c 'cat /etc/NetworkManager/NetworkManager.conf.backup |sed -e "s/^dns=.*//"| sed -e "s/\[main\]/\[main\]\ndns=dnsmasq/" >/etc/NetworkManager/NetworkManager.conf'
# Restart NetworkManager to make the change above applied
sudo systemctl restart NetworkManager
# This removes the systemd resolv.conf link only if it has NetworkManager replacement :-)
ls /var/run/NetworkManager/resolv.conf && sudo rm /etc/resolv.conf
# And add NetworkManager's resolv.conf available for the system resolver
sudo ln -s /var/run/NetworkManager/resolv.conf /etc/resolv.conf(please note that the only general difference with the above answers is that the NetworkManager handle the dnsmasq DNS server assignments automatically
2As you know, Docker copy host /etc/resolv.conf file to containers but removing any local nameserver.
My solution to this problem is to keep using systemd-resolvd and NetworkManager but add dnsmasq and use it to "forward" Docker containers DNS queries to systemd-resolvd.
Step by step guide:
- Make /etc/resolv.conf a "real" file
sudo rm /etc/resolv.conf
sudo touch /etc/resolv.conf- Create file /etc/NetworkManager/conf.d/systemd-resolved-for-docker.conf to tell NetworkManager to inform systemd-resolvd but to not touch /etc/resolv.conf
[main]
# NetworkManager will push the DNS configuration to systemd-resolved
dns=systemd-resolved
# NetworkManager won’t ever write anything to /etc/resolv.conf
rc-manager=unmanaged- Install dnsmasq
sudo apt-get -y install dnsmasq- Configure dnsmasq in /etc/dnsmasq.conf for listening DNS queries comming from Docker and using systemd-resolvd name server
# Use interface docker0
interface=docker0
# Explicitly specify the address to listen on
listen-address=172.17.0.1
# Looks like docker0 interface is not available when dnsmasq service starts so it fails. This option makes dynamically created interfaces work in the same way as the default.
bind-dynamic
# Set systemd-resolved DNS server
server=127.0.0.53 - Edit /etc/resolv.conf to use systemd-resolvd nameserver (127.0.0.53) and the host IP (172.17.0.1) in Docker network
# systemd-resolvd name server
nameserver 127.0.0.53
# docker host ip
nameserver 172.17.0.1 - Restart services
sudo service network-manager restart
sudo service dnsmasq restart
sudo service docker restartFor more info see my post (in spanish)
Ubuntu 18.10
IMHO, if your going to be running dnsmasq, you should statically assign your ip address instead of getting it from dhcp. This way you can just disable systemd-resolved all together.
sudo apt-get install dnsmasq
sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
Manually assign your ip address, gateway, and assign the ip address to your machine as DNS.
configure /etc/dnsmasq.conf (really...RTFM --> man dnsmasq.conf)
sudo systemctl enable dnsmasq
- reboot
sudo systemctl status dnsmasq
point dhcp on your dhcp server to your shiny new dnsmasq server (..if yumpto)