- README.md: project writeup (why, design, what's deployed, what was tested, lessons learned, rollback) - generic-guide.md: Debian/ifupdown-agnostic reusable pattern for phone- tether default-route failover, with gotchas and verification steps - files/: sanitized config snapshots (wpa_supplicant psk redacted) Context: ggs netz ag HFC maintenance window 2026-10-07. WiFi tether path live-tested both directions (connect/disconnect). USB path staged, same hook logic, not live-tested this session. |
||
|---|---|---|
| files | ||
| generic-guide.md | ||
| README.md | ||
Router02 — iPhone Tether Emergency Uplink
Status: Live and tested (WiFi path), staged-but-untested (USB path). Deployed 2026-10-07.
Why
PDC's primary uplink (VyOS, PPPoE via ggs netz ag) goes through a scheduled HFC
maintenance window. Router02 (Debian 13, PC Engines APU2e4) sits as a transit
box between VyOS and the internal network on a dedicated interlink VLAN
(enp3s0.1300, 10.10.8.2/31, peer 10.10.8.3). It's positioned to act as a
stopgap internet path via an iPhone's Personal Hotspot — either over USB
(ipheth) or WiFi — for the duration of any outage.
This is intentionally a temporary, manual-attach path. No HA, no automatic failback beyond what the kernel/dhcp client already gives you, no inbound services. Outbound-only for whatever's behind Router02's internal interfaces.
Design
Two interfaces, same logic, independently:
- WiFi (
wlp4s0→ SSIDh@x-P, the iPhone's hotspot name) — live-tested, confirmed working both directions. - USB (
enxfa10939f8b51,iphethdriver, MAC-stable interface name) — same hooks staged, not yet live-tested (no physical USB connect event during this session).
On interface up (phone connects):
- DHCP lease acquired from the phone (WiFi:
172.20.10.0/28typical iPhone hotspot range; USB: similar viaipheth). post-uphook installs a persistent static route for internal/PDC address space (10.0.0.0/8) via the original uplink peer (10.10.8.3) — so internal traffic never follows the default route onto the phone, even transiently.post-uphook removes the existing static default route via10.10.8.3. DHCP's own default route (installed at a high metric, e.g. 200 vs. the original's 50) becomes the only default — traffic now egresses via the phone.
On interface down (phone disconnects):
pre-downhook explicitly re-assertsdefault via 10.10.8.3(belt and suspenders — dhcpcd also removes its own route on interface teardown, but this closes any ordering gap).
No NAT/masquerade rules were added — Router02's existing nftables ruleset already masquerades outbound traffic by egress interface in the general case; this design works within that existing posture rather than building a parallel, interface-specific NAT stack.
No OSPF redistribution. The 10.0.0.0/8 static route and the default
route switch are both plain kernel routes, local to Router02, invisible to
FRR/OSPF. This was an explicit directive (Mykola, LL network authority) — a
route announced into OSPF for a consumer-grade, single-point, phone-dependent
uplink is a bad idea; other OSPF speakers shouldn't ever consider routing
through it.
What's deployed
/etc/network/interfaces—wlp4s0stanza,post-up/pre-downhooks (seegeneric-guide.mdfor the template)/etc/network/interfaces.d/60-iphone-tether—enxfa10939f8b51stanza, same hook pattern/etc/wpa_supplicant/wpa_supplicant-wlp4s0.conf— scoped to only the iPhone's hotspot SSID (a prior config also matched the regular home WiFi AP at higher priority, which associated by accident during testing — removed, see Lessons below)/etc/resolv.conf— unrelated bug found en route: file had zero nameservers (empty, dhcpcd-generated). Added1.1.1.1as a stopgap.
All changes backed up in place with .bak-<timestamp> suffixes before
editing. No destructive edits — every change was additive or clearly
reversible.
What was tested
# WiFi connect
$ ifup wlp4s0
...
wlp4s0: connected to Access Point: h@x-P
wlp4s0: leased 172.20.10.4 for 3600 seconds
$ ip route show default
default via 172.20.10.1 dev wlp4s0 proto dhcp src 172.20.10.4 metric 3005
$ ping -c2 1.1.1.1 # via phone, 1.1.1.1 ttl 56, ~30ms
$ ping -c2 10.0.2.42 # internal net, still direct, unaffected
# WiFi disconnect
$ ifdown wlp4s0
$ ip route show default
default via 10.10.8.3 dev enp3s0.1300 metric 50 # restored
Both directions confirmed working. Internal traffic was never observed transiting the phone during either state.
USB path has the identical hook logic staged in
/etc/network/interfaces.d/60-iphone-tether but was not live-tested — no
physical USB connect occurred this session. idevicepair trust was
established (idevicepair pair → SUCCESS, idevicepair validate →
SUCCESS) so the device trust relationship is ready; only the physical
cable-in event remains to verify.
Lessons / gotchas
- wpa_supplicant SSID priority matters more than you'd think. The tethering-interface's wpa_supplicant config initially had two network blocks: the iPhone hotspot (priority 1) and the regular home WiFi AP (priority 10). wpa_supplicant picked the higher-priority network — the home AP — which is not useless exactly (it's still a working uplink) but defeats the purpose of an iPhone-specific emergency path and silently masks whether the actual target (the phone) is even reachable. Fix: keep the tethering-dedicated wpa_supplicant config scoped to only the emergency SSID.
- A previous session had already deployed a more complex, OSPF-integrated
version of this (
udevrule →systemdoneshot service →tether-updownscript managing dedicated nftables tables andvtysh ... default-information originate). That stack was dormant (never triggered) but present on disk. It was found via MemPalace search after this session's simpler design was already live — a reminder thatmempalace_searchbefore touching infra is not optional, even mid-project, even same-night. The OSPF-originate behavior in that stack directly conflicted with an explicit "don't redistribute this into OSPF" directive given in this session. Removed (moved to/root/removed-stall-files-20261007/on Router02, not deleted) to leave a single, non-conflicting automation path. /etc/resolv.confcan silently go empty under dhcpcd-managed setups without obviously breaking connectivity (ICMP/raw IP worked fine, DNS quietly didn't). Worth a periodic sanity check independent of this project.
Rollback
To fully remove this setup and return to original state:
# WiFi
mv /etc/network/interfaces.bak-20261007-0157 /etc/network/interfaces
mv /etc/wpa_supplicant/wpa_supplicant-wlp4s0.conf.bak-20261007-0155 \
/etc/wpa_supplicant/wpa_supplicant-wlp4s0.conf
# USB
mv /etc/network/interfaces.d/60-iphone-tether.bak-20261007-0144 \
/etc/network/interfaces.d/60-iphone-tether
ifdown wlp4s0 2>/dev/null; ifup wlp4s0
(resolv.conf nameserver addition was left as-is — unrelated fix, not part of rollback scope.)
Generic guide
See generic-guide.md for a reusable, Hx/Router02-
agnostic version of this pattern — any Debian-family ifupdown box, any
upstream peer IP, any tether source.