Configuration
Lighthouse is configured by a single, human-editable TOML file
(/etc/lighthouse/lighthouse.toml on Ubuntu, C:\ProgramData\Lighthouse\lighthouse.toml on
Windows). The web UI edits the same file — its structured editor round-trips it (but drops
comments; use the raw-TOML mode to keep them). Durations accept s/m/h/d and compounds
(10h30m).
Config changes are validated before apply and hot-swapped without dropping the running
config — except listen_port, which needs a restart. Validate a file without starting the engine:
lighthoused --config /etc/lighthouse/lighthouse.toml --check
Sections
| Section | Purpose |
|---|---|
[server] | Interfaces, server_id (option 54), authoritative, metrics listen. |
[logging] | Log file and verbose packet logging. |
[lease] | Lease store (memfile or postgres), TTLs, T1/T2, reservation file. |
[control_api] | The engine's local control endpoint (default 127.0.0.1:8067). |
[[subnet]] | An IPv4 subnet — CIDR, pools, options, reservations, boot. |
[[class]] | Client classification. |
[ddns] | Dynamic DNS (RFC 2136 + TSIG). |
[dhcpv6] | The IPv6 engine and its subnets. |
[tftp] | The bundled read-only TFTP server for PXE. |
[ha] | High-availability node settings. |
A worked IPv4 subnet
[server]
interfaces = ["eth0"]
server_id = "192.168.10.1"
authoritative = true
[lease]
store = "memfile"
file = "/var/lib/lighthouse/leases.db"
default_ttl = "12h"
max_ttl = "24h"
[[subnet]]
cidr = "192.168.10.0/24"
pools = ["192.168.10.100-192.168.10.200"]
exclude = ["192.168.10.150"]
[subnet.options]
routers = ["192.168.10.1"]
domain_name_servers = ["192.168.10.1", "1.1.1.1"]
domain_name = "corp.example"
# A pinned address for a known device.
[[subnet.reservation]]
match = "mac"
mac = "aa:bb:cc:dd:ee:ff"
ip = "192.168.10.50"
hostname = "printer-1"
# A custom option by numeric code.
[[subnet.option_custom]]
code = 114
type = "string"
value = "https://captive.example/"
Client classes & PXE
# Only PXE clients draw from this pool.
[[subnet.pool]]
range = "192.168.10.220-192.168.10.240"
classes = ["pxe"]
[[subnet.boot]]
arch = "uefi-x64"
next_server = "192.168.10.5"
boot_file = "bootx64.efi"
[[class]]
name = "pxe"
vendor_class = "PXEClient" # option 60 substring
Class matchers are vendor_class (option 60), user_class (option 77), or mac_prefix (an OUI).
[class.options] overrides subnet options for matching clients.
IPv6
[dhcpv6]
enabled = true
[[dhcpv6.subnet]]
cidr = "2001:db8:10::/64"
pools = ["2001:db8:10::1000-2001:db8:10::1fff"]
# Prefix delegation:
pd_pools = ["2001:db8:100::/40"]
delegated_len = 56
[[dhcpv6.subnet.reservation]]
duid = "00:03:00:01:aa:bb:cc:dd:ee:ff"
Dynamic DNS
[ddns]
enabled = true
dns_server = "192.168.10.2"
forward_zone = "corp.example"
reverse_zones = ["10.168.192.in-addr.arpa"]
tsig_key_name = "lighthouse-key"
tsig_algorithm = "hmac-sha256"
tsig_secret = "..."
Lease store
[lease] store = "memfile" (default) is a crash-safe append-only file — it survives a hard kill.
Switch to store = "postgres" (with a url and sslmode) to use PostgreSQL, which is also the
substrate for HA. With Postgres configured, Lighthouse
refuses to start if the database is unreachable — it never silently runs stateless.