Configure a DHCP Server on Linux

Configure a Linux host to act as a DHCP server and assign predefined IP addressees to the supported hosts on our network. Temporarily allow IP addresses to be allocated dynamically during device setup.

The Dynamic Host Configuration Protocol (DHCP) is utilized during device startup to enable a networked device to obtain a valid network configuration, including IP address, from a DHCP server on the local network. The vast majority of devices (e.g., tablets, PCs, Xbox, etc.) that you'll find on a network utilize DHCP. Typically, a server assigns a private network address (e.g., 192.168.1.XXX) to the device.

This article makes use of the Internet Software Consortium's (ISC) DHCP server on both Ubuntu 16.04 Server and Yocto Pyro. ISC claims that its DHCP server "is the most widely used open source DHCP implementation on the Internet and is a carrier and enterprise grade solution". You can read more at http://www.isc.org/software/dhcp.

We make use of the DHCP server to assign a known, consistent, private address to each supported device in our trusted, private network zone.

Installation on Ubuntu 16.04

Prior to installation, you may notice that an /etc/dhcp directory already exists. If it does exist, then this directory most likely contains configuration files for the dhcp client (e.g, dhclient.conf). Keep in mind that our Linux server acts as both a DHCP server and a DHCP client for retrieving an IP and DNS address from our firewall.

After a fresh Ubuntu installation, we find the following files in /etc/dhcp:

$ ls
debug  dhclient.conf  dhclient-enter-hooks.d  dhclient-exit-hooks.d
If you want to see your dhclient in action, type the following:
$ sudo dhclient -v <interface> # e.g., enp0s7

To install the DHCP server, type the following:

$ sudo apt install isc-dhcp-server

The DHCP server doesn't start automatically after installation, as can be seen below:

$ ps -e | grep dhcp		

However, we can see that the DHCP server will start automatically on subsequent reboots:

$ ls -l /etc/rc5.d/*dhcp*
lrwxrwxrwx 1 root root 25 Feb 16 15:10 /etc/rc5.d/S02isc-dhcp-server -> ../init.d/isc-dhcp-server

Configuration

Important Files

File Purpose
/etc/dhcp/dhcpd.conf DHCP server configuration file
/etc/init.d/isc-dhcp-server DHCP initialization script
/etc/default/isc-dhcp-server Defaults for DHCP initialization script
/var/lib/dhcp/dhcpd.leases DHCP client lease database

For both our Ubuntu and Yocto systems we define a test network at 192.168.6.0/24, and this is where we will enable the DHCP server to assign addresses. For our Ubuntu server, we define the following in our /etc/network/interfaces file:

# experimental / test network
auto enp3s0
iface enp3s0 inet static
address 192.168.6.1
network 192.168.6.0
netmask 255.255.255.0
broadcast 192.168.6.255	

Next we modify the /etc/default/isc-dhcp-server file, which provides defaults for initialization of the server process. We just want to support the DHCP server on enp3s0. We do this by setting the INTERFACES parameter, and this parameter is ultimately passed onto the DHCP sever via its command line interface when it's started.

A snippet of /etc/default/isc-dhcp-server is shown below:

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
#       Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACES="enp3s0"

Before we modify our configuration file, /etc/dhcpd.conf, we make a copy as shown below

$ sudo cp /etc/dhcpd.conf /etc/dhcpd.conf.orig

There are various options supported by the DHCP server that aren't utilized in our simple example configuration file. Two quick resources for finding out more about the available options are the original configuration file and the man page: "man dhcpd.conf".

The configuration file consists of parameter and declaration statements. Parameter statements can be used to assign settings (e.g., authoritative), and we use declaration statements to describe the network topology and clients on the network. We make extensive use of the host declaration statement to assign fixed IP addresses to our known client devices.

Note that most devices support static IP address assignment via an administrative interface (e.g., local web server running on a web camera or a settings screen on a tablet). We prefer not to use this method to assign addresses since this is difficult to manage versus our centralized approach. Also, the distributed or a hybrid approach can lead to address conflicts that are difficult to debug.

For this article, we only support our POE SVC3 camera:

authoritative;

subnet 192.168.6.0 netmask 255.255.255.0 {
#        range 192.168.6.100 192.168.6.101;
        default-lease-time 86400;
        max-lease-time 86400;
        option subnet-mask 255.255.255.0;
        option broadcast-address 192.168.6.255;
        option routers 192.168.6.1;
        #option domain-name-servers 192.168.0.1;   
}

host svc3_cam {
        hardware ethernet C0:99:34:51:77:01;
        fixed-address 192.168.6.200;
}

A few notes to make about the configuration file:

  • The authoritative statement instructs the DHCP server to send a DHCPNAK in response to an invalid DHCPREQUEST
  • The subnet statement defines our local network and the option statements are propagated to each host statement. We are leaving range commented out to prevent the DHCP server from assigning IP addresses to unknown devices that may be attached to our network without permission. However, in some cases it is very convenient to enable this line temporarily to configure a device and record its MAC address, which can be found in the lease file (see below).
  • Each host statement maps an Ethernet MAC address to an IP address. A name is also given to each map (e.g., win_laptop)

Start the DHCP Server

$ sudo service isc-dhcp-server start

$ ps -e | grep dhcp
 2295 ?        00:00:00 dhcpd

We can see that our camera was assigned an IP address by examining /var/log/syslog:

$ grep DHCP /var/log/syslog

Feb 16 17:12:32 ubuntu1 dhcpd[2295]: DHCPDISCOVER from C0:99:34:51:77:01 via enp3s0
Feb 16 17:12:32 ubuntu1 dhcpd[2295]: DHCPOFFER on 192.168.6.200 to C0:99:34:51:77:01 via enp3s0
Feb 16 17:12:32 ubuntu1 dhcpd[2295]: DHCPREQUEST for 192.168.6.200 (192.168.6.1) from C0:99:34:51:77:01 via enp3s0
Feb 16 17:12:32 ubuntu1 dhcpd[2295]: DHCPACK on 192.168.6.200 to C0:99:34:51:77:01 via enp3s0

Using the DHCP Server

The dhcpd.leases file is used as a cache by the server across reboots and power failures. It also provides visibility into what if any dynamic addresses have been granted to devices from the range pool within the defined subnet. New leases are appended to the end of the dhcpd.leases file.

In order to prevent the file from becoming arbitrarily large, from time to time dhcpd creates a new dhcpd.leases file from its in-core lease database. Once this file has been written to disk, the old file is renamed dhcpd.leases~, and the new file is renamed dhcpd.leases. If the system crashes in the middle of this process, whichever dhcpd.leases file remains will contain all the lease information, so there is no need for a special crash recovery process.

Each time the dhcpd.conf file is changed, the DHCP server must be restarted to process the changes. This can be accomplished as follows:

$ sudo service isc-dhcp-server restart

Tips on Debugging

During boot, a client device will make a request to the broadcast IP address of 255.255.255.255 on destination port 67 using a unqiue transaction ID. This request will be made from an IP address of 0.0.0.0.

Nov 15 19:28:55 controller dhcpd: DHCPDISCOVER from C0:99:34:51:77:01 via enp3s0: network 192.168.6.0/24: no free leases

The DHCP server supports various command line options. To read about them, type "man dhcpd" or "man dhcp.conf" at a terminal prompt.

To see the options that were used by the system when starting the server, type the following at a terminal prompt:

$ ps -ef | grep dhcp

dhcp     19519     1  0 Feb06 ?        00:00:00 /usr/sbin/dhcpd -q -user dhcp -group dhcp

Future updates to this articlewill include Yocto specific configuration and additional debug information.

Help us improve this article by adding your comment or question:

email addresses are neither displayed nor shared