Files
pxe-server/playbook/pxe-server-helpers/dnsmasq.service.d/nic-guard.conf
cproudlock bc422649e9 NIC guard: dnsmasq never serves DHCP/PXE on the GE network
pxe-nic-check classifies each NIC from what it hears: LLDP/CDP/802.1X
from managed switches, foreign DHCP offers and their domain (one
DHCPDISCOVER on the imaging NIC; the GE NIC's networkd lease is read
instead), STP and ARP hosts for information. A kernel BPF filter keeps
bulk SMB traffic out of the capture loop; bridge ports are listened on
too, since LLDP and EAPOL stop at the port.

- dnsmasq drop-in runs --guard as ExecStartPre: exit 1 on a ge or
  foreign-dhcp imaging verdict, fail open (loudly) on bugs or no link
- pxe-nic-check.timer runs --watch every 5 min: stops dnsmasq on a bad
  imaging verdict, never starts it
- /run/pxe-nic-status.json (0644, atomic) for the webapp
- playbook installs it all and writes /etc/pxe-server/nic.conf from
  pxe_imaging_mac, pxe_ge_mac, pxe_corp_domain_suffixes,
  pxe_nic_allowed_switches
- unit tests plus a no-root network-namespace lab (veth pairs, a raw
  socket DHCP/LLDP peer and real dnsmasq); docs/pxe-nic-guard.md has the
  operator notes and the two floor tests
2026-10-14 17:18:53 -04:00

19 lines
926 B
Plaintext

# dnsmasq drop-in: refuse to start DHCP/PXE unless the imaging NIC is on
# the isolated imaging network.
#
# Installed as /etc/systemd/system/dnsmasq.service.d/nic-guard.conf by
# pxe_server_setup.yml. pxe-nic-check --guard listens on the imaging NIC
# for 5 s and sends one DHCPDISCOVER (~6 s total), then exits:
# 0 safe to serve (isolated, no link, or the check itself broke - it
# fails open on bugs and says so loudly in the journal)
# 1 DO NOT serve: a foreign DHCP server or a managed/corporate switch
# (LLDP, CDP, 802.1X) is on the imaging NIC. dnsmasq does not start.
#
# Why did dnsmasq not start? journalctl -u dnsmasq -b | grep pxe-nic-check
# Full picture: pxe-nic-check (or the webapp status page)
# Guard does not run on "systemctl reload"; every start/restart runs it,
# including the @reboot cron restart.
[Service]
ExecStartPre=/usr/local/sbin/pxe-nic-check --guard