Archived
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
134 lines
4.5 KiB
Bash
Executable File
134 lines
4.5 KiB
Bash
Executable File
#!/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"
|