| |

LFCE 42 ๐Ÿง isc-dhcp-server โ€” Installation and Config

โฑ๏ธ Estimated read: 11 min | |

The ISC DHCP server is the traditional implementation of DHCP on Linux, maintained by the Internet Systems Consortium. It is the server that responds to the DORA exchange described in the previous chapter: it listens on UDP port 67, receives the client’s broadcast Discover, selects an address from the configured pool, and sends the Offer, Acknowledge, and lease confirmation. The package is named isc-dhcp-server on Debian and Ubuntu, and dhcp-server on RHEL and its derivatives . The daemon is dhcpd, and its behavior is controlled by two files: /etc/dhcp/dhcpd.conf for the address pools and options, and /etc/default/isc-dhcp-server for the interface binding on Debian-based systems.

This chapter covers the installation, the minimal dhcpd.conf that defines a subnet and range, the interface binding that restricts the daemon to the correct network card, and the validation and testing commands. It builds on the protocol concepts from the previous chapter: the range statement defines the pool from which the DORA exchange draws addresses, and the option statements populate the configuration that the client receives in the Acknowledge.

Key point: The subnet declaration is mandatory for every network the server serves. The range statement inside it defines the addresses that can be assigned. The option routers and option domain-name-servers statements populate the client’s gateway and DNS configuration. Without the authoritative directive, the server may refuse requests for addresses it does not know about, and clients may not receive a timely response .


Why isc-dhcp-server requires explicit interface binding

The listening-interface problem.

A DHCP server on a multi-homed host must be told which interface to listen on. If it listens on all interfaces, it may respond to requests on a network where it has no authority, or it may send offers from the wrong source address. On Debian and Ubuntu, the /etc/default/isc-dhcp-server file contains the INTERFACESv4 variable, which restricts the daemon to the named interfaces . The daemon does not automatically determine the correct interface from the subnet declarations; the administrator must specify it.

The subnet-declaration problem.

The dhcpd.conf file must contain a subnet declaration for every network the server is expected to serve. If a client sends a Discover from a subnet that is not declared, the server has no pool to draw from and no options to send. The range statement inside the subnet declaration defines the addresses that can be assigned, and the option statements inside it define the configuration that accompanies the address .

The authoritative problem.

The authoritative directive tells the server that it is the authoritative DHCP server for the network. Without it, the server may ignore requests for addresses that it does not have a record of, or it may be slow to respond because it is waiting to see if another server will answer. In a network with a single DHCP server, the directive should be present .


a. Installing the package and locating the configuration

The package installation places the daemon, the configuration file, and the service unit on the system. The configuration file is not populated with a working subnet by default; the administrator must create it.

# Debian / Ubuntu
sudo apt update
sudo apt install isc-dhcp-server

# RHEL / Rocky Linux / Fedora
sudo dnf install dhcp-server

# Verify the installation
dhcpd --version
# Output: isc-dhcpd-4.4.x

# The main configuration file
ls -l /etc/dhcp/dhcpd.conf
# The file exists but contains only comments and examples

On Debian, the installation may fail to start the service because the default configuration has no subnet declaration. This is expected. The service will not start until a valid dhcpd.conf is in place .


b. The minimal dhcpd.conf

The configuration file contains global settings and one or more subnet declarations. The global settings apply to all subnets unless overridden locally. The subnet declaration contains the range and the option statements for that network.

# /etc/dhcp/dhcpd.conf
# Global settings
default-lease-time 600;        # Default lease: 10 minutes
max-lease-time 7200;           # Maximum lease: 2 hours
authoritative;                 # This is the authoritative server

# Subnet declaration
subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.150 192.168.1.200;        # Address pool
    option routers 192.168.1.254;              # Default gateway
    option domain-name-servers 192.168.1.1, 192.168.1.2;  # DNS servers
    option domain-name "example.com";          # Domain suffix
    option subnet-mask 255.255.255.0;          # Subnet mask
    option broadcast-address 192.168.1.255;    # Broadcast address
}

The range statement defines the start and end of the address pool. The option routers statement provides the default gateway that the client will use. The option domain-name-servers statement provides the DNS resolvers. The option subnet-mask and option broadcast-address statements complete the IP configuration .

The default-lease-time and max-lease-time values are in seconds. The client receives the default lease unless it requests a different duration; the maximum lease is the upper bound that the server will grant .


c. Binding the interface and starting the service

On Debian and Ubuntu, the interface binding is configured in /etc/default/isc-dhcp-server. The INTERFACESv4 variable lists the interfaces that the daemon should listen on.

# /etc/default/isc-dhcp-server
INTERFACESv4="eth1"            # Listen only on the internal interface
# INTERFACESv4="eth0 eth1"     # Or multiple interfaces

On RHEL and its derivatives, the interface binding is typically handled by the service unit or by the DHCPDARGS variable in /etc/sysconfig/dhcpd. The dhcpd daemon can also be started with the interface name as an argument .

# Validate the configuration before starting
sudo dhcpd -t -cf /etc/dhcp/dhcpd.conf
# Output: no errors

# Start and enable the service
sudo systemctl start isc-dhcp-server
sudo systemctl enable isc-dhcp-server

# Check the status
sudo systemctl status isc-dhcp-server

The dhcpd -t command tests the configuration syntax without starting the daemon. It is the equivalent of named-checkconf for BIND9 and should be run after every change .


Complete Example Session

# ============================================
# PART 1: INSTALL THE PACKAGE
# ============================================
sudo apt update
sudo apt install isc-dhcp-server

# ============================================
# PART 2: WRITE THE CONFIGURATION
# ============================================
sudo tee /etc/dhcp/dhcpd.conf > /dev/null <<'EOF'
default-lease-time 600;
max-lease-time 7200;
authoritative;

subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.150 192.168.1.200;
    option routers 192.168.1.254;
    option domain-name-servers 192.168.1.1, 192.168.1.2;
    option domain-name "example.com";
    option subnet-mask 255.255.255.0;
    option broadcast-address 192.168.1.255;
}
EOF

# ============================================
# PART 3: BIND THE INTERFACE
# ============================================
sudo tee /etc/default/isc-dhcp-server > /dev/null <<'EOF'
INTERFACESv4="eth1"
EOF

# ============================================
# PART 4: VALIDATE THE CONFIGURATION
# ============================================
sudo dhcpd -t -cf /etc/dhcp/dhcpd.conf
# Output: no errors

# ============================================
# PART 5: START AND ENABLE THE SERVICE
# ============================================
sudo systemctl start isc-dhcp-server
sudo systemctl enable isc-dhcp-server
sudo systemctl status isc-dhcp-server

# ============================================
# PART 6: VERIFY THE DAEMON IS LISTENING
# ============================================
sudo ss -ulnp | grep :67
# Output shows dhcpd listening on UDP port 67

# ============================================
# PART 7: CHECK THE LEASE FILE
# ============================================
sudo cat /var/lib/dhcp/dhcpd.leases
# The file is empty until a client receives a lease

# ============================================
# PART 8: TEST WITH A CLIENT
# ============================================
# On a client on the 192.168.1.0/24 network:
# sudo dhclient -r eth0; sudo dhclient eth0
# Then check the client's address:
# ip addr show eth0

# ============================================
# PART 9: MONITOR THE LOGS
# ============================================
sudo journalctl -u isc-dhcp-server -f
# Or on systems with syslog:
sudo tail -f /var/log/syslog | grep dhcpd

# ============================================
# PART 10: ADD A STATIC LEASE
# ============================================
sudo tee -a /etc/dhcp/dhcpd.conf > /dev/null <<'EOF'
host printer {
    hardware ethernet 00:11:22:33:44:55;
    fixed-address 192.168.1.50;
    option host-name "printer";
}
EOF
sudo dhcpd -t -cf /etc/dhcp/dhcpd.conf
sudo systemctl restart isc-dhcp-server

The ten parts demonstrate the complete installation and configuration workflow: installation, configuration, interface binding, validation, service start, daemon verification, lease file inspection, client testing, log monitoring, and static lease configuration. The critical steps are Part 4 (validation before starting) and Part 6 (confirming the daemon is listening on the correct port).


Quick Reference

Installation Commands

DistributionPackage
Debian / Ubuntuisc-dhcp-server
RHEL / Rocky / Fedoradhcp-server

Configuration Files

FilePurpose
/etc/dhcp/dhcpd.confSubnet declarations, ranges, options
/etc/default/isc-dhcp-serverInterface binding (Debian)
/var/lib/dhcp/dhcpd.leasesActive lease database

Key dhcpd.conf Statements

StatementPurpose
subnet <network> netmask <mask> { ... }Define a subnet
range <start> <end>;Address pool
option routers <ip>;Default gateway
option domain-name-servers <ip>;DNS servers
option subnet-mask <mask>;Subnet mask
option broadcast-address <ip>;Broadcast address
default-lease-time <seconds>;Default lease duration
max-lease-time <seconds>;Maximum lease duration
authoritative;Server is authoritative
host <name> { hardware ethernet <mac>; fixed-address <ip>; }Static lease

Commands

CommandPurpose
dhcpd -t -cf /etc/dhcp/dhcpd.confValidate configuration
systemctl start isc-dhcp-serverStart the service
systemctl status isc-dhcp-serverCheck service status
ss -ulnp | grep :67Confirm daemon is listening
cat /var/lib/dhcp/dhcpd.leasesInspect active leases
journalctl -u isc-dhcp-serverView logs

Best Practices

โœ… Do This:

# Validate the configuration before starting
dhcpd -t -cf /etc/dhcp/dhcpd.conf                          # โœ…

# Bind the daemon to the correct interface
INTERFACESv4="eth1"                                         # โœ…

# Use authoritative in single-server networks
authoritative;                                              # โœ…

# Define a range that does not overlap with static addresses
range 192.168.1.150 192.168.1.200;                          # โœ…

# Include all required options: gateway, DNS, mask, broadcast
option routers 192.168.1.254;                               # โœ…

# Use static leases for infrastructure devices
host printer { hardware ethernet ...; fixed-address ...; }  # โœ…

โŒ Don’t Do This:

# Start the service without a subnet declaration
# The service fails to start                                   # โŒ

# Leave the interface binding unset on a multi-homed host
# The daemon may listen on the wrong interface                # โŒ

# Use a range that includes the server's own address
# The server may offer its own address to a client            # โŒ

# Omit the gateway option
# Clients receive an address but cannot reach other subnets   # โŒ

# Forget to validate after editing
systemctl restart isc-dhcp-server    # Syntax error causes outage # โŒ

# Use a lease time longer than the pool can sustain
# Addresses are exhausted and new clients cannot connect      # โŒ

Common Pitfalls

PitfallWhy It HappensFix
Service fails to startNo subnet declaration in dhcpd.confAdd a subnet with a range
Clients receive no addressDaemon not listening on the correct interfaceSet INTERFACESv4 to the correct interface
Clients cannot reach internetoption routers missingAdd the gateway option
Address conflictStatic address within the dynamic rangeMove static addresses outside the range
Lease file emptyNo clients have requested addressesExpected; wait for a client or test manually
Configuration syntax errorMissing semicolon or bracedhcpd -t reports the file and line

Real-World Examples

1. Install on Debian

sudo apt install isc-dhcp-server

2. Install on RHEL

sudo dnf install dhcp-server

3. Minimal subnet

subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.150 192.168.1.200; option routers 192.168.1.254; }

4. Global lease times

default-lease-time 600; max-lease-time 7200;

5. Authoritative directive

authoritative;

6. Interface binding

INTERFACESv4="eth1"

7. Validate configuration

dhcpd -t -cf /etc/dhcp/dhcpd.conf

8. Start service

systemctl start isc-dhcp-server

9. Check listening port

ss -ulnp | grep :67

10. Static lease

host printer { hardware ethernet 00:11:22:33:44:55; fixed-address 192.168.1.50; }

Visual

isc-dhcp-server Configuration Structure

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  dhcpd.conf STRUCTURE                                        โ”‚
โ”‚                                                              โ”‚
โ”‚  Global settings                                             โ”‚
โ”‚  โ”œโ”€โ”€ default-lease-time 600;                                 โ”‚
โ”‚  โ”œโ”€โ”€ max-lease-time 7200;                                    โ”‚
โ”‚  โ””โ”€โ”€ authoritative;                                          โ”‚
โ”‚                                                              โ”‚
โ”‚  Subnet declaration                                          โ”‚
โ”‚  โ””โ”€โ”€ subnet 192.168.1.0 netmask 255.255.255.0 {              โ”‚
โ”‚        โ”œโ”€โ”€ range 192.168.1.150 192.168.1.200;                โ”‚
โ”‚        โ”œโ”€โ”€ option routers 192.168.1.254;                     โ”‚
โ”‚        โ”œโ”€โ”€ option domain-name-servers 192.168.1.1;           โ”‚
โ”‚        โ”œโ”€โ”€ option subnet-mask 255.255.255.0;                 โ”‚
โ”‚        โ””โ”€โ”€ option broadcast-address 192.168.1.255;           โ”‚
โ”‚      }                                                       โ”‚
โ”‚                                                              โ”‚
โ”‚  Static lease (optional)                                     โ”‚
โ”‚  โ””โ”€โ”€ host printer { ... }                                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Interface Binding

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE DAEMON MUST KNOW WHICH INTERFACE TO LISTEN ON           โ”‚
โ”‚                                                              โ”‚
โ”‚  /etc/default/isc-dhcp-server                                โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ INTERFACESv4="eth1"                                    โ”‚  โ”‚
โ”‚  โ”‚                                                        โ”‚  โ”‚
โ”‚  โ”‚ eth1 = internal network (clients)                      โ”‚  โ”‚
โ”‚  โ”‚ eth0 = external network (not a DHCP server)            โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                                                              โ”‚
โ”‚  If INTERFACESv4 is empty or wrong:                          โ”‚
โ”‚  โ†’ Daemon listens on the wrong interface                     โ”‚
โ”‚  โ†’ Clients receive no offers                                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Validation Workflow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  VALIDATE BEFORE STARTING                                    โ”‚
โ”‚                                                              โ”‚
โ”‚  Edit dhcpd.conf                                             โ”‚
โ”‚       โ”‚                                                      โ”‚
โ”‚       โ–ผ                                                      โ”‚
โ”‚  dhcpd -t -cf /etc/dhcp/dhcpd.conf                           โ”‚
โ”‚       โ”‚                                                      โ”‚
โ”‚       โ”œโ”€โ”€ Error โ†’ Fix file, repeat                           โ”‚
โ”‚       โ”‚                                                      โ”‚
โ”‚       โ””โ”€โ”€ Success โ†’ systemctl restart isc-dhcp-server        โ”‚
โ”‚                           โ”‚                                  โ”‚
โ”‚                           โ–ผ                                  โ”‚
โ”‚                     ss -ulnp | grep :67                      โ”‚
โ”‚                     (confirm listening)                      โ”‚
โ”‚                                                              โ”‚
โ”‚  Never skip validation. A syntax error stops the daemon.     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
Debian packageisc-dhcp-server
RHEL packagedhcp-server
Daemondhcpd
Main config/etc/dhcp/dhcpd.conf
Interface binding (Debian)/etc/default/isc-dhcp-server
Lease database/var/lib/dhcp/dhcpd.leases
Validationdhcpd -t -cf /etc/dhcp/dhcpd.conf
Listening portUDP 67
Subnet declarationMandatory for each served network
RangeDefines the address pool
AuthoritativeRequired for single-server networks

Key takeaways:

  • The subnet declaration is mandatory. Without it, the server has no pool and no options for that network. The range statement inside the subnet defines the addresses that can be assigned .
  • The interface binding restricts the daemon. On Debian, INTERFACESv4 in /etc/default/isc-dhcp-server tells the daemon which interface to listen on. Without it, the daemon may listen on all interfaces or fail to start .
  • The authoritative directive is required for single-server networks. It tells the server that it is the only DHCP authority, so it responds promptly to all requests .
  • Validate before starting. dhcpd -t catches syntax errors before the service is restarted. A configuration error prevents the daemon from starting, and clients receive no addresses.
  • The lease database records active leases. /var/lib/dhcp/dhcpd.leases is populated as clients receive addresses. An empty file means no client has requested an address yet.
  • Static leases use host declarations. The hardware ethernet statement matches the client’s MAC address, and fixed-address assigns a specific IP. Static addresses should be outside the dynamic range to avoid conflicts .

Remember: isc-dhcp-server is the traditional DHCP daemon. Installation is one package, but the configuration requires a subnet declaration, a range, and the option statements that the client needs. The interface binding tells the daemon which network to serve. The authoritative directive tells it to respond without hesitation. Validate with dhcpd -t before restarting, and verify with ss that the daemon is listening on port 67. The lease file records what has been assigned, and the logs show the DORA exchanges as they happen.


Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!