Local DNS cache and NetworkManager

Mon 11 October 2010

If you've used a debian-based distribution and delved into the network setup, you've probably seen something called 'resolvconf'. This is a tool that manages the local dnsmasq cache and /etc/resolv.conf file so that it stays sane when NetworkManager and other tools change the network configuration. NetworkManager handles /etc/resolv.conf on most Fedora desktop-style installations. For most purposes, this works really well, but if you're using your VPN DNS as your primary and your link is slow or a lot of requests are made at once, it can cause some serious slowdown. These instructions show you how to get dnsmasq/NetworkManager working together to make your life easier.

Configure dnsmasq

dnsmasq is a very powerful DNS caching server that can also function as a DHCP and TFTP server. If you've used a Linux-based router (Linksys WRT line, many Buffalo devices, etc) then you've already used dnsmasq. It's small, fast, easy to configure, and lightweight. It fits the bill perfectly as a small local caching daemon to run on a laptop to speed up DNS queries. To set it up, run the following:

yum install dnsmasq

Then, create the file /etc/dnsmasq.d/localcache.conf . It should contain:

strict-order
interface=lo
bind-interfaces

These settings make sure DNS servers are queried in order (strict-order) and only binds to localhost (interface and bind-interfaces). Next set dnsmasq to start on boot and start it up now:

chkconfig dnsmasq on
service dnsmasq start

By default, dnsmasq picks your servers out of /etc/resolv.conf to use for forwarding. You can test that it's working by looking up a host:

host www.google.com 127.0.0.1

If you get back a set of IPs for www.google.com, dnsmasq is up and working.

Configure NetworkManager

Every time NetworkManager changes the network configuration, it rewrites /etc/resolv.conf, where the other tools on your system look for DNS servers. We need to get it to add 127.0.0.1 as the first dns server every time. NetworkManager has a dispatcher that runs when network changes are made, and it calls scripts in /etc/NetworkManager/dispatcher.d/ . We can add a script here to update /etc/resolv.conf and make sure 127.0.0.1 (and therefore dnsmasq) is the primary DNS server. Create the file /etc/NetworkManager/dispatcher.d/00-localdns and add in:

1
2
3
4
#!/bin/bash
# Keep 127.0.0.1 as primary DNS (dnsmasq) and reload dnsmasq on network changes
sed -i 's/^\(search .*\)/\1\nnameserver 127.0.0.1/' /etc/resolv.conf
killall -HUP dnsmasq

Save this file and make it executable (0755 should be fine permissions). Restart NetworkManager and it should start making the changes when the network changes. What this does is insert the localhost DNS ahead of the other 'nameserver' entries, making it first in the list. The HUP to dnsmasq tells it to re-read /etc/resolv.conf (ignoring 127.0.0.1) to pull the new upstream DNS to use. This way, when you change to an internal DNS server, it does work.
This will save you a lot of trips over the VPN or a slow link when a page/app requests a lot of DNS lookups that are identical. I have seen firefox do this when using GSSAPI, among other situations. It sped up my apparent network speed greatly when all but the first request gets cached.
I have used this configuration while connected over wireless, ethernet, and tethered to my Android phone (shows up as usb0 ethernet device). Also works when I connect to the VPN (Openvpn and vpnc both work)

Category: Linux Tagged: dns linux network networkmanager

comments