restructure: move proxmox/ into subfolder, add pihole/ section

All existing content moved from repo root into proxmox/ to make room
for other Debian machine configs. Adds pihole/ with:

- config/pihole.toml — snapshot of current Pi-hole v6 config
- config/dnsmasq.d/99-ipxe-chainload.conf — custom PXE DHCP rules
  (EFI/BIOS iPXE chainload, fixed tag-specificity bug for UEFI boot)
- pull-config.sh <source-host> <dest-dir> — pull live config to disk
- apply-config.sh <source-dir> <dest-host> — push config to a Pi-hole

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XRzqNDrbnYR22ZgZj1Bg3s
This commit is contained in:
2026-07-23 12:16:35 +10:00
co-authored by Claude Sonnet 4.6
parent 7a038b534f
commit 2909db5d04
28 changed files with 1894 additions and 0 deletions
+133
View File
@@ -0,0 +1,133 @@
#!/bin/bash
# Reproduces pve-test's wifi-primary networking: vmbr0 bridged over a wifi
# NIC in 4addr (WDS) client-bridge mode, active-backup bonded with a wired
# NIC as an automatic LAN fallback. See docs/06-pve-test-wifi-network.md for
# why this exists and how it was validated. Idempotent - safe to re-run.
#
# Requires: a wifi NIC whose driver/AP both support 4addr mode (verify with
# docs/06-pve-test-wifi-network.md's isolated-namespace test *before*
# trusting this against a live management IP - a wifi NIC or AP that
# doesn't support 4addr will associate fine but silently drop bridged
# frames from any MAC other than the card's own).
#
# Usage (run as root on the target PVE host):
# WIFI_SSID="..." WIFI_PASSPHRASE="..." \
# MGMT_ADDR=192.168.2.251/24 MGMT_GATEWAY=192.168.2.254 \
# ./setup-wifi-bond-network.sh
#
# Optional overrides: WIFI_IFACE (default wlp3s0), LAN_IFACE (default nic0)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib/common.sh
source "${SCRIPT_DIR}/lib/common.sh"
require_root
WIFI_IFACE="${WIFI_IFACE:-wlp3s0}"
LAN_IFACE="${LAN_IFACE:-nic0}"
for var in WIFI_SSID WIFI_PASSPHRASE MGMT_ADDR MGMT_GATEWAY; do
if [ -z "${!var:-}" ]; then
echo "$var is not set. See usage in this script's header." >&2
exit 1
fi
done
if ! ip link show "$WIFI_IFACE" >/dev/null 2>&1; then
echo "No interface named $WIFI_IFACE on this host. Run 'ip -br link' and set WIFI_IFACE=..." >&2
exit 1
fi
if ! ip link show "$LAN_IFACE" >/dev/null 2>&1; then
echo "No interface named $LAN_IFACE on this host. Run 'ip -br link' and set LAN_IFACE=..." >&2
exit 1
fi
echo "=== 1/4: wifi tooling ==="
apt-get install -y iw wpasupplicant >/dev/null
echo "installed iw, wpasupplicant"
echo
echo "=== 2/4: wpa_supplicant config (SSID: $WIFI_SSID, iface: $WIFI_IFACE) ==="
WPA_CONF="/etc/wpa_supplicant/wpa_supplicant-${WIFI_IFACE}.conf"
wpa_passphrase "$WIFI_SSID" "$WIFI_PASSPHRASE" > "$WPA_CONF"
sed -i '/^\s*#psk=/d' "$WPA_CONF"
chmod 600 "$WPA_CONF"
echo "wrote $WPA_CONF (passphrase hashed, not stored in plaintext)"
echo
echo "=== 3/4: systemd unit to set 4addr mode + start wpa_supplicant ==="
UNIT="/etc/systemd/system/wpa-4addr-${WIFI_IFACE}.service"
write_if_changed "$UNIT" "[Unit]
Description=wpa_supplicant on ${WIFI_IFACE} with 4addr mode enabled
Before=network-pre.target
Wants=network-pre.target
[Service]
Type=simple
ExecStartPre=/sbin/ip link set ${WIFI_IFACE} down
ExecStartPre=/sbin/iw dev ${WIFI_IFACE} set 4addr on
ExecStartPre=/sbin/ip link set ${WIFI_IFACE} up
ExecStart=/sbin/wpa_supplicant -i ${WIFI_IFACE} -c ${WPA_CONF}
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target"
systemctl daemon-reload
systemctl enable --now "wpa-4addr-${WIFI_IFACE}.service"
sleep 5
if ! iw dev "$WIFI_IFACE" link | grep -q "^Connected"; then
echo "WARNING: ${WIFI_IFACE} did not associate to '$WIFI_SSID' within 5s - check:" >&2
echo " systemctl status wpa-4addr-${WIFI_IFACE}.service" >&2
echo " journalctl -u wpa-4addr-${WIFI_IFACE}.service" >&2
exit 1
fi
echo "associated: $(iw dev "$WIFI_IFACE" link | grep '^Connected')"
echo
echo "=== 4/4: /etc/network/interfaces (bond0 active-backup: ${WIFI_IFACE} primary, ${LAN_IFACE} backup) ==="
IFACES_FILE="/etc/network/interfaces"
backup_file "$IFACES_FILE"
cat > "$IFACES_FILE" <<EOF
auto lo
iface lo inet loopback
iface ${LAN_IFACE} inet manual
iface ${WIFI_IFACE} inet manual
auto bond0
iface bond0 inet manual
bond-slaves ${WIFI_IFACE} ${LAN_IFACE}
bond-mode active-backup
bond-miimon 100
bond-primary ${WIFI_IFACE}
bond-updelay 200
bond-downdelay 200
auto vmbr0
iface vmbr0 inet static
address ${MGMT_ADDR}
gateway ${MGMT_GATEWAY}
bridge-ports bond0
bridge-stp off
bridge-fd 0
source /etc/network/interfaces.d/*
EOF
echo "wrote $IFACES_FILE"
echo
echo "Config staged but NOT applied yet - applying it live can drop your"
echo "current management connection for ~30-60s while the switch/AP"
echo "relearns MAC locations (expected, self-resolves; see"
echo "docs/06-pve-test-wifi-network.md). Recommended: run this from the"
echo "physical console, or arm a revert-on-timeout watchdog first, e.g.:"
echo
echo " cp ${IFACES_FILE}.bak.* /tmp/interfaces.orig # pick the backup just made"
echo " (sleep 45 && cp /tmp/interfaces.orig ${IFACES_FILE} && ifreload -a) &"
echo " ifreload -a"
echo " # then kill the backgrounded revert job once you confirm connectivity"
echo
echo "Apply now with: ifreload -a"
echo "Verify after with: cat /proc/net/bonding/bond0 ; ip -4 -br addr show vmbr0"