The ISC DHCP server has become the de facto standard for DHCP, and is used by numerous organizations to manage and assign IP addresses. In addition to supporting IP address assignments, ISC DHCP can also be configured to supply the DHCP options that are needed to PXE boot clients. This article will describe how to install, configure and troubleshoot an ISC DHCP server, and will also show how to set up the dhcpd.conf configuration file to allow servers to PXE boot.
The ISC DHCP server can be installed from source code, or from your favorite package repository if you are using Linux. If you are using the CentOS, Redhat Enterprise, or Fedora Linux distributions, you can use the yum utility to install the ISC DHCP server:
$ yum install dhcp
If you would prefer to install from source code, you can use curl along with the “configure”, “make” and “make install” options to build a server from source:
$ curl http://ftp.isc.org/isc/dhcp/dhcp-4.1.0.tar.gz > dhcp-4.1.0.tar.gz
$ tar xfvz dhcp-4.1.0.tar.gz
$ cd dhcp-4.1.0
$ ./configure --prefix=/usr/local
$ make && make install
If everything completed successfully, the server binary (dhcpd) should be installed in /usr/sbin or /usr/local/sbin, and a sample DHCP configuration file (dhcpd.conf) should be placed in the /etc or /usr/local/etc directory.
The ISC DHCP server is extremely easy to configure, and has two types of configuration directives. The first set of directives start with the word “option”, and control the values of the DHCP options sent to a client in response to a DHCPDISCOVER request. Directives without the “option” keyword control operational attributes of the server, such as lease times, how many leases to assign to clients, etc. The configuration file is typically named dhcpd.conf, and will typically be placed in the /etc or /usr/local/etc directory. Here is an annotated DHCP configuration file that supports PXE and Etherboot clients:
# Configure the default and maximum lease times
max-lease-time 3600;
default-lease-time 3600;
# Disable dynamic DNS updates
ddns-update-style none;
# Make the server authoritative for the network segments that
# are configured, and tell it to send DHCPNAKs to bogus requests
authoritative;
# Allow each client to have exactly one lease, and expire
# old leases if a new DHCPDISCOVER occurs
one-lease-per-client true;
# Tell the server to look up the host name in DNS
get-lease-hostnames true;
# Domain name to distribute to clients
option domain-name "prefetch.net";
# List of name servers to distribute to clients
option domain-name-servers 192.168.1.1, 192.168.2.1;
# Log to the local0 facility by default
log-facility local0;
# Ping the IP address that is being offered to make sure it isn't
# configured on another node. This has some potential repercussions
# for clients that don't like delays.
ping-check true;
# Server to request the bootfile from
next-server 192.168.1.5;
# Define option 150 for teh grub menu
option grubmenu code 150 = text;
# PXE clients will need to retrieve pxegrub and the menu.lst file
if substring(option vendor-class-identifier, 0, 9) = "PXEClient" {
option grubmenu "/boot/grub/menu.lst";
filename "pxegrub";
}
# Etherboot clients will retrieve pxegrub and a special menu.lst
# file that has the serial port settings configured
if substring(option vendor-class-identifier, 0, 9) = "Etherboot" {
option grubmenu "(nd)/boot/grub/menu.lst.serial";
filename "pxegrub";
}
# Define a subnet with the following items:
# - Netmask to use
# - The IP range to distribute to clients
# - The broadcast address to use
# - The router to use
#
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.100 192.168.1.200;
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.1.255;
option routers 192.168.1.1;
}
# Define a host named thecrue, and statically
# assign an IP address to it
host thecrue {
hardware ethernet 00:24:8c:4e:07:f6;
fixed-address 192.168.1.2;
}
# Define a host named aic, and statically
# assign an IP address to it
host aic {
hardware ethernet 00:24:8c:4e:07:f7;
fixed-address 192.168.1.3;
}
In the configuration above, the server is authoritative for the 192.168.1.0/24 network. Two hosts (thecrue and aic) are configured to use static IP assignments, and all other hosts will be allocated an IP address from the dynamic IP range 192.168.1.[100-200]. The configuration also has two configuration stanzas to check if the client is booting via PXE or Etherboot, and will send the name of the boot image (pxegrub in this case) and grub menu as DHCP options if the client code matches. For additional configuration options, please consult dhcpd.conf(5).
Before using the ISC DHCP server, you will need to create a leases file. This file is used by the server to store the leases as they are assigned to clients, and is a handy tool for debugging client issues. To create the file, you can use the touch utility:
$ touch /var/db/dhcp.leases
After the leases file has been created, you can start up the server. If the ISC DHCP server was installed from a package on a CentOS, Redhat Enterprise or Fedora server, you can use the chkconfig and service commands to enable it:
$ chkconfig dhcp on
$ service dhcp start
If you installed the server from source code, you can start the daemon from the command line:
$ /usr/local/sbin/dhcpd -q -lf /var/db/dhcp.leases -cf /etc/dhcpd.conf
You can verify that the daemon is running by checking for dhcpd in the ps output.
If your server is unable to start, or if a client isn’t retrieving an IP address, the first place to check is the system logs. The dhcpd daemon will log to the daemon syslog facility by default, but can be configured to use any of the available facilities. To configure the daemon to log to the local0 facility, you can add the following directive to your dhcpd.conf file:
log-facility local0;
In order for this to work, you will need to add an entry similar to the following to /etc/syslog.conf
local0.debug <one or more tabs> /var/log/dhcpd
If the logs aren’t helpful in locating the source of a problem, you can use a packet capture utility such as snoop or tcpdump. To use tcpdump to observe the DHCP protocol exchanges between the client and server, tcpdump can be run with a filter to limit traffic to the bootps and bootpc service ports:
$ tcpdump -n -i br0 port bootps or port bootpc
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on br0, link-type EN10MB (Ethernet), capture size 96 bytes
14:31:02.458945 IP 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 54:52:00:53:20:01, length 548
14:31:02.459572 IP 192.168.1.5.bootps > 192.168.1.11.bootpc: BOOTP/DHCP, Reply, length 300
14:31:04.882281 IP 192.168.1.11.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 54:52:00:53:20:01, length 548
14:31:04.882900 IP 192.168.1.5.bootps > 192.168.1.11.bootpc: BOOTP/DHCP, Reply, length 300
If you are running Solaris, you can use the snoop utility to observe the protocol exchanges:
$ snoop -vvv -d bge0 port bootpc or port bootps
.............
DHCP: ----- Dynamic Host Configuration Protocol -----
DHCP:
DHCP: Hardware address type (htype) = 1 (Ethernet (10Mb))
DHCP: Hardware address length (hlen) = 6 octets
DHCP: Relay agent hops = 0
DHCP: Transaction ID = 0x65abbe
DHCP: Time since boot = 0 seconds
DHCP: Flags = 0x0000
DHCP: Client address (ciaddr) = 0.0.0.0
DHCP: Your client address (yiaddr) = 0.0.0.0
DHCP: Next server address (siaddr) = 0.0.0.0
DHCP: Relay agent address (giaddr) = 0.0.0.0
DHCP: Client hardware address (chaddr) = 54:52:00:53:20:01
DHCP:
DHCP: ----- (Options) field options -----
DHCP:
DHCP: Message type = DHCPDISCOVER
DHCP: Maximum DHCP Message Size = 1500 bytes
DHCP: Unrecognized Option = 97, length = 17 octets
DHCP: Value = 0x00 0xDE 0xAD 0xBE 0xEF 0xDE 0xAD 0xBE 0xEF 0xDE 0xAD 0xBE 0xEF 0xDE 0xAD 0xBE 0xEF (unprintable)
DHCP: Unrecognized Option = 93, length = 2 octets
DHCP: Value = 0x00 0x00 (unprintable)
DHCP: Unrecognized Option = 94, length = 3 octets
DHCP: Value = 0x01 0x02 0x01 (unprintable)
DHCP: Client Class Identifier = "PXEClient:Arch:00000:UNDI:002001"
DHCP: Requested Options:
DHCP: 1 (Subnet Mask)
DHCP: 3 (Router)
DHCP: 12 (Client Hostname)
DHCP: 43 (Vendor Specific Options)
DHCP: 60 (Client Class Identifier =)
DHCP: 128 (Site Option)
DHCP: 129 (Site Option)
DHCP: 130 (Site Option)
DHCP: 131 (Site Option)
DHCP: 132 (Site Option)
DHCP: 133 (Site Option)
DHCP: 134 (Site Option)
DHCP: 135 (Site Option)
DHCP: Site Option = 150, length = 11 octets
DHCP: Value = 0xAF 0x05 0x01 0x10 0xEC 0x81 0x39 0xB1 0x02 0x03 0x00 (unprintable)
........
DHCP: ----- Dynamic Host Configuration Protocol -----
DHCP:
DHCP: Hardware address type (htype) = 1 (Ethernet (10Mb))
DHCP: Hardware address length (hlen) = 6 octets
DHCP: Relay agent hops = 0
DHCP: Transaction ID = 0x65abbe
DHCP: Time since boot = 0 seconds
DHCP: Flags = 0x0000
DHCP: Client address (ciaddr) = 0.0.0.0
DHCP: Your client address (yiaddr) = 192.168.1.11
DHCP: Next server address (siaddr) = 192.168.1.5
DHCP: Relay agent address (giaddr) = 0.0.0.0
DHCP: Client hardware address (chaddr) = 54:52:00:53:20:01
DHCP:
DHCP: ----- (Options) field options -----
DHCP:
DHCP: Message type = DHCPOFFER
DHCP: DHCP Server Identifier = 192.168.1.5
DHCP: IP Address Lease Time = 1800 seconds
DHCP: Subnet Mask = 255.255.255.0
DHCP: Router at = 192.168.1.1
DHCP: Client Hostname = kvmnode1.prefetch.net
DHCP: Boot File Name = pxegrub
The DHCP protocol and ISC DHCP server provide one of the core technologies needed to perform unattended Linux and Solaris installations, and to dynamically assign addresses to clients on a network. As you have seen in this article, it is pretty straight forward to get a DHCP server up and operational. If you are interested in learning more about the ISC DHCP server, check out the ISC website.
The following references were used while writing this article: