A DHCP server automates IP address assignment across your network, eliminating manual configuration errors and centralizing address management. ISC DHCP (provided by the dhcp-server package on RHEL 8) is the most widely deployed open-source DHCP implementation and supports dynamic address pools, static reservations, vendor class options, and failover pairing. This tutorial walks through installing and configuring dhcpd on RHEL 8, defining a subnet with a dynamic range, creating static host reservations, enabling the service, opening the firewall, and verifying lease allocation from a client.
Prerequisites
- RHEL 8 server with a static IP address on the interface that will serve DHCP (e.g.,
192.168.1.1/24onens3) - Root or
sudoaccess - The subnet you intend to serve must not already have another DHCP server — duplicate DHCP responses cause unpredictable client behavior
- A client on the same subnet for testing
Step 1 — Install the DHCP Server Package
The ISC DHCP server is available in the default RHEL 8 AppStream repository. A single package installs the daemon, configuration examples, and systemd service unit.
dnf install -y dhcp-server
# Confirm the installed version
dhcpd --version
# Review the example configuration for reference
cat /usr/share/doc/dhcp-server/dhcpd.conf.example | less
The main configuration file is /etc/dhcp/dhcpd.conf. It is empty by default — all configuration must be added manually or copied from the example file.
Step 2 — Write the dhcpd.conf Configuration
Create the primary configuration. The global section sets default and maximum lease times and DNS options. The subnet block defines the network the server will serve, the dynamic address range, and essential options such as the default gateway and DNS servers.
# /etc/dhcp/dhcpd.conf
# Global parameters
default-lease-time 86400; # 24 hours in seconds
max-lease-time 604800; # 7 days in seconds
authoritative; # This server is authoritative for the subnet
option domain-name "example.local";
option domain-name-servers 192.168.1.1, 8.8.8.8;
log-facility local7;
# Subnet declaration
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.100 192.168.1.200;
option routers 192.168.1.1;
option broadcast-address 192.168.1.255;
option subnet-mask 255.255.255.0;
option ntp-servers 192.168.1.1;
}
The authoritative directive tells dhcpd to send DHCPNAK to clients requesting addresses outside the configured subnets, preventing stale leases from a previous DHCP server from causing connectivity problems.
Step 3 — Add Static Host Reservations
Static reservations bind a fixed IP address to a specific MAC address. This is useful for servers, printers, and network devices that need predictable addressing. Add host blocks inside or outside the subnet block — placing them inside the subnet is cleaner and is the recommended practice.
# Add inside the subnet block in /etc/dhcp/dhcpd.conf
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.100 192.168.1.200;
option routers 192.168.1.1;
option broadcast-address 192.168.1.255;
option subnet-mask 255.255.255.0;
# Static reservation for a web server
host webserver01 {
hardware ethernet 52:54:00:ab:cd:ef;
fixed-address 192.168.1.10;
option host-name "webserver01";
}
# Static reservation for a network printer
host printer01 {
hardware ethernet 00:1a:2b:3c:4d:5e;
fixed-address 192.168.1.20;
}
}
Fixed addresses should be outside the dynamic range to prevent them from being assigned to another client. In this example the range starts at .100, leaving .1 through .99 available for static assignments.
Step 4 — Enable and Start the dhcpd Service
Before starting the service, validate the configuration file syntax with dhcpd -t. This catches typos and syntax errors without affecting running state.
# Test the configuration for syntax errors
dhcpd -t -cf /etc/dhcp/dhcpd.conf
# Enable and start the service
systemctl enable --now dhcpd
# Check service status and recent logs
systemctl status dhcpd
journalctl -u dhcpd -n 50 --no-pager
If dhcpd fails to start, the most common causes are: a syntax error in dhcpd.conf, a missing subnet declaration for the interface’s network, or a port conflict with another DHCP process. The journalctl output will identify the specific line and error.
Step 5 — Open the Firewall
DHCP uses UDP port 67 (server) and port 68 (client). Firewalld has a predefined dhcp service that opens port 67/UDP. Because DHCP discovery uses broadcast, the server must be on the same Layer 2 segment as the clients, or a DHCP relay agent must be configured on intervening routers.
firewall-cmd --permanent --add-service=dhcp
firewall-cmd --reload
# Confirm the rule is active
firewall-cmd --list-services
Step 6 — Verify Lease Allocation
From a client on the same subnet, request a DHCP lease. On the server, the active leases file records every assignment made by dhcpd.
# On a Linux client: release and re-request a lease
dhclient -r ens3
dhclient ens3
ip addr show ens3
# On the DHCP server: view active leases
cat /var/lib/dhcpd/dhcpd.leases
# Watch for new lease activity in real time
journalctl -u dhcpd -f
Each lease entry in dhcpd.leases shows the IP address, binding state, start and end timestamps, and the client’s MAC and hostname. The file is an append-only log — dhcpd periodically rewrites it to remove expired entries.
Conclusion
You have installed ISC DHCP on RHEL 8, written a complete dhcpd.conf with a dynamic address pool and static host reservations, enabled and started the service, opened the appropriate firewall rule, and verified that clients receive leases. This configuration handles most small-to-medium network environments. For larger or redundant deployments, consider configuring ISC DHCP failover pairing between two servers, or evaluate ISC Kea (the modern successor to ISC DHCP) which provides a REST API, JSON configuration, and built-in high availability. Always monitor the lease file and logs to catch address exhaustion before clients begin to fail.
Next steps: How to Configure a DNS Server with BIND on RHEL 8, How to Set Up ISC DHCP Failover Pairing on RHEL 8, and How to Configure DHCP Relay with firewalld on RHEL 8.