Skip to main content

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

SectionPurpose
[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.