Razorback
NewsProjectsGuidesResourcesContact
 Guide Index Quick Links


Install DNS, DHCP, and Routing with dnsmasq on Debian

For someone wanting to put together their own internal network complete with a separate router with DNS and DHCP services, there's quite a number of ways to go about it. Originally I had been using Windows 2000 for the job since such services were readily available in the same package that let me set up a domain controller, but it hasn't exactly been something I could count on. I've since brought down those services on the domain controller, and now I use dnsmasq and iptables on a Debian virtual machine for the job.

It's actually really easy to set up such services in Linux, better than doing it the Windows way. Assuming you haven't set something wrong, you'll be up and running in a matter of minutes.

Prerequisites

To get started, you will need:

  • The latest Debian installation CD from debian.org
  • A machine with two NICs (if virtual, one can be set to NAT, the other must connect to a bridge that goes to your actual network)
  • Some means of isolating your network from the rest of the LAN (for example, creating a VLAN WITHOUT its own built-in DNS/DHCP services, often found in a "smart" switch)
    • You may also replace your main router if desired, though some ISPs really suck and don't let you do this. You will need to set up a proper firewall if you do so; this is not covered here.

First, get Debian installed. When prompted for a hostname and domain, you should specify that upfront, though you can always change it later. Since this assumes you're using an internal network, you can make up whatever domain name you want (for instance, hornet.storm, with "hornet" being the hostname and "storm" being the domain name), no registration necessary. Do not use a domain ending in .local, as that is known to introduce conflicts between Windows and Mac OS X systems.

Don't install a desktop environment; you don't need it here. You may wish to mark the SSH server for installation if you want the convenience of being able to use another terminal to manage your server from another location. Once the installation is complete, log in as root and run the following commands:

# apt-get update
# apt-get -y upgrade
# apt-get -y install sudo dnsmasq iptables-persistent

On the third line, you may also wish to include vim or your preferred text editor. The sudo package is for letting regular users run commands as root whenever needed if they are given permission to do so, which can be safer than simply logging in as root to do everything. If you created a normal user account, you can grant it sudo privileges by typing:

# usermod -a -G sudo [your_username]

With all of that out of the way, let's get the server configured.

Configure Interfaces and Hosts

On a fresh installation, it's very likely that your interfaces will be configured to use DHCP to get IP addresses. Since this is going to be a DNS/DHCP server and router, this is definitely not something we want. Edit /etc/network/interfaces so the two network adapters use static IP addresses. It should look a little something like this:

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# Goes outward to your main router
# (I'm using a VM with a NAT interface,
# so I just use the IP addresses for that)
allow-hotplug enp1s0
iface enp1s0 inet static
        address 192.168.122.3
        netmask 255.255.255.0
        gateway 192.168.122.1
        # Line below may be needed in case DNS
        # resolving doesn't work otherwise
        dns-nameservers 192.168.1.1 

# Your devices in the VLAN connect to this
allow-hotplug enp7s0
iface enp7s0 inet static
        address 192.168.10.2
        netmask 255.255.255.0
        broadcast 192.168.10.255
        network 192.168.0.0

Both adapters are given static IPs, one which goes outward to the internet (hence the gateway option is assigned to it. The other adapter does not have a gateway set, because it will be the gateway for all clients connecting to the VLAN. Be mindful of which adapter is connected to where in your network. If you don't know the adapter names being used in your installation, run the ip link or ip addr command. For both interfaces, make sure the netmask is set correctly; addresses starting in 192.168 will have a netmask of 255.255.255.0.

In my case, enp1s0 connects to the internet and provides internet access to the other clients in the VLAN, whereas enp7s0 is the interface which other VLAN clients will go through. The settings you'll need to enter are bound to vary depending on your own network configuration, so make sure you go over the lines and change them as needed.

/etc/hosts also needs to be edited now. dnsmasq will use this file as a list of permanent DNS records to use for the network. Only static IP addresses should be listed here, such as those of important servers.

127.0.0.1	localhost
# The DNS/DHCP server we're creating
192.168.10.2	hornet.storm	hornet
# My domain controller (put other 
# static IPs you have below)
192.168.10.3	baleen.storm	baleen

Add new lines to the file in the format as shown, keeping note of the domain name you're using. You could also add IPv6 addresses, but given most old systems can't utilize IPv6 (and that IPv4 provides more than enough addresses for an internal network), there's not much of a point in doing so for a case like this.

Configuring dnsmasq

Now that we've got those files taken care of, it's time to set up dnsmasq. To do this, we only need to edit one file: /etc/dnsmasq.conf. If the file already exists, rename it to dnsmasq.conf.old. The sample file provides a good reference with plenty of comments if you need to consult it later.

# DNS
bogus-priv
strict-order
expand-hosts
domain=storm
local=/storm/
# I prefer to put my router's internal IP here,
# but have listed Quad9 here for those who
# want that instead.
server=9.9.9.9
server=149.112.112.112

# DHCP
interface=enp7s0
dhcp-authoritative
dhcp-range=192.168.10.10,192.168.10.99,24h
dhcp-option=option:router,192.168.10.2
dhcp-option=option:dns-server,192.168.10.2
dhcp-option=option:netmask,255.255.255.0

# TFTP (only needed if running a TFTP server somewhere)
enable-tftp
tftp-root=/srv/tftp
dhcp-option=option:tftp-server,192.168.10.2
dhcp-option=option:bootfile-name,"pxelinux.0"

Small, isn't it? Let's break down the more important lines:

  • expand-hosts - Allows DHCP clients to register their hostnames into DNS records automatically, allowing machines to address each other by hostname without any extra effort.
  • domain - The full domain name to be used in the server. This should be consistent with what you've specified in /etc/hosts so far. Do not set this to a hostname.
  • local - Should generally be the same as domain, but surrounded by slashes.
  • server - A higher DNS server yours will call for any domains it cannot resolve itself. This could be your main router (starting in 192.168 or the like) if it has its own DNS server, or some public DNS server with a strong backing. Please don't use 8.8.8.8. Seriously.
  • interface - The interface your clients will connect to. dnsmasq will listen to DHCP requests only on that interface.
  • dhcp-authoritative - Make this the primary DHCP server in your network. Use this option only if no other DHCP servers in your isolated network have a DHCP server configured as authoritative.
  • dhcp-range - The range of IP addresses your server will lease out to clients, followed by the lease duration in hours.
  • dhcp-fqdn - (OPTIONAL) Register the FQDN of a DHCP client into the DHCP client rather than the base hostname; for example, manta.storm is registered rather than just manta. I don't find this option useful here.
  • enable-tftp - Enables the internal TFTP server in dnsmasq.
  • tftp-root - The root directory for your TFTP clients, such as those booting via PXE.

DHCP Options

  • router - the IP address of the router being used. If you are setting up a router on this server, it should be the same IP address as that.
  • dns-server - the IP address of the DNS server the clients will use to resolve domains, internal and external. Since we've set up DNS in this configuration file, this should also point to the same IP address.
  • netmask - This should be exactly what was assigned in /etc/network/interfaces. Surely it's easy to remember.

DHCP Options for TFTP

These should only be specified if you are running a TFTP server on your network. The TFTP server does not have to reside on the same server as the DHCP server.

  • tftp-server - the IP address of the TFTP server which PXE clients should connect to.
  • bootfile-name - the name of the program in the TFTP root directory which PXE clients should execute.

Once your configuration file is written down, save it and restart the dnsmasq service with either of the following commands:

# systemctl restart dnsmasq
# service dnsmasq restart

Try connecting some clients to it now. If you can ping them by hostname from some other machine on the isolated network, your DNS/DHCP server is working!

Setting Up Routing

If you want to set up your machine as a router to provide internet access to clients in your isolated network, it's really easy to do with two network interfaces installed. The iptables-persistent package will help us set this machine up as a router with only a few lines in a file. Create or edit the /etc/iptables/rules.v4 file with these lines in place:

*nat
-A POSTROUTING -o enp1s0 -j MASQUERADE
COMMIT

*filter
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i enp1s0 -j DROP
COMMIT

Replace enp1s0 with the interface that is connecting outward to the internet. The line in the nat table is what will be used to provide the clients with internet access, and the filter table acts as a sort of firewall that can cut off undesirable traffic not part of your network. Assuming you will be accessing all of your machines from within your household, this is all that you should need. You don't have to understand it thoroughly, this is just a bare minimum configuration.

After saving this file, you need to tell iptables-persistent to use the new rules. This can be done with the following command:

# iptables-restore < /etc/iptables/rules.v4

Job done. You should probably reboot the server for good measure.