DNSMasq, the Pint-Sized Super Dæmon!
I've always been a fan of putting aftermarket firmware on consumer-grade routers. Whether it's DD-WRT, Tomato, OpenWRT or whatever your favorite flavor of "better than stock" firmware might be, it just makes economic sense. Unfortunately, my routing needs have surpassed my trusty Linksys router. Although I could certainly buy a several-hundred-dollar, business-class router, I really don't like spending money like that. Thankfully, I found an incredible little router (the EdgeRouter Lite) that can route a million packets per second and has three gigabit Ethernet ports. So far, it's an incredible router, but that's all it does—route. Which brings me to the point of this article.
I've always used the DHCP and DNS server built in to DD-WRT to serve my network. I like having those two services tied to the router, because if every other server on my network fails, I still can get on-line. I figure the next best thing is to have a Raspberry Pi dedicated to those services. Because all my RPi devices currently are attached to televisions around the house (running XBMC), I decided to enlist the Cubox computer I reviewed in November 2013 (Figure 1). It's been sitting on my shelf collecting dust, and I'd rather have it do something useful.
Figure 1. The Cubox is more powerful than a Raspberry Pi, but even an RPi is more power than DNSMasq requires!
Although the Cubox certainly is powerful enough to run BIND and the ISC DHCP server, that's really overkill for my network. Plus, BIND really annoys me with its serial-number incrementation and such whenever an update is made. It wasn't until I started to research alternate DNS servers that I realized just how powerful DNSMasq can be. Plus, the way it works is simplicity at its finest. First, let's look at its features:
Extremely small memory and CPU footprint: I knew this was the case, because it's the program that runs on Linux-based consumer routers where memory and CPU are at a premium.
DNS server: DNSMasq approaches DNS in a different way from the traditional BIND dæmon. It doesn't offer the complexity of domain transfers, master/slave relationships and so on. It does offer extremely simple and highly configurable options that are, in my opinion, far more useful in a small- to medium-size network. It even does reverse DNS (PTR records) automatically! (More on those details later.)
DHCP server: where the DNS portion of DNSMasq lacks in certain advanced features, the DHCP services offered actually are extremely robust. Most routers running firmware like DD-WRT don't offer a Web interface to the advanced features DNSMasq provides, but it rivals and even surpasses some of the standalone DHCP servers.
TFTP server: working in perfect tandem with the advanced features of DHCP, DNSMasq even offers a built-in TFTP server for things like booting thin clients or sending configuration files.
A single configuration file: it's possible to use multiple configuration files, and I even recommend it for clarity's sake. In the end, however, DNSMasq requires you to edit only a single configuration file to manage all of its powerful services. That configuration file also is very well commented, which makes using it much nicer.
DNSMasq has been around for a very long time. Installing it on any Linux operating system should be as simple as searching for it in your distribution's package management system. On Debian-based systems that would mean something like:
sudo apt-get install dnsmasq
Or, on a Red Hat/CentOS system:
yum install dnsmasq (as root)
The configuration file (there's just one!) is usually stored at /etc/dnsmasq.conf, and like I mentioned earlier, it is very well commented. Figuring out even the most advanced features is usually as easy as reading the configuration file and un-commenting those directives you want to enable. There are even examples for those directives that require you to enter information specific to your environment.
After the dnsmasq package is installed, it most likely will get started automatically. From that point on, any time you make changes to the configuration (or make changes to the /etc/hosts file), you'll need to restart the service or send an HUP signal to the dæmon. I recommend using the init script to do that:
sudo service dnsmasq restart
But, if your system doesn't have the init service set up for dnsmasq, you can issue an HUP signal by typing something like this:
sudo kill -HUP $(pidof dnsmasq)
This will find the PID (process ID) and send the signal to reload its configuration files. Either way should work, but the init script will give you more feedback if there are errors.
First Up: DNS
Of all the features DNSMasq offers, I find its DNS services to be the most useful and awesome. You get the full functionality of your upstream DNS server (usually provided by your ISP), while seamlessly integrating DNS records for you own network. To accomplish that "split DNS"-type setup with BIND, you need to create a fake DNS master file, and even then you run into problems if you are missing a DNS name in your local master file, because BIND won't query another server by default for records it thinks it's in charge of serving. DNSMasq, on the other hand, follows a very simple procedure when it receives a request. Figure 2 shows that process.
Figure 2. DNSMasq makes DNS queries simple, flexible and highly configurable.
For my purposes, this means I can put a single entry into my server's /etc/hosts file for something like "server.brainofshawn.com", and DNSMasq will return the IP address in the /etc/hosts file. If a host queries DNSMask for an entry not in the server's /etc/hosts file, www.brainofshawn.com for instance, it will query the upstream DNS server and return the live IP for my Web host. DNSMasq makes a split DNS scenario extremely easy to maintain, and because it uses the server's /etc/hosts file, it's simple to modify entries.
My personal favorite feature of DNSMasq's DNS service, however, is that it supports round-robin load balancing. This isn't something that normally works with an /etc/hosts file entry, but with DNSMasq, it does. Say you have two entries in your /etc/hosts file like this:
192.168.1.10 webserver.example.com 192.168.1.11 webserver.example.com
On a regular system (that is, if you put it in your client's /etc/hosts file), the DNS query always will return 192.168.1.10 first. DNSMasq, on the other hand, will see those two entries and mix up their order every time it's queried. So instead of 192.168.1.10 being the first IP, half of the time, it will return 192.168.1.11 as the first IP. It's a very rudimentary form of load balancing, but it's a feature most people don't know exists!
Finally, DNSMasq automatically will create and serve reverse DNS responses based on entries found in the server's /etc/hosts file. In the previous example, running the command:
dig -x 192.168.1.10
would get the response "webserver.example.com" as the reverse DNS lookup. If you have multiple DNS entries for a single IP address, DNSMasq uses the first entry as the reverse DNS response. So if you have a line like this in your server's /etc/hosts file:
192.168.1.15 www.example.com mail.example.com ftp.example.com
Any regular DNS queries for www.example.com, mail.example.com or ftp.example.com will get answered with "192.168.1.15", but a reverse DNS lookup on 192.168.1.15 will get the single response "www.example.com".
DNSMasq is so flexible and feature-rich, it's hard to find a reason not to use it. Sure, there are valid reasons for using a more robust DNS server like BIND, but for most small to medium networks, DNSMasq is far more appropriate and much, much simpler.
It's possible to use DNSMasq for DNS only and disable the DHCP services it offers. Much like DNS, however, the simplicity and power offered by DNSMasq makes it a perfect candidate for small- to medium-sized networks. It supports both dynamic ranges for automatic IP assignment and static reservations based on the MAC address of computers on your network. Plus, since it also acts as the DNS server for your network, it has a really great hostname-DNS integration for computers connected to your network that may not have a DNS entry. How does that work? Figure 3 shows the modified method used when the DNS server receives a query if it's also serving as a DHCP server. (The extra step is shown as the orange-colored diamond in the flowchart.)
Figure 3. If you use DHCP, it automatically integrates into your DNS system—awesome for finding dynamically assigned IPs!
Basically, if your friend brings a laptop to your house and connects to your network, when it requests a DHCP address, it tells the DNSMasq server its hostname. From that point on, until the lease expires, any DNS queries the server receives for that hostname will be returned as the IP it assigned via DHCP. This is very convenient if you have a computer connected to your network whose hostname you know, but it gets a dynamically assigned IP address. In my house, I have a Hackintosh computer that just gets a random IP assigned via DNSMasq's DHCP server. Figure 4 shows what happens when I ping the name "hackintosh" on my network. Even though it isn't listed in any of the server's configuration files, since it handles DHCP, it creates a DNS entry on the fly.
Figure 4. There are no DNS entries anywhere for my Hackintosh, but thanks to DNSMasq, it's pingable via its hostname.
Static DHCP entries can be entered in the single configuration file using this format:
dhcp-host=90:fb:a6:86:0d:60,xbmc-livingroom,192.168.1.20 dhcp-host=b8:27:eb:e3:4c:5f,xbmc-familyroom,192.168.1.21 dhcp-host=b8:27:eb:16:d9:08,xbmc-masterbedroom,192.168.1.22 dhcp-host=00:1b:a9:fa:98:a9,officelaser,192.168.1.100 dhcp-host=04:46:65:d4:e8:c9,birdcam,192.168.1.201
It's also valid to leave the hostname out of the static declaration, but adding it to the DHCP reservation adds it to the DNS server's list of known addresses, even if the client itself doesn't tell the DHCP server its hostname. You also could just add the hostname to your DNSMasq server's /etc/hosts file, but I prefer to make my static DHCP entries with hostnames, so I can tell at a glance what computer the reservation is for.
And If That's Not Enough...
The above scenarios are all I use DNSMasq for on my local network. It's more incredible than any DHCP/DNS combination I've ever used before, including the Windows and OS X server-based services I've used in large networks. It does provide even more services, however, for those folks needing them.
The TFTP server can be activated via configuration file to serve boot files, configuration files or any other TFTP files you might need served on your network. The service integrates flawlessly with the DHCP server to provide boot filenames, PXE/BOOTP information, and custom DHCP options needed for booting even the most finicky devices. Even if you need TFTP services for a non-boot-related reason, DNSMasq's server is just a standard TFTP service that will work for any computer or device requiring it.
If you've read Kyle Rankin's recent articles on DNSSEC and want to make sure your DNS information is secure, there's no need to install BIND. DNSMasq supports DNSSEC, and once again provides configuration examples in the configuration file.
Truly, DNSMasq is the unsung hero for consumer-grade Internet routers. It allows those tiny devices to provide DNS and DHCP for your entire network. If you install the program on a regular server (or teeny tiny Raspberry Pi or Cubox), however, it can become an extremely robust platform for all your network needs. If it weren't for my need to get a more powerful and reliable router, I never would have learned about just how amazing DNSMasq is. If you've ever been frustrated by BIND, or if you'd just like to have more control over the DNS and DHCP services on your network, I urge you to give DNSMasq a closer look. It's for more than just your DD-WRT router!