Skip to main content

Chapter 14 Managing Host Addresses Dynamically with DHCP

Chapter Overview

In this chapter I introduce the Dynamic Host Configuration Protocol (DHCP), which automatically manages key network parameters on a LAN—IP addresses, subnet masks, gateways, and DNS servers. DHCP improves IP utilization, speeds up configuration, and reduces operating overhead.

I configure and deploy the Kea DHCP service on Linux, explain each parameter in its configuration file, and complete hands‑on labs: dynamically allocating IP addresses and binding fixed addresses to specific MACs. By the end, you’ll feel the practical power of DHCP and be able to use it confidently in production.

14.1 The DHCP protocol

DHCP is a UDP‑based protocol used inside local networks. It’s best suited to large LANs or environments with many mobile devices. A DHCP server automatically provides clients with IP configuration, offering a one‑stop service for network parameters.

Put simply, DHCP lets hosts in the same LAN obtain network settings automatically. In a topology like Figure 14‑1, manually configuring every machine would be tedious, and future maintenance would be painful. As the number of hosts grows (100, 1,000, or more), the work becomes overwhelming. DHCP not only assigns parameters automatically and ensures uniqueness of addresses, it can also reserve a fixed IP for a particular host.

Figure 14-1 DHCP topology

DHCP is everywhere: server rooms, homes, airports, cafés. For example, a café owner wants to focus on serving coffee, not on setting each visitor’s IP, mask, and gateway. A typical café LAN uses a private /24 such as 192.168.10.0/24, which can hold just over 200 hosts; daily customer count easily exceeds that. If customers were assigned addresses manually, those IPs wouldn’t be released when they leave, quickly exhausting the pool and raising management costs. With DHCP, clients automatically obtain the IP they need to get online; when they leave, the server reclaims the lease for others to use.

Since DHCP is essential in real environments, let me review several common terms:

  • scope: a complete IP subnet; DHCP uses scopes to manage distribution, address allocation, and parameters.
  • superscope: a list of scopes on a single physical network that are managed together.
  • exclusion range: addresses inside a scope that will never be handed to clients.
  • address pool: the remaining range within the scope that can be allocated dynamically.
  • lease: how long a client may use an assigned IP.
  • reservation: a guarantee that a particular device always receives the same IP.

14.2 Deploying the Kea service

On RHEL 10, the traditional ISC DHCP server package (dhcp-server, service name dhcpd) has been removed. The distribution now ships ISC Kea as the next‑generation DHCP service. The theory is the same, but configuration differs substantially, so follow the steps carefully.

After confirming my repositories, I install Kea (package name kea):

root@linuxprobe:~# dnf install kea
Updating Subscription Management repositories.
BaseOS 2.7 MB/s | 2.7 kB 00:00
AppStream 2.7 MB/s | 2.8 kB 00:00
Dependencies resolved.
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
kea x86_64 2.6.1-4.el10 BaseOS 1.3 M
Installing dependencies:
boost-system x86_64 1.83.0-4.el10 BaseOS 16 k
kea-libs x86_64 2.6.1-4.el10 BaseOS 3.1 M
libpq x86_64 16.1-7.el10 BaseOS 253 k
log4cplus x86_64 2.1.1-7.el10 BaseOS 355 k
mariadb-connector-c x86_64 3.4.1-1.el10 BaseOS 214 k
mariadb-connector-c-config noarch 3.4.1-1.el10 BaseOS 10 k
Installed:
boost-system-1.83.0-4.el10.x86_64
kea-2.6.1-4.el10.x86_64
kea-libs-2.6.1-4.el10.x86_64
libpq-16.1-7.el10.x86_64
log4cplus-2.1.1-7.el10.x86_64
mariadb-connector-c-3.4.1-1.el10.x86_64
mariadb-connector-c-config-3.4.1-1.el10.noarch

Complete!

Kea’s IPv4 configuration lives in kea-dhcp4.conf. The file is 468 lines long, but most are comments. I take a quick look (I’ll explain options shortly):

root@linuxprobe:~# cat /etc/kea/kea-dhcp4.conf

You’ll notice the familiar JSON format. Much of the file is blank lines and comments. I create a condensed version by stripping both with grep, then review the numbered lines:

root@linuxprobe:~# cd /etc/kea/
root@linuxprobe:/etc/kea# mv kea-dhcp4.conf kea-dhcp4.bak
root@linuxprobe:/etc/kea# grep -v "^$" kea-dhcp4.bak | grep -v "//" > kea-dhcp4.conf
root@linuxprobe:/etc/kea# cat -n kea-dhcp4.conf

Even the condensed file is 127 lines—about one quarter of the original. Table 14‑1 summarizes common Kea parameters and what they do.

Table 14-1 Common Kea parameters and their purposes

ParameterPurpose
interfacesWhich interfaces Kea listens on (e.g., ens160)
subnetAddress scope, e.g., 192.168.10.0/24
poolsAddress ranges used for dynamic allocation
reservationsBind specific IPs to clients by MAC or identifier
valid-lifetimeIP lease lifetime in seconds
renew-timerLease renewal timer
rebind-timerLease rebind timer
option-dataA set of DHCP options (gateway, DNS, NTP, etc.)
routersDefault gateway for clients
domain-name-serversDNS server addresses for clients
domain-nameDNS search domain for clients (e.g., example.org)
ntp-serversNTP server addresses
nis-serversNIS domain server addresses
time-offsetOffset from UTC in seconds (e.g., UTC+8 is 28800)
server-nameDHCP server’s hostname or identifier
ddns-send-updatesEnable/disable dynamic DNS updates (true/false)
ddns-qualifying-suffixSuffix used for DDNS (e.g., example.com.)
host-reservation-identifiersWhich identifiers to use for reservations (e.g., hw-address)
hw-addressClient MAC address for a reservation
ip-addressFixed IP to be handed to that client
client-classesClassify clients and apply different policies
lease-databaseWhere leases are stored
loggersHow Kea logs (method, level, destination)

14.3 Automating IP address management

DHCP was built to centralize and streamline IP management. The server automatically provides clients with IP, mask, gateway, DNS, and more—and reclaims leases when they expire.

Let me simulate a realistic request:

“Operations: Tomorrow, 100 learners will bring their own laptops for a training. Please ensure the lab’s local DHCP server automatically provides IP connectivity.”

Assume the lab’s network parameters are as in Table 14‑2.

Table 14-2 Lab network parameters

ParameterValue
IP range192.168.10.50–192.168.10.150
Subnet mask255.255.255.0
Gateway192.168.10.1
DNS server192.168.10.1

Table 14‑3 lists the server and client setup.

Table 14-3 DHCP server and client configuration

Host typeOSIP address
DHCP serverRHEL 10192.168.10.1
DHCP clientWindows 11Obtain via DHCP

Scopes are usually full subnets; the address pool is the portion actually handed to clients, so the pool is less than or equal to the scope. Because VMware Workstation includes its own DHCP service, I disable it to avoid conflicts with Kea (Figures 14‑2 and 14‑3).

Figure 14-2 Open “Virtual Network Editor”

Figure 14-3 Turn off VMware’s built‑in DHCP

I power on a few client VMs to test (1–3 is sufficient). I ensure both server and clients use Host‑only networking; otherwise they’ll be isolated and won’t obtain addresses.

After confirming the server’s IP is correct, I configure Kea. First, I edit lines 1–5 to specify the NIC name:

root@linuxprobe:/etc/kea# vim kea-dhcp4.conf
1 {
2 "Dhcp4": {
3 "interfaces-config": {
4 "interfaces": [ "ens160" ]
5 },

Lines 6–9 define a control socket used to talk to the server daemon. I don’t need it here; I delete these lines:

     6	    "control-socket": {
7 "socket-type": "unix",
8 "socket-name": "/tmp/kea4-ctrl-socket"
9 },

Lines 10–13 define the lease database. Not required for this exercise; I delete:

    10	    "lease-database": {
11 "type": "memfile",
12 "lfc-interval": 3600
13 },

Lines 14–21 set parameters for processing expired leases. I delete them as well:

    14	    "expired-leases-processing": {
15 "reclaim-timer-wait-time": 10,
16 "flush-reclaimed-timer-wait-time": 25,
17 "hold-reclaimed-time": 3600,
18 "max-reclaim-leases": 100,
19 "max-reclaim-time": 250,
20 "unwarned-reclaim-cycles": 5
21 },

Lines 22–24 set renew, rebind, and lifetime timers. Kea defaults to RFC 2131 values if omitted, so I delete these too:

    22	    "renew-timer": 900,
23 "rebind-timer": 1800,
24 "valid-lifetime": 3600,

Lines 25–29 define global client DNS. I keep and modify per Table 14‑2:

    25	    "option-data": [
26 {
27 "name": "domain-name-servers",
28 "data": "192.168.10.1"
29 },

Lines 30–46 set default search domain and other extras. I don’t need them; I delete:

    30	        {
31 "code": 15,
32 "data": "example.org"
33 },
34 {
35 "name": "domain-search",
36 "data": "mydomain.example.com, example.com"
37 },
38 {
39 "name": "boot-file-name",
40 "data": "EST5EDT4\,M3.2.0/02:00\,M11.1.0/02:00"
41 },
42 {
43 "name": "default-ip-ttl",
44 "data": "0xf0"
45 }
46 ],

Lines 47–55 define client classes and vendor‑specific options. I don’t need them; I delete:

    47	    "client-classes": [
48 {
49 "name": "voip",
50 "test": "substring(option[60].hex,0,6) == 'Aastra'",
51 "next-server": "192.0.2.254",
52 "server-hostname": "hal9000",
53 "boot-file-name": "/dev/null"
54 }
55 ],

Lines 56–60 define the scope and pool. I fill them in per Table 14‑2:

    56	    "subnet4": [
57 {
58 "id": 1,
59 "subnet": "192.168.10.0/24",
60 "pools": [ { "pool": "192.168.10.50 - 192.168.10.150" } ],

Lines 61–66 set the default gateway:

    61	            "option-data": [
62 {
63 "name": "routers",
64 "data": "192.168.10.1"
65 }
66 ],

Lines 67–113 show reservations (MAC↔IP bindings). I’ll use these in the next section; I delete them for now:

    67	            "reservations": [
68 {
69 "hw-address": "1a:1b:1c:1d:1e:1f",
70 "ip-address": "192.0.2.201"
71 },
72 {
73 "client-id": "01:11:22:33:44:55:66",
74 "ip-address": "192.0.2.202",
75 "hostname": "special-snowflake"
76 },
77 {
78 "duid": "01:02:03:04:05",
79 "ip-address": "192.0.2.203",
80 "option-data": [ {
81 "name": "domain-name-servers",
82 "data": "10.1.1.202, 10.1.1.203"
83 } ]
84 },
85 {
86 "client-id": "01:12:23:34:45:56:67",
87 "ip-address": "192.0.2.204",
88 "option-data": [
89 {
90 "name": "vivso-suboptions",
91 "data": "4491"
92 },
93 {
94 "name": "tftp-servers",
95 "space": "vendor-4491",
96 "data": "10.1.1.202, 10.1.1.203"
97 }
98 ]
99 },
100 {
101 "client-id": "01:0a:0b:0c:0d:0e:0f",
102 "ip-address": "192.0.2.205",
103 "next-server": "192.0.2.1",
104 "server-hostname": "hal9000",
105 "boot-file-name": "/dev/null"
106 },
107 {
108 "flex-id": "'s0mEVaLue'",
109 "ip-address": "192.0.2.206"
110 }
111 ]
112 }
113 ],

Lines 114–125 configure logging. Optional here; I delete them too:

   114	    "loggers": [
115 {
116 "name": "kea-dhcp4",
117 "output-options": [
118 {
119 "output": "/var/log/kea-dhcp4.log"
120 }
121 ],
122 "severity": "INFO",
123 "debuglevel": 0
124 }
125 ]

After trimming, the effective configuration is just 26 lines—the truly useful part:

  1 {
2 "Dhcp4": {
3 "interfaces-config": {
4 "interfaces": [ "ens160" ]
5 },
6 "option-data": [
7 {
8 "name": "domain-name-servers",
9 "data": "192.168.10.1"
10 },
11 ],
12 "subnet4": [
13 {
14 "id": 1,
15 "subnet": "192.168.10.0/24",
16 "pools": [ { "pool": "192.168.10.50 - 192.168.10.150" } ],
17 "option-data": [
18 {
19 "name": "routers",
20 "data": "192.168.10.1"
21 }
22 ],
23 }
24 ],
25 }
26 }

In exams and production alike, I enable services at boot so they start automatically after a reboot:

root@linuxprobe:/etc/kea# systemctl restart kea-dhcp4
root@linuxprobe:/etc/kea# systemctl enable kea-dhcp4
Created symlink '/etc/systemd/system/multi-user.target.wants/kea-dhcp4.service' → '/usr/lib/systemd/system/kea-dhcp4.service'.

Now I flip a Windows 11 client to Host‑only networking (Figure 14‑4) and set its NIC to obtain an address automatically. After a short wait, the client should display the assigned network info as in Figure 14‑5.

Figure 14-4 NIC mode

Figure 14-5 IP obtained automatically

In production, the firewall may block DHCP. I open it if needed:

root@linuxprobe:~# firewall-cmd --permanent --add-service=dhcp
success
root@linuxprobe:~# firewall-cmd --reload
success

Typically, DHCP proceeds through four stages: discover, offer, request, and acknowledge. After a client receives an IP, it broadcasts an ARP probe. Devices—including the Kea server—listen; when Kea hears a probe for one of its assigned addresses, it marks that IP as in use so it won’t be offered to others, preventing conflicts at the source.

14.4 Reserving fixed IP addresses

A reservation ensures that a particular device always gets the same IP. Think of it as a “reserved table” at a restaurant: the DHCP server holds that address for a specific client.

To bind an IP to a host, I need the host’s MAC address—a unique identifier on the NIC. Figures 14‑6 and 14‑7 show how to view it on Linux and Windows, respectively.

Figure 14-6 Viewing the NIC MAC on Linux

Figure 14-7 Viewing the NIC MAC on Windows

In Kea’s configuration, I bind MAC and IP using the following structure:

MAC to IP binding code
"reservations": [
{
"hw-address":"MAC",
"ip-address":"IP",
"hostname":"HostName"
}
]

A common pitfall I’ve seen in classes: some learners perform the binding test on Windows hosts, where older versions (Windows 7/10) display MAC addresses with hyphens (e.g., 00-0C-29-16-3F-EF). In Linux and Windows 11, the delimiter is a colon (:).

root@linuxprobe:/etc/kea# vim kea-dhcp4.conf
{
"Dhcp4": {
"interfaces-config": {
"interfaces": [ "ens160" ]
},
"option-data": [
{
"name": "domain-name-servers",
"data": "192.168.10.1"
},
],
"subnet4": [
{
"id": 1,
"subnet": "192.168.10.0/24",
"pools": [ { "pool": "192.168.10.50 - 192.168.10.150" } ],
"option-data": [
{
"name": "routers",
"data": "192.168.10.1"
}
],
"reservations": [
{
"hw-address": "00:0C:29:16:3F:EF",
"ip-address": "192.168.10.88",
"hostname": "Windows11"
}
]
}
],
}
}

After confirming parameters are correct, I save and restart Kea:

root@linuxprobe:/etc/kea# systemctl restart kea-dhcp4

If I just assigned this host an IP, the lease may not have expired yet, so it won’t switch to the reserved IP immediately. To see the effect right away, I restart the client’s network (Figure 14‑8).

Figure 14-8 Restart the NIC

I then see the reserved address in effect (Figure 14‑9).

Figure 14-9 Verifying the reservation

Review Questions

  1. What is DHCP used for?
    Answer: Automatically distributing IP configuration to devices on a LAN.

  2. Which network resources can DHCP hand out?
    Answer: IP address, subnet mask, default gateway, and DNS servers.

  3. Which range is actually handed to users—the scope or the pool?
    Answer: The address pool (because a scope can include excluded addresses).

  4. What’s the role of a lease?
    Answer: Define how long a client may use its address; expired leases are reclaimed to avoid waste.

  5. What’s a reservation?
    Answer: Binding a host’s MAC to a fixed IP so it always receives the same address.

  6. What does an exclusion range do?
    Answer: Ensures those IPs are never allocated to clients.

  7. Binding which piece of host information guarantees a fixed IP?
    Answer: The NIC’s MAC address.

  8. Can a MAC as shown by Windows 10 be used directly?
    Answer: Not as‑is—convert hyphens to colons.

  9. Without checking the client, how can I learn its MAC and assigned IP?
    Answer: Check the server’s logs (e.g., /var/log/messages).

  10. If Kea is running but clients still get no address, what are common causes?
    Answer: The server and clients are on different network modes (physically isolated), or the firewall is blocking DHCP.