From 9bf142074a2ff7b1eb665b470c748e39b34bc18b Mon Sep 17 00:00:00 2001 From: Andreas Wrede Date: Mon, 6 Jul 2026 16:59:34 -0400 Subject: [PATCH] port to Pi 4 'wan': onboard eth0+wlan0 as NM WANs, AP stack verbatim The USB hub (5GHz + 2.4GHz AP dongles, Starlink + LAN RTL8153s) moves over from wayback; MAC-derived wlx*/enx* names travel with it, so hostapd/ networkd/cockpit configs are unchanged. Pi diffs only: failover WAN list (wlan0 wifi 100, eth0 150, starlink USB 200, Koodo 300), cpu_thermal sensor, bcm2835 watchdog 10s, no HA DNAT/lease, and deploy.sh drops battery/lid/heartbeat/ZT-dns. Netplan reference in ap/50-van-wan.yaml. Co-Authored-By: Claude Fable 5 --- README.md | 6 + ap/50-van-wan.yaml | 24 +++ ap/nftables.conf | 12 -- ap/van-ap-dnsmasq.conf | 3 - deploy.sh | 73 +++------ dns/99-ztuga7c2kh.network.generated | 13 -- dns/zerotier-systemd-manager.service | 8 - dns/zerotier-systemd-manager.timer | 9 -- dns/zt-network.local.conf | 4 - dns/zt-search.conf | 3 - failover/config.json | 3 +- ha/ha_van.xml | 87 ---------- heartbeat/hbc.service | 16 -- heartbeat/hbc.yaml | 15 -- power/10-vanlink-nolid.conf | 6 - power/10-vanlink-watchdog.conf | 6 +- power/battery-config.json | 9 -- power/thermal-config.json | 9 +- power/van-battery | 231 --------------------------- power/van-battery.service | 13 -- 20 files changed, 63 insertions(+), 487 deletions(-) create mode 100644 ap/50-van-wan.yaml delete mode 100644 dns/99-ztuga7c2kh.network.generated delete mode 100644 dns/zerotier-systemd-manager.service delete mode 100644 dns/zerotier-systemd-manager.timer delete mode 100644 dns/zt-network.local.conf delete mode 100644 dns/zt-search.conf delete mode 100644 ha/ha_van.xml delete mode 100644 heartbeat/hbc.service delete mode 100644 heartbeat/hbc.yaml delete mode 100644 power/10-vanlink-nolid.conf delete mode 100644 power/battery-config.json delete mode 100644 power/van-battery delete mode 100644 power/van-battery.service diff --git a/README.md b/README.md index a053d55..9347791 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # vanlink — campervan router on `wayback` +> **This clone = the Pi 4 port (host `wan`, branch `wan`).** Onboard `eth0`+`wlan0` are +> NM-managed WANs (netplan `ap/50-van-wan.yaml`); the AP radios + wired LAN port arrive +> with the USB hub from wayback (same MAC-derived names, so all configs port verbatim). +> Dropped here: HA VM, battery/lid (no hardware), heartbeat + ZeroTier (not installed yet). +> Watchdog is 10s (bcm2835 max 15s); thermal watches `cpu_thermal`. + Turns **wayback** (Asus ZenBook UX391U, Ubuntu 24.04, zabbly kernel) into a self-contained campervan hub/router/AP: diff --git a/ap/50-van-wan.yaml b/ap/50-van-wan.yaml new file mode 100644 index 0000000..5bfc238 --- /dev/null +++ b/ap/50-van-wan.yaml @@ -0,0 +1,24 @@ +# /etc/netplan/50-van-wan.yaml — replaces cloud-init's 50-cloud-init.yaml. +# Both onboard interfaces are WANs handed to NetworkManager so van-failover can +# steer them (mirrors wayback where NM owns all WANs): wlan0 = wifi uplink +# (Wapana at home / campsite wifi), eth0 = ethernet uplink. The AP radios and +# the wired LAN port (USB dongles, wlx*/enx* MAC-named) are deliberately absent: +# systemd-networkd/hostapd own them, and van-ap-unmanaged.conf hides them from NM. +# Apply once by hand: netplan generate && netplan apply (flaps both uplinks). +network: + version: 2 + ethernets: + eth0: + renderer: NetworkManager + optional: true + dhcp4: true + wifis: + wlan0: + renderer: NetworkManager + optional: true + dhcp4: true + access-points: + "Wapana": + auth: + key-management: "psk" + password: "6e1335fd97165a7d2618bec19824be363a2766d7765f91aa14773d871eaa59dc" diff --git a/ap/nftables.conf b/ap/nftables.conf index 4ef329c..91ee99f 100755 --- a/ap/nftables.conf +++ b/ap/nftables.conf @@ -4,20 +4,8 @@ table ip van_router_nat delete table ip van_router_nat table ip van_router_nat { - chain prerouting { - type nat hook prerouting priority dstnat; policy accept; - # Home Assistant VM (ha_van) is bridged onto br0 at 10.42.0.50 — clients reach - # it directly. Keep the legacy http://10.42.0.1:8123 URL working for anything - # that bookmarked it (phones, ZT clients). - ip daddr 10.42.0.1 tcp dport 8123 dnat to 10.42.0.50:8123 - } chain postrouting { type nat hook postrouting priority srcnat; policy accept; ip saddr 10.42.0.0/24 oifname != "br0" masquerade - # Hairpin for the legacy 10.42.0.1:8123 DNAT when the client sits on the same - # subnet as the HA VM: without masquerade the VM would reply directly on br0 - # from 10.42.0.50 and the client (expecting 10.42.0.1) would drop it. ZT-sourced - # traffic doesn't match and doesn't need it — VM replies route back through us. - ip saddr 10.42.0.0/24 ip daddr 10.42.0.50 tcp dport 8123 oifname "br0" masquerade } } diff --git a/ap/van-ap-dnsmasq.conf b/ap/van-ap-dnsmasq.conf index 21dc0ce..1639585 100644 --- a/ap/van-ap-dnsmasq.conf +++ b/ap/van-ap-dnsmasq.conf @@ -5,8 +5,5 @@ domain-needed bogus-priv dhcp-authoritative dhcp-range=10.42.0.10,10.42.0.254,255.255.255.0,12h -# Home Assistant VM (libvirt ha_van, bridged onto br0) — pinned address, resolves -# as "homeassistant" via this dnsmasq; HAOS also announces homeassistant.local (mDNS). -dhcp-host=52:54:00:ad:0a:01,10.42.0.50,homeassistant dhcp-option=option:router,10.42.0.1 dhcp-option=option:dns-server,10.42.0.1 diff --git a/deploy.sh b/deploy.sh index e7ee87a..3f10252 100755 --- a/deploy.sh +++ b/deploy.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash -# Deploy vanlink configs/scripts from this directory to their system locations. +# Deploy vanlink configs/scripts (Pi 4 "wan" port) to their system locations. # Usage: cd ~/vanlink && sudo ./deploy.sh -# Idempotent. See README.md §4 for the two manual steps this does NOT do -# (zerotier-systemd-manager binary install, hostapd unmask). +# Idempotent. Netplan (onboard eth0+wlan0 = NM-managed WANs) is NOT touched here — +# reference copy in ap/50-van-wan.yaml, applied once manually (apply flaps uplinks). set -euo pipefail cd "$(dirname "$(readlink -f "$0")")" [ "$(id -u)" = 0 ] || { echo "Run with sudo (writes to /etc, /usr)."; exit 1; } @@ -11,13 +11,13 @@ echo "== access point ==" install -D -m0644 ap/hostapd.conf /etc/hostapd/hostapd.conf install -D -m0644 ap/hostapd-restart.conf /etc/systemd/system/hostapd.service.d/restart.conf install -D -m0644 ap/default-hostapd /etc/default/hostapd -install -D -m0755 ap/van-ap-watchdog /usr/local/sbin/van-ap-watchdog -install -D -m0644 ap/van-ap-watchdog.service /etc/systemd/system/van-ap-watchdog.service install -D -m0644 ap/hostapd-2g.conf /etc/hostapd/hostapd-2g.conf install -D -m0644 ap/hostapd-2g.service /etc/systemd/system/hostapd-2g.service install -D -m0644 ap/11-van-ap-2g.network /etc/systemd/network/11-van-ap-2g.network install -D -m0644 ap/van-ap-watchdog-2g.service /etc/systemd/system/van-ap-watchdog-2g.service install -D -m0644 ap/rtw88.conf /etc/modprobe.d/rtw88.conf +install -D -m0755 ap/van-ap-watchdog /usr/local/sbin/van-ap-watchdog +install -D -m0644 ap/van-ap-watchdog.service /etc/systemd/system/van-ap-watchdog.service install -D -m0644 ap/van-ap-dnsmasq.conf /etc/van-ap/dnsmasq.conf install -D -m0644 ap/van-ap-dnsmasq.service /etc/systemd/system/van-ap-dnsmasq.service install -D -m0644 ap/10-van-ap.network /etc/systemd/network/10-van-ap.network @@ -37,9 +37,6 @@ install -D -m0644 failover/van-failover.service /etc/systemd/system/van-failover install -D -m0755 failover/50-disable-eee /etc/NetworkManager/dispatcher.d/50-disable-eee install -D -m0644 failover/99-van-arp.conf /etc/sysctl.d/99-van-arp.conf -echo "== zerotier managed dns ==" -install -D -m0644 dns/zt-search.conf /etc/systemd/network/99-ztuga7c2kh.network.d/search.conf - echo "== cockpit plugin ==" install -d /usr/share/cockpit/vanrouter install -m0644 cockpit/vanrouter/* /usr/share/cockpit/vanrouter/ @@ -48,60 +45,32 @@ echo "== thermal monitor ==" install -D -m0755 power/van-thermal /usr/local/sbin/van-thermal install -D -m0644 power/thermal-config.json /etc/van-thermal/config.json install -D -m0644 power/van-thermal.service /etc/systemd/system/van-thermal.service - -echo "== battery monitor ==" -install -D -m0755 power/van-battery /usr/local/sbin/van-battery -install -D -m0644 power/battery-config.json /etc/van-battery/config.json -install -D -m0644 power/van-battery.service /etc/systemd/system/van-battery.service -# Pushover secrets live only on the system (0600), never in the repo. Seed from the -# template on first deploy; never clobber a filled-in file on later deploys. +# Pushover secrets live only on the system (0600), never in the repo. Path kept +# under /etc/van-battery/ for parity with wayback's van-thermal default. if [ ! -f /etc/van-battery/pushover.json ]; then install -D -m0600 power/pushover.json.example /etc/van-battery/pushover.json echo " -> seeded /etc/van-battery/pushover.json (EDIT IT: add Pushover token + user)" fi -echo "== power / never-sleep ==" -install -D -m0644 power/10-vanlink-nolid.conf /etc/systemd/logind.conf.d/10-vanlink-nolid.conf -# Belt-and-suspenders: a router must never suspend from idle, GUI, or a stray `systemctl suspend`. -systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target >/dev/null 2>&1 || true - echo "== hardware watchdog ==" install -D -m0644 power/10-vanlink-watchdog.conf /etc/systemd/system.conf.d/10-vanlink-watchdog.conf -echo "== heartbeat client (dead-man's switch) ==" -install -D -m0644 heartbeat/hbc.yaml /etc/hbc.yaml -install -D -m0644 heartbeat/hbc.service /etc/systemd/system/hbc.service -# The hbc binary itself (~/bin/hbc + venv) is installed once via the heartbeat -# project's installer — see README §4. Only start the service if it's present. -if [ ! -x /home/andreas/bin/hbc ]; then - echo " -> /home/andreas/bin/hbc not found; run 'sh ~/git/heartbeat/scripts/hb_install.sh client' (README §4)" -fi - echo "== apply ==" sysctl --system >/dev/null systemctl daemon-reload -# Re-exec PID1 so the system.conf.d watchdog drop-in takes effect (daemon-reload alone -# does NOT re-arm RuntimeWatchdogSec). Safe online: re-exec keeps all services running. +# Re-exec PID1 so the system.conf.d watchdog drop-in takes effect (daemon-reload +# alone does NOT re-arm RuntimeWatchdogSec). Safe online. systemctl daemon-reexec -# networkd here owns only the AP + ZT overlay (neither a real uplink), so its wait-online -# can never satisfy "online" and just burns its 120s timeout, stalling network-online.target -# and ZeroTier by ~2min every boot. Real uplink readiness is covered by NetworkManager-wait-online. +# networkd here owns only the AP radios + bridge + wired LAN port (no real uplink); +# its wait-online would just stall network-online.target. NM-wait-online covers WANs. systemctl mask systemd-networkd-wait-online.service >/dev/null 2>&1 || true -# pick up the lid drop-in (re-execs logind; does NOT drop the network) -systemctl restart systemd-logind >/dev/null 2>&1 || true systemctl unmask hostapd >/dev/null 2>&1 || true -systemctl enable regdomain.service hostapd hostapd-2g van-ap-dnsmasq nftables systemd-networkd van-failover van-thermal van-battery van-ap-watchdog van-ap-watchdog-2g >/dev/null 2>&1 || true -systemctl restart van-thermal van-battery -# Heartbeat: only enable/start once the client binary is installed (README §4). -if [ -x /home/andreas/bin/hbc ]; then - systemctl enable hbc >/dev/null 2>&1 || true - systemctl restart hbc -fi -# Pick up the unmanaged-devices change so NM releases the wired LAN port (drops its -# old 192.168.10.x lease); networkd then enslaves it to br0 on the restart below. +systemctl enable regdomain.service hostapd hostapd-2g van-ap-dnsmasq nftables systemd-networkd van-failover van-thermal van-ap-watchdog van-ap-watchdog-2g >/dev/null 2>&1 || true +systemctl restart van-thermal +# Pick up unmanaged-devices changes so NM releases/keeps the right interfaces. nmcli general reload 2>/dev/null || systemctl reload NetworkManager 2>/dev/null || true -# restart in dependency order: br0 + AP iface + LAN member first, then hostapd adds -# the wlan to br0, then dnsmasq binds br0, then NAT/failover +# restart in dependency order: bridge + members first, then hostapd enslaves the +# radios, then dnsmasq binds br0, then NAT/failover systemctl restart systemd-networkd systemctl restart hostapd hostapd-2g van-ap-dnsmasq nftables van-failover # AP watchdogs last, after hostapd is back up (they only ever restart a wedged hostapd) @@ -109,10 +78,10 @@ systemctl restart van-ap-watchdog van-ap-watchdog-2g networkctl reload 2>/dev/null || true echo -echo "Deployed. Verify:" +echo "Deployed. NOTE: until the USB hub (AP radios + LAN/Starlink adapters) is" +echo "plugged in, hostapd/hostapd-2g just retry every 5s — that is by design." +echo "Verify (with hub present):" echo " iw dev wlxc83a35a4ee55 info | grep -E 'ssid|channel|width'" +echo " iw dev wlxd8ec5e2faa8c info | grep -E 'ssid|channel|width'" echo " cat /run/van-failover/state.json" -echo " cat /run/van-thermal/state.json # CPU + NVMe temps" -echo " cat /run/van-battery/state.json # mains/battery + charge %" -echo " systemctl status hbc # heartbeat client -> hbd.wrede.pvt" -echo "Manual one-time steps (see README §4): zerotier-systemd-manager binary + 'zerotier-cli set allowDNS=1'." +echo " cat /run/van-thermal/state.json" diff --git a/dns/99-ztuga7c2kh.network.generated b/dns/99-ztuga7c2kh.network.generated deleted file mode 100644 index 1bcc0e5..0000000 --- a/dns/99-ztuga7c2kh.network.generated +++ /dev/null @@ -1,13 +0,0 @@ -# vim: ft=systemd -# --- Managed by zerotier-systemd-manager. Do not remove this comment. --- -[Match] -Name=ztuga7c2kh - -[Network] -Description=suspicious_house -DHCP=no -DNS=192.168.196.115 -DNS=192.168.10.5 -Domains=~wrede.pvt ~196.168.192.in-addr.arpa ~c.e.3.d.d.f.ip6.arpa -ConfigureWithoutCarrier=true -KeepConfiguration=static diff --git a/dns/zerotier-systemd-manager.service b/dns/zerotier-systemd-manager.service deleted file mode 100644 index 3f8ed54..0000000 --- a/dns/zerotier-systemd-manager.service +++ /dev/null @@ -1,8 +0,0 @@ -[Unit] -Description=Update zerotier per-interface DNS settings -Requires=zerotier-one.service -After=zerotier-one.service - -[Service] -Type=oneshot -ExecStart=/usr/bin/zerotier-systemd-manager diff --git a/dns/zerotier-systemd-manager.timer b/dns/zerotier-systemd-manager.timer deleted file mode 100644 index 0014869..0000000 --- a/dns/zerotier-systemd-manager.timer +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Update zerotier per-interface DNS settings - -[Timer] -OnStartupSec=1min -OnUnitInactiveSec=1min - -[Install] -WantedBy=timers.target diff --git a/dns/zt-network.local.conf b/dns/zt-network.local.conf deleted file mode 100644 index ed63c70..0000000 --- a/dns/zt-network.local.conf +++ /dev/null @@ -1,4 +0,0 @@ -allowManaged=1 -allowGlobal=0 -allowDefault=0 -allowDNS=1 diff --git a/dns/zt-search.conf b/dns/zt-search.conf deleted file mode 100644 index 567688f..0000000 --- a/dns/zt-search.conf +++ /dev/null @@ -1,3 +0,0 @@ -[Network] -Domains= -Domains=wrede.pvt ~196.168.192.in-addr.arpa ~c.e.3.d.d.f.ip6.arpa diff --git a/failover/config.json b/failover/config.json index 1fcafbb..b50fa67 100644 --- a/failover/config.json +++ b/failover/config.json @@ -9,7 +9,8 @@ "http://cp.cloudflare.com/" ], "wans": [ - { "name": "wifi", "device": "wlp1s0", "metric": 100 }, + { "name": "wifi", "device": "wlan0", "metric": 100 }, + { "name": "eth", "device": "eth0", "metric": 150 }, { "name": "starlink", "device": "enxd8ec5eeb3512", "metric": 200 }, { "name": "cellular", "connection": "Koodo", "metric": 300 } ] diff --git a/ha/ha_van.xml b/ha/ha_van.xml deleted file mode 100644 index 421ccc1..0000000 --- a/ha/ha_van.xml +++ /dev/null @@ -1,87 +0,0 @@ - - ha_van - af014c94-de20-4f52-8d6b-438f16cd82e6 - Home Assistant OS - 4194304 - 4194304 - 2 - - hvm - - - - - /usr/share/OVMF/OVMF_CODE_4M.fd - /var/lib/libvirt/qemu/nvram/ha_van_VARS.fd - - - - - - - - - - - - - destroy - restart - destroy - - - - - - /usr/bin/qemu-system-x86_64 - - - - -
- - -
- - -
- - - -
- - - -
- - - -
- - - - - - -
- - - - - - - - - - - - - - -