DHCP scopes and network options
DHCP guides · Step-by-step setup
Start in the dashboard (SQLite)
A fresh Linux/SQLite node needs no DHCP YAML. First provide its static host addresses, persistent data volume and the network privileges in the host guide. The browser can select existing interfaces and addresses; it cannot create a VLAN interface, assign a host address or grant container capabilities.
- Open DNS → DHCP on the node that will allocate addresses. All setup and lease operations apply to that connected node.
- Choose New scope. Enter a stable name, interface, server IPv4 address, client subnet and any trusted relay pairs. Interface discovery lists local IPv4 addresses without sending DHCP traffic.
- Complete the address pool, router, DNS servers, lease duration and optional DNS registration, then review and save the scope. Open its detail page to add initial reservations or change saved setup.
- Turn on Enable DHCP after restart. The restart notice describes the saved desired state; saving does not start a listener or change a running allocator. Every saved scope must be complete even while DHCP is disabled.
- Stop any competing DHCP service before restarting this node to activate the saved scopes. Follow cutover checks, then confirm that the scope is running and inspect its leases.
New scopes, enabled state and topology changes take effect after a node restart. For an active API-managed scope, its ordinary network option and reservation editors apply changes immediately. Setup for next restart stages a complete scope instead. Disabling DHCP also takes effect only after restart. Up to 256 scopes and a 4 MiB saved setup document are supported; incomplete drafts cannot be persisted.
Optional file configuration
The legacy flat form configures a scope named default. Replace these
example addresses and interface with your LAN settings. serverIP must
already be assigned to the interface. Range endpoints are inclusive.
store:
driver: sqlite
dhcp:
enabled: true
management: api
interface: eth0
serverIP: 192.0.2.2
subnet: 192.0.2.0/24
rangeStart: 192.0.2.100
rangeEnd: 192.0.2.199
router: 192.0.2.1
dnsServers: [192.0.2.2]
domainName: lan.home.arpa
leaseDuration: 12h
registerDNS: true
dnsTTL: 30s
reservations:
- mac: "02:00:00:00:00:10"
ip: 192.0.2.10
hostname: printer
The pool, router and reservations must fit the subnet. Server, router, network, broadcast and trusted relay gateway addresses cannot be allocated. A reservation may be outside the dynamic pool but must be inside the subnet. Reservations use unicast Ethernet MAC addresses. Keep unmanaged static addresses outside the pool. Before new offers, the server probes candidate addresses and durably quarantines detected conflicts for ten minutes. This reduces collisions without proving that a quiet host is absent. A matching client's DECLINE uses the same ten-minute hold. Relay server-ID overrides and all configured failover server addresses are also excluded from allocation.
leaseDuration defaults to 12 hours and accepts whole seconds from one
minute to 30 days. dnsTTL defaults to 30 seconds and accepts one second to
one hour. Ensure advertised DNS servers are reachable on UDP and TCP port 53.
domainName is optional unless DNS registration is enabled.
Multiple subnets and relays
Use dhcp.scopes instead of flat scope fields to serve several networks.
Names are stable lowercase filename components; keep them unchanged while
leases remain active. This example serves a local subnet and a remote subnet
through a trusted relay on the same server-facing interface:
dhcp:
enabled: true
scopes:
- name: lan
management: api
interface: eth0
serverIP: 192.0.2.2
subnet: 192.0.2.0/24
rangeStart: 192.0.2.100
rangeEnd: 192.0.2.199
router: 192.0.2.1
dnsServers: [192.0.2.2]
domainName: lan.home.arpa
registerDNS: true
- name: guest
management: file
interface: eth0
serverIP: 192.0.2.2
subnet: 198.51.100.0/24
relayOnly: true
trustedRelays:
- sourceIP: 192.0.2.1
gatewayIP: 198.51.100.1
rangeStart: 198.51.100.100
rangeEnd: 198.51.100.199
router: 198.51.100.1
dnsServers: [192.0.2.2]
domainName: guest.home.arpa
registerDNS: true
Subnets cannot overlap. There is one listener per interface, at most one
direct scope per interface, and a shared server address for scopes on that
interface. Additional direct subnets need their own interfaces, such as VLAN
interfaces. Flat fields and scopes cannot be combined.
Configure the relay to send to the server address, preserving its return
address in giaddr. Both source IP and gateway IP must match the configured
pair on the receiving interface; allow a route back to giaddr. Ports default
to UDP 67. Unknown relays and direct clients carrying option 82 are ignored.
Routed unicast renewals use the client's existing address to choose its scope.
Relays supporting the following extensions need explicit authorization in
each trusted mapping. For example, a relay may use a transit giaddr while
selecting the guest link:
trustedRelays:
- sourceIP: 192.0.2.1
gatewayIP: 192.0.2.1
sourcePort: 1067
linkSelection: 198.51.100.1
serverIdentifier: 198.51.100.1
This is a mapping within a guest scope with subnet: 198.51.100.0/24.
linkSelection authorizes the exact RFC 3527 option-82 suboption-5 address;
it must be usable within that scope. Several scopes may share a relay source
and giaddr when their selectors differ. serverIdentifier authorizes the
exact RFC 5107 suboption-11 value used as option 54 in offers and replies. The
relay must handle subsequent client traffic sent to that override address.
The server's source IP stays its local serverIP.
A non-67 sourcePort requires RFC 8357's zero-length suboption 19 and must
match the actual UDP source port. Replies go to giaddr at that same port;
they never use linkSelection as the destination. Port 68 is forbidden.
Configured link selection and server identifier values must be present exactly;
unset fields reject those extensions. Duplicate control suboptions, malformed
TLVs and port mismatches are dropped. Valid option 82 is echoed whole, or
omitted whole if it cannot fit the client's reply limit. If a transit address
also falls within another configured scope, that scope must exclude it through
its own immutable topology; merely setting it as a mutable router is insufficient.
Conflict detection
conflictDetection accepts arp, icmp or disabled. By default, a directly
attached scope without trusted relays uses an ARP probe. A relay-only scope or
any scope with trusted relays uses a routed ICMP echo. ARP is rejected for
relay-configured scopes; choose ICMP or explicitly disable probes instead.
probeTimeout defaults to 200ms and accepts integral milliseconds between
50ms and 500ms. An offer hold commits before probing. A positive response
causes a durable ten-minute quarantine before another candidate is tried, up
to three candidates per packet. Existing bound clients are not probed again
when rediscovering their lease. Probe socket, route and cancellation errors
drop that packet without an offer; inspect logs and retry after correcting
the deployment. Probes require the raw-network privileges.
ICMP only detects hosts that answer it through the configured server interface.
Firewalls, sleeping devices and competing external allocators can hide conflicts.
Continue to reserve DHCP pools exclusively and keep other static addresses
outside them. disabled is an explicit operator opt-out; it does not disable
client DECLINE quarantine.
NTP, search domains, routes and boot settings
These optional fields work in the flat form or within a named scope. The following fields extend the local-scope example above:
ntpServers: [192.0.2.1]
domainSearch: [lan.home.arpa, lab.home.arpa]
classlessRoutes:
- destination: 0.0.0.0/0
router: 192.0.2.1
- destination: 10.20.0.0/16
router: 192.0.2.1
bootServer: 192.0.2.3
bootServerName: boot.lan.home.arpa
bootFile: netboot.efi
bootProfiles:
- architecture: 7
bootServer: 192.0.2.3
bootServerName: boot.lan.home.arpa
bootFile: http://boot.lan.home.arpa/boot.efi
NTP option 42 permits up to 63 unicast IPv4 servers. Search option 119 uses
validated DNS labels with at most 255 encoded bytes. Classless routes use
option 121 and Microsoft option 249 when requested; destinations must be
canonical IPv4 prefixes and next hops usable within the scope. The complete
route list must fit 255 encoded bytes. Clients receiving classless routes
ignore option 3, so include a 0.0.0.0/0 route explicitly for a default gateway.
bootServer sets BOOTP siaddr. bootServerName sets option 66 and, when at
most 63 bytes, sname; its limit is 253 bytes. bootFile sets both BOOTP file
and option 67, with a 127-byte limit. Names and files accept printable ASCII
without spaces. Up to 128 unique bootProfiles select a complete replacement
set of those three fields by client option-93 architecture. The first matching
architecture in the client's list wins; an unmatched client uses scope defaults.
Blank profile fields stay blank. Use an external TFTP or HTTP boot server;
kudurru does not serve boot files or provide proxyDHCP on UDP 4011.
Optional options follow the client's parameter-request list and are omitted
whole when the reply-size limit cannot accommodate them. Client FQDN option 81
accepts DNS-label and legacy ASCII names and is preferred over option 12 as an
advisory hostname. Its reply signals no server-driven RFC 2136 DNS UPDATE;
registerDNS controls local A/PTR publication independently. Malformed FQDN
flags/names and malformed architecture lists are rejected before allocation.