Setting up a home network DHCP/DNS server with dnsmasq

When you have too many networked devices like I.., uh, someone I know does, it becomes very difficult to keep up with IP addresses...

The problem is two fold. First, to be able to get to every device, you have to give them all static IPs. Otherwise your DHCP server (typically your cable/DSL router) will give them seemingly random IPs if they restart. Assigning static IPs can be a real pain, especially with embedded devices that have clunky, or sometimes no interface for setting up IPs. If that wasn't enough, you have to try to remember all those IPs! Ugh. These problems can be solved with some DHCP options and a DNS server, but those are typically heavyweight servers that are just too complex for a simple home network.

Enter dnsmasq

Dnsmasq is an excellent lightweight utility that provides network infrastructure for small networks. It is the perfect tool for solving our two problems! Firstly, it provides DHCP with address reservation. This just means the DHCP server will assign us an IP, but it will be the same IP every time. The usefulness of a static IP with the convenience of DHCP! One problem down. Second, it doubles as a DNS server. Therefore, we will be able to access our devices by name. No more having to remember IPs!

Using dnsmasq in your network

If you decide to use dnsmasq in your network, you need to be aware that it will replace some services that your cable/DSL router may be providing (specifically DHCP) so you will need to turn those off when you turn on dnsmasq. Also, since dnsmasq will be providing critical network services, it will need to be hosted on a computer that is on all the time. In this article, we'll use a Raspberry Pi to run dnsmasq for a couple of reasons: It's inexpensive. It small and unobtrusive. It is very power efficient. Finally, you will need to pick a real static IP for the Pi since it will be the DNS server. If your router's LAN address is 192.168.0.1, I would suggest using an adjacent address for your DHCP/DNS server (e.g. 192.168.0.2 in this case).

The sample network for this article

In this article, we'll use the following network setup. Obviously, your network will be different but having concrete examples makes things easier to demonstrate.

Sample Network Layout

So we have:

  • Our cable/DSL/wireless router named router at its LAN IP 192.168.0.1
  • A Raspberry Pi running dnsmasq named dnsserver at static IP 192.168.0.2
  • A desktop computer named thedoctor at DHCP-assigned address 192.168.0.10
  • A laptop computer named tardis at DHCP-assigned address 192.168.0.22
  • A phone named sonicscrewdriver at DHCP-assigned address 192.168.0.23
  • A game system named satellite5 at DHCP-assigned addressed 192.168.0.32

Raspberry Pi setup

We need to set up a "headless" Raspberry Pi as our server. Go do that before we proceed...

Installing and configuring dnsmasq

Once you have your Pi on your network with a static IP (we'll use 192.168.0.2 in this article), you'll need to install dnsmasq:

sudo apt-get install dnsmasq

Easy enough. Now, let's configure dnsmasq. The default configuration file for dnsmasq is /etc/dnsmasq.conf. At some point you should take a look at it. It is well documented and if your needs go beyond basic DNS/DHCP you can probably find what you want to do in there. However, we are going to add our specific configuration to a new file in /etc/dnsmasq.d. This keeps our configuration out of the main dnsmasq.conf file so that there are no problems with new default config files when we update dnsmasq through the package manager.

I'm going to give you the config file for the whole sample network up front. Then we'll go over it to see what it actually does. Create a new file, /etc/dnsmasq.d/home.dns with the following contents:

# General configuration
domain-needed
bogus-priv
domain=home.lan
dhcp-range=192.168.0.10,static,48h
dhcp-option=3,192.168.0.1

# Static IPs
dhcp-host=00:00:5e:00:53:42,thedoctor,192.168.0.10
dhcp-host=00:00:5e:00:53:01,00:00:5e:00:53:02,tardis,192.168.0.22
dhcp-host=00:00:5e:00:53:08,sonicscrewdriver,192.168.0.23
dhcp-host=00:00:5e:00:53:10,satellite5,192.168.0.32

The first two options, domain-needed and bogus-priv allow us to use made up names on our network. (By "made up" I mean we get to name our machines internally whatever we want. We don't have to register them with anyone.) Dnsmasq will resolve those for us, without asking the "real" (e.g. internet) DNS servers for addresses for those names.

The next option domain lets us specify a domain for our network, though we'll rarely use it. I chose a simple home.lan value here. You can choose what you want.

There's a lot happening in the next option, dhcp-range. It does what it sounds like. It specifies the range of IPs for our DHCP server to give out. In this example, we began giving out addresses at 192.168.0.10. We didn't specify an end address (but we could have). We specified the option static which means that we will be statically assigning IP addresses to MAC addresses. This means dnsmasq will not hand out an IP to everyone, but only to MAC addresses listed in this config file. Finally, the 48h is the lease time. IP addresses will be valid for 48 hours at which point our devices will renew their leases. Please note we started the range at .10 to allow us to configure truly static IPs outside of dnsmasq in the 1 to 9 range.

The next option dhcp-option sets the default route that dnsmasq will send to hosts when giving out IP addresses. This defaults to the machine dnsmasq is running on, but we still want our cable/DSL router to be the default since it has the connection to the internet. So, we set the default route option to 192.168.0.1.

The next section contains our actual address reservations for our devices. It is a series of dhcp-host options, one for each machine we want to have an IP address. First we list the MAC address, then our desired machine name, and finally the desired IP address of the machine.

You may notice the entry for tardis has two different MAC addresses listed. That is because the tardis machine has two network interfaces, a wired one and a wireless one. By specifying the same IP for both addresses, the machine will be appropriately named and have the same IP no matter which interface it connects to the network with. Nice!

Configuration is complete! Do not forget to disable DHCP in your router before proceeding. Dnsmasq will be taking over those duties at this point. Go ahead and (re)start dnsmasq with the new config:

sudo service dnsmasq restart

Everything should be ready to go! If you made syntax errors in your config, dnsmasq will warn you. Fix those and re-run the command above.

Getting to your router and DNS server by name

Everything will work as configured above. You can access your cable/DSL router via 192.168.0.1 and your DNS/DHCP server via 192.168.0.2. If you want to access those machines by name, we need to tell dnsmasq about them. Currently, dnsmasq does not know about them since they have static IP addresses and are not served by dnsmasq's DHCP operation. To give them names, simply add the following to /etc/hosts on the Pi:

192.168.0.1    router.home.lan router
192.168.0.2    dnsserver.home.lan dnsserver

Restart dnsmasq with:

sudo service dnsmasq restart

Now you can access the router with router and the DNS/DHCP server with dnsserver.

Adding machines to your network

Each time you want to put a new machine on your network you will need to get its MAC address and add a dhcp-host entry in your config file. You can do this by a variety of means. On Linux, ifconfig will list your MAC(s) as HWaddr. Similarly, on Windows, ipconfig /all will list MAC addresses. On phones, the MAC is typically listed somewhere in the Settings/About area. Some devices print the MAC on stickers on the physical device. Some devices do not tell you the MAC at all (fortunately, this seems to be rare). All these are valid ways of getting a MAC for your config entry.

There is a trick, however, that I use a lot when adding machines to my network. Before you bring your new device online, SSH into your dnsmasq machine and run the following:

tail -f /var/log/syslog | grep DHCP

This will show you log information from dnsmasq. Next, start up your new device. When it requests an address, dnsmasq will log "No address available" along with the MAC of the requesting device. Copy that MAC into your dhcp-host entry for the device and restart dnsmasq with:

sudo service dnsmasq restart

Summary

In this article, we have added a Raspberry Pi statically to our home network. We've configured it to be a DNS/DHCP server using dnsmasq. We've set static address reservations for all our machines. We can now do things like ping thedoctor, or ssh tardis. No more random IPs and no more remembering IPs!