Merge branch 'nic-guard' into pxe-webapp-redesign

This commit is contained in:
cproudlock
2026-10-15 08:40:57 -04:00
11 changed files with 2634 additions and 0 deletions

View File

@@ -55,6 +55,20 @@
# _media/<pctype> links the base image's entries, so also look in the
# image roots (on a rebuild the _media views may not exist yet).
zscaler_ca_share_glob: "{{ samba_share }}/_media/*/Deploy/Applications/ZscalerCommercialCertificate-2048-SHA256.crt {{ samba_share }}/gea-*/Deploy/Applications/ZscalerCommercialCertificate-2048-SHA256.crt"
# NIC guard (pxe-nic-check): dnsmasq must never serve DHCP/PXE on the GE
# corporate network. Pin the two NICs by MAC (ip -br link); left blank,
# the imaging NIC is the interface= of /etc/dnsmasq.d/pxe-nic-only.conf
# or the holder of 172.16.9.1, and the GE NIC is the one with a DHCP
# lease. A MAC of a bridge port resolves to the bridge (br-pxe).
pxe_imaging_mac: ""
pxe_ge_mac: ""
# A foreign DHCP server handing out one of these domains (whole labels:
# wjs.geaerospace.net matches, notgeaerospace.net does not) = GE network.
pxe_corp_domain_suffixes: "geaerospace.net, ge.com"
# Only if the IMAGING switch is itself managed and sends LLDP/CDP: its
# LLDP system name / CDP device id / chassis MAC, comma separated, so
# it does not count as a corporate switch. 802.1X always counts.
pxe_nic_allowed_switches: ""
image_types:
- gea-standard
- gea-engineer
@@ -211,6 +225,77 @@
# firmware / iPXE requests.
script-on-renewal
# --- NIC guard: keep dnsmasq off the GE corporate network ---
# pxe-nic-check classifies each NIC from what it hears (LLDP/CDP/802.1X
# from managed switches, foreign DHCP offers and their domain). The
# dnsmasq drop-in runs it as ExecStartPre (--guard: dnsmasq refuses to
# start if the imaging NIC is on the GE network or next to another DHCP
# server); the timer re-checks every 5 min (--watch: stops dnsmasq) and
# writes /run/pxe-nic-status.json for the webapp. Operator notes and
# the floor tests: docs/pxe-nic-guard.md.
- name: "NIC guard: deploy pxe-nic-check"
copy:
src: "{{ usb_mount }}/pxe-server-helpers/pxe-nic-check"
dest: /usr/local/sbin/pxe-nic-check
mode: '0755'
- name: "NIC guard: create /etc/pxe-server"
file:
path: /etc/pxe-server
state: directory
mode: '0755'
- name: "NIC guard: write /etc/pxe-server/nic.conf"
copy:
dest: /etc/pxe-server/nic.conf
mode: '0644'
content: |
# Managed by pxe_server_setup.yml (vars pxe_imaging_mac, pxe_ge_mac,
# pxe_corp_domain_suffixes). Read by /usr/local/sbin/pxe-nic-check.
[nic]
{% if pxe_imaging_mac %}
imaging_mac = {{ pxe_imaging_mac | lower }}
{% else %}
# imaging_mac unset: falls back to interface= in
# /etc/dnsmasq.d/pxe-nic-only.conf, then the holder of own_ip
{% endif %}
{% if pxe_ge_mac %}
ge_mac = {{ pxe_ge_mac | lower }}
{% else %}
# ge_mac unset: falls back to the interface holding a DHCP lease
{% endif %}
corp_domain_suffixes = {{ pxe_corp_domain_suffixes }}
own_ip = 172.16.9.1
allowed_switches = {{ pxe_nic_allowed_switches }}
- name: "NIC guard: create dnsmasq drop-in directory"
file:
path: /etc/systemd/system/dnsmasq.service.d
state: directory
mode: '0755'
- name: "NIC guard: install dnsmasq ExecStartPre drop-in"
copy:
src: "{{ usb_mount }}/pxe-server-helpers/dnsmasq.service.d/nic-guard.conf"
dest: /etc/systemd/system/dnsmasq.service.d/nic-guard.conf
mode: '0644'
- name: "NIC guard: install watch service and timer"
copy:
src: "{{ usb_mount }}/pxe-server-helpers/{{ item }}"
dest: "/etc/systemd/system/{{ item }}"
mode: '0644'
loop:
- pxe-nic-check.service
- pxe-nic-check.timer
- name: "NIC guard: enable watch timer"
systemd:
name: pxe-nic-check.timer
state: started
enabled: yes
daemon_reload: yes
- name: "Create TFTP directory"
file:
path: "{{ tftp_dir }}"