Sites no longer need either MAC in site-vars. pxe_nic_mac empty: before anything changes, the playbook runs pxe-pick-nic --auto. It takes the one wired port with a link, accepts it only if pxe-nic-check calls it isolated (no LLDP/CDP/802.1X, no other DHCP server, at most 10 hosts heard in 65 s), and pins it. The choice is saved in /etc/pxe-server/nic-pick.conf and never re-guessed at boot. When it cannot tell (no link, two links, not isolated) nothing changes, and the console banner says why and to run sudo pxe-pick-nic: pull the imaging cable and plug it back in, and the port that blinked is the imaging one. Both helpers are installed before the pick, so that works after a refused first boot. The site's corp domains and allowed switches are passed to the check. corp_nic_mac empty: every other wired port (en*, eth*) is a catch-all DHCP client, so GE can be plugged in at install or later. - dnsmasq stays pinned with interface=pxe0. A new check refuses any dhcp-range outside the imaging subnet, and proxy ranges. - The catch-all ports ignore offers from 172.16.9.1. - UFW allows SSH and 9009 by source on any interface, and keeps those rules when the old any-interface rules are removed. - pxe_nic_name must not look like en*/eth* in this mode. pxe-netplan-apply.sh takes 3 or 5 args. Without a pinned GE NIC it: - renames stray names (the old pxe0 after a re-pick, a leftover corp0) to enx<mac>, so the catch-all takes them, and restores them on revert; - checks that every NIC that had a DHCP address before has one after, tracked by MAC. With both MACs set (the WJ server), netplan, the dnsmasq pin and UFW render byte-for-byte as before. Tested in the pxetest VMs: - Fresh install with no MACs and the GE link down: the imaging port was picked and pinned as pxe0 with 172.16.9.1, and dnsmasq bound DHCP to pxe0 only. GE plugged in afterwards got a lease, SSH worked, and the guard reported pxe0 isolated. - --auto refuses with two links. - The interactive pick works by pulling and replugging the link. - A 3-arg re-apply is UNCHANGED. Unit tests (fake sysfs) cover the re-pick and pinned-to-catch-all renames.
67 lines
2.7 KiB
Django/Jinja
67 lines
2.7 KiB
Django/Jinja
# Managed by pxe_server_setup.yml (vars pxe_nic_mac, corp_nic_mac,
|
|
# pxe_nic_name, corp_nic_name, pxe_server_ip, pxe_subnet). Local edits are
|
|
# replaced on the next playbook run; the previous file is kept under
|
|
# /var/backups/netplan-<timestamp>/.
|
|
#
|
|
{% if corp_nic_mac %}
|
|
# Two NICs, each matched by MAC and given a stable name:
|
|
# pxe-lan imaging LAN, static, no gateway, no DNS. The ONLY NIC that
|
|
# serves DHCP/TFTP/HTTP boot/SMB. ignore-carrier: the address
|
|
# is put on (and kept) without link, so a switch that is off
|
|
# or a cable pulled at boot does not leave dnsmasq, Samba and
|
|
# Apache without {{ pxe_server_ip }} (networkd
|
|
# ConfigureWithoutCarrier= + IgnoreCarrierLoss=).
|
|
# ge-corp GE corporate network, DHCP client (SSH + webapp 9009, updates).
|
|
{% else %}
|
|
# The imaging NIC pinned by MAC, every other wired port a DHCP client:
|
|
# pxe-lan imaging LAN, matched by MAC and given a stable name. Static,
|
|
# no gateway, no DNS. The ONLY NIC that serves DHCP/TFTP/HTTP
|
|
# boot/SMB. ignore-carrier: the address is put on (and kept)
|
|
# without link, so a switch that is off or a cable pulled at
|
|
# boot does not leave dnsmasq, Samba and Apache without
|
|
# {{ pxe_server_ip }} (networkd ConfigureWithoutCarrier= +
|
|
# IgnoreCarrierLoss=).
|
|
# zz-en, zz-eth every other wired port: DHCP client, so the GE cable
|
|
# can go into any of them, at install or later. No set-name.
|
|
# networkd applies the first matching .network file in name
|
|
# order: 10-netplan-pxe-lan sorts before 10-netplan-zz-*, and
|
|
# {{ pxe_nic_name }} does not look like en*/eth* (the playbook
|
|
# checks), so the imaging NIC never falls into these. dnsmasq
|
|
# never serves them (interface= pins it to {{ pxe_nic_name }}),
|
|
# and a drop-in makes them ignore offers from {{ pxe_server_ip }}.
|
|
{% endif %}
|
|
network:
|
|
version: 2
|
|
renderer: networkd
|
|
ethernets:
|
|
pxe-lan:
|
|
match:
|
|
macaddress: "{{ pxe_nic_mac | lower }}"
|
|
set-name: {{ pxe_nic_name }}
|
|
dhcp4: false
|
|
dhcp6: false
|
|
ignore-carrier: true
|
|
optional: true
|
|
addresses:
|
|
- {{ pxe_server_ip }}/{{ pxe_prefix }}
|
|
{% if corp_nic_mac %}
|
|
ge-corp:
|
|
match:
|
|
macaddress: "{{ corp_nic_mac | lower }}"
|
|
set-name: {{ corp_nic_name }}
|
|
dhcp4: true
|
|
dhcp4-overrides:
|
|
route-metric: {{ corp_route_metric }}
|
|
{% else %}
|
|
{% for id, glob in [('zz-en', 'en*'), ('zz-eth', 'eth*')] %}
|
|
{{ id }}:
|
|
match:
|
|
name: "{{ glob }}"
|
|
dhcp4: true
|
|
dhcp6: false
|
|
optional: true
|
|
dhcp4-overrides:
|
|
route-metric: {{ corp_route_metric }}
|
|
{% endfor %}
|
|
{% endif %}
|