NICs: pick the imaging port at install, GE can go into any other port
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.
This commit is contained in:
@@ -4,5 +4,11 @@
|
||||
# port=0 / listen-address / bind-dynamic in /etc/dnsmasq.conf and the
|
||||
# pxe-nic-check guard (docs/pxe-nic-guard.md).
|
||||
interface={{ pxe_nic_name }}
|
||||
{% if corp_nic_mac %}
|
||||
except-interface={{ corp_nic_name }}
|
||||
no-dhcp-interface={{ corp_nic_name }}
|
||||
{% else %}
|
||||
# No pinned GE NIC (corp_nic_mac empty): every other wired port is a DHCP
|
||||
# client with no fixed name. interface= alone keeps dnsmasq off them, and
|
||||
# its only dhcp-range is the imaging subnet, so a GE address matches none.
|
||||
{% endif %}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# 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
|
||||
@@ -11,6 +12,24 @@
|
||||
# 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
|
||||
@@ -25,6 +44,7 @@ network:
|
||||
optional: true
|
||||
addresses:
|
||||
- {{ pxe_server_ip }}/{{ pxe_prefix }}
|
||||
{% if corp_nic_mac %}
|
||||
ge-corp:
|
||||
match:
|
||||
macaddress: "{{ corp_nic_mac | lower }}"
|
||||
@@ -32,3 +52,15 @@ network:
|
||||
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 %}
|
||||
|
||||
Reference in New Issue
Block a user