You plugged in the switch and nothing connects
Your Fedora machine has a static IP and works fine. You connected a laptop, a phone, and a printer to the network, and they all show "No Internet" or an IP address starting with 169.254. Those devices are shouting for an IP address and getting silence. You need a DHCP server. You installed a package, but the service won't start, or clients aren't receiving leases. The configuration file is full of options you don't recognize, and you're not sure which tool Fedora actually recommends.
What DHCP actually does
DHCP is a four-step conversation between a client and a server. The client broadcasts a request asking for an IP address. The server replies with an offer. The client accepts the offer. The server acknowledges the lease and records the assignment. The server hands out the IP, the subnet mask, the default gateway, and DNS servers. It also tracks how long each client holds the address.
Fedora provides two primary tools for this job. dnsmasq is a lightweight daemon that handles both DHCP and DNS. It is fast, simple, and perfect for home labs, small offices, and virtual machine networks. dhcp-server installs the ISC DHCP daemon. This is the full-featured enterprise standard. It supports complex vendor-specific options, failover clustering, and granular control over lease policies.
Fedora does not install a DHCP server by default. You must choose the tool that matches your scale and requirements. The configuration lives in /etc/. Never edit files in /usr/lib/. Those files ship with the package and get overwritten on updates. Your changes belong in /etc/.
Which tool to use
Use dnsmasq when you need a lightweight server for a home lab, a small office, or a VM network where you also want simple DNS resolution. Use dhcp-server when you are managing a large enterprise network, need complex vendor-specific options, or require strict separation of DHCP and DNS services. Use NetworkManager's built-in DHCP server only when you are setting up a temporary hotspot on a laptop and don't need persistent configuration.
Set up dnsmasq for small networks
dnsmasq is the default choice for most Fedora users. It installs quickly and requires minimal configuration. The package is available in the base repositories.
Install the package and enable the service. The --now flag starts the service immediately after enabling it.
sudo dnf install dnsmasq
# Install the dnsmasq package from the base repository
sudo systemctl enable --now dnsmasq
# Enable the service to start on boot and start it now
Before you configure the daemon, check for a conflict with systemd-resolved. Fedora enables systemd-resolved by default. That service listens on port 53 for DNS queries. dnsmasq also wants port 53. If both run, dnsmasq fails to bind the socket and exits. You must stop systemd-resolved or configure dnsmasq to avoid the port.
Disable systemd-resolved if you plan to use dnsmasq for DNS as well. If you only need DHCP, you can run dnsmasq without DNS by setting port=0 in the config.
sudo systemctl stop systemd-resolved
# Stop the resolver to free port 53
sudo systemctl disable systemd-resolved
# Prevent systemd-resolved from starting on boot
Edit the configuration file. The default file contains commented examples. Add your settings at the bottom or uncomment and modify the relevant lines. Always back up the file before editing.
Here is how to configure the interface, address range, gateway, and DNS options.
# /etc/dnsmasq.conf
# Listen only on the specified interface. Replace eth0 with your actual interface name.
interface=eth0
# Define the DHCP pool. Start IP, End IP, Lease duration.
# 24h means leases expire after 24 hours.
dhcp-range=192.168.1.100,192.168.1.200,24h
# Option 3 is the default gateway. Clients use this to reach other networks.
dhcp-option=3,192.168.1.1
# Option 6 is the DNS server. Point clients to your dnsmasq or an external DNS.
dhcp-option=6,192.168.1.1
# Option 15 sets the domain name for clients.
dhcp-option=15,home.lan
# Read /etc/hosts for local DNS overrides. Useful for static hostnames.
addn-hosts=/etc/hosts
Restart the service to apply the changes.
sudo systemctl restart dnsmasq
# Reload the configuration and restart the daemon
Pin a MAC address to a static IP
You can reserve a specific IP for a device by its MAC address. This is useful for printers, servers, or IoT devices that need a predictable address. Add a dhcp-host line to the config.
# /etc/dnsmasq.conf
# Assign 192.168.1.50 permanently to the device with this MAC address.
dhcp-host=aa:bb:cc:dd:ee:ff,192.168.1.50
Restart dnsmasq after adding the reservation. The client must renew its lease to pick up the new assignment.
Disable systemd-resolved before starting dnsmasq. Port 53 is a single-occupancy room.
Set up ISC DHCP for large networks
The ISC DHCP server offers more control over lease policies, vendor classes, and failover. It is heavier than dnsmasq and requires more careful configuration. The package is named dhcp-server.
Install the package and enable the service.
sudo dnf install dhcp-server
# Install the ISC DHCP server package
sudo systemctl enable --now dhcpd
# Enable and start the dhcpd service
The configuration file is /etc/dhcp/dhcpd.conf. The syntax is strict. A missing semicolon or brace causes the service to fail. Validate the config before restarting.
Here is how to define a subnet, address range, and options.
# /etc/dhcp/dhcpd.conf
# Define the subnet and netmask.
subnet 192.168.1.0 netmask 255.255.255.0 {
# The pool of addresses to hand out.
range 192.168.1.100 192.168.1.200;
# Option 3: Default gateway.
option routers 192.168.1.1;
# Option 6: DNS servers. Comma-separated list.
option domain-name-servers 1.1.1.1, 8.8.8.8;
# Option 15: Domain name.
option domain-name "home.lan";
# Lease times in seconds. 600 is 10 minutes.
default-lease-time 600;
max-lease-time 7200;
}
Restart the service. If the config has a syntax error, dhcpd will not start and will log the error in the journal.
sudo systemctl restart dhcpd
# Restart the daemon to load the new configuration
Pin a MAC address to a static IP
ISC DHCP uses a host declaration for reservations. Place the block outside the subnet definition or inside it, depending on your structure.
# /etc/dhcp/dhcpd.conf
# Reserve an IP for a specific MAC address.
host my-printer {
hardware ethernet aa:bb:cc:dd:ee:ff;
fixed-address 192.168.1.50;
}
Restart dhcpd after adding the host declaration.
Check journalctl -xeu dhcpd. The daemon tells you exactly which line has a syntax error.
Open the firewall
Fedora enables firewalld by default. DHCP uses UDP ports 67 and 68. The firewall blocks these ports until you add the service.
Add the DHCP service to the permanent zone and reload the firewall. The --permanent flag saves the rule for the next boot. You must reload the firewall for the rule to take effect immediately.
sudo firewall-cmd --add-service=dhcp --permanent
# Add the dhcp service definition to the permanent configuration
sudo firewall-cmd --reload
# Apply the permanent rules to the running firewall
Run firewall-cmd --reload. Persistent rules are useless without a reload.
Verify the server works
Check the service status first. A green active (running) state means the daemon started without fatal errors.
systemctl status dnsmasq
# Check the state and recent log lines for dnsmasq
# Or use: systemctl status dhcpd
Inspect the journal for warnings or errors. The -xe flags add explanatory text and jump to the end of the log. The -u flag filters by unit.
journalctl -xeu dnsmasq
# Show detailed logs for dnsmasq with explanations
Verify the server is listening on the correct ports. DHCP listens on UDP 67.
ss -ulnp | grep :67
# List UDP sockets and filter for port 67
Check the lease file to see assigned addresses. dnsmasq stores leases in /var/lib/dnsmasq/dnsmasq.leases. dhcpd stores leases in /var/lib/dhcpd/dhcpd.leases.
cat /var/lib/dnsmasq/dnsmasq.leases
# View the current lease database for dnsmasq
The lease file shows the expiry time, MAC address, assigned IP, hostname, and client ID. If the file is empty, clients are not requesting addresses or the server is not responding.
Test with a real client. Connect a laptop or phone to the network. Check that it receives an IP in the configured range, the correct gateway, and working DNS. A server that hands out IPs but breaks DNS is worse than no server.
Test with a real client. A server that thinks it works but hands out bad DNS is worse than no server.
Common pitfalls and errors
dnsmasq fails to start
The most common error is a port conflict. dnsmasq tries to bind port 53, but systemd-resolved is already using it. The journal shows dnsmasq: failed to create listening socket.
Stop systemd-resolved and restart dnsmasq. If you need systemd-resolved for other reasons, configure dnsmasq to skip DNS by adding port=0 to /etc/dnsmasq.conf. This disables the DNS listener and leaves DHCP functional.
dhcpd config syntax error
dhcpd is unforgiving. A missing semicolon or mismatched brace causes the service to fail. The journal shows dhcpd: /etc/dhcp/dhcpd.conf line X: missing semicolon.
Check the line number in the error. Fix the syntax and restart. You can also run dhcpd -t to test the config without starting the daemon.
sudo dhcpd -t
# Test the configuration file for syntax errors
Clients get no IP
Check the firewall. If firewalld is blocking UDP 67, clients never see the offer. Run firewall-cmd --list-services to confirm dhcp is listed.
Check the interface. If dnsmasq is bound to eth0 but your traffic is on wlan0, the server ignores the requests. Verify the interface name with ip link.
Check SELinux. Both packages have SELinux policies. If you moved the lease file or config to a non-standard location, SELinux may block access. The journal shows avc: denied. Restore the context with restorecon -Rv /path/to/file.
Check the lease file permissions. The daemon must be able to write to the lease file. If the file is owned by root and the daemon runs as a different user, you get permission denied errors. The packages set the correct ownership by default. Do not change ownership manually.
Run journalctl first. Read the actual error before guessing.