docs(openwrt): OpenWrt Gateway setup guide + live-tested fixes #154

Merged
chaum merged 9 commits from docs/openwrt-gateway-setup into main 2026-09-07 07:24:34 +00:00
Collaborator

Summary

  • Adds docs/openwrt-gateway-setup.md: a full node-operator guide for pairing an OpenWrt router and provisioning TollGate pay-as-you-go WiFi, including a worked example flashing a GL.iNet AX3000 (Beryl AX / GL-MT3000) to stock OpenWrt.
  • Two real bugs found and fixed during a live install against physical hardware:
    • fix(openwrt): resolve opkg/apk via $PATH, not a hardcoded /usr/bin path — some official OpenWrt builds don't symlink /bin into /usr/bin, so a hardcoded path silently misreported "no package management" on a perfectly normal install.
    • fix(ui): stop sending an empty ssh_password over the saved router connection — the OpenWrt Gateway panel's action functions were falling back to never-populated local form refs instead of omitting params so the backend's saved-config fallback would apply, intermittently sending an empty password over an otherwise-working saved connection.
  • Bumps the pinned TollGate release v0.2.0 -> v0.5.0 (fix(openwrt): bump pinned TollGate release), which fixes an upstream crash-loop on an empty/broken default mint keyset and adds CBOR/V4 Cashu token support to the bundled captive-portal JS. Also adds a native .apk install fast-path for architectures with a native v0.5.0 build, replacing a fragile manual ar/tar .ipk extraction for those targets.
  • Docs additions from the live install/troubleshooting pass: the transient post-reboot apk update failed timing issue, the Ctrl+T/LuCI workaround needed to set a router's initial root password from a kiosk-mode display, and a "Verifying a successful install" section covering what a correct install actually looks like on the wire (nodogsplash bound to br-tollgate via its rendered config, not just UCI intent — installing by hand instead of through the UI/RPC flow leaves nodogsplash gating br-lan by default and locks out router admin access).

Test plan

  • Live-installed on physical GL.iNet GL-MT3000 hardware, flashed to stock OpenWrt 25.12.5, end to end through the UI: Connect → WAN/WISP (WISP mode) → Install TollGate.
  • Verified tollgate-wrt running, nodogsplash's rendered config gating br-tollgate (not br-lan), router LAN/SSH admin access unaffected, and TollGate's own mint probes succeeding.
  • Verified the two backend/frontend fixes against the live failure modes that originally surfaced them (opkg path resolution; empty-password submission with a saved connection).

🤖 Generated with Claude Code

https://claude.ai/code/session_0176RpCxFNS9ZaSJjL72W9Z5

## Summary - Adds `docs/openwrt-gateway-setup.md`: a full node-operator guide for pairing an OpenWrt router and provisioning TollGate pay-as-you-go WiFi, including a worked example flashing a GL.iNet AX3000 (Beryl AX / GL-MT3000) to stock OpenWrt. - Two real bugs found and fixed during a live install against physical hardware: - `fix(openwrt): resolve opkg/apk via $PATH, not a hardcoded /usr/bin path` — some official OpenWrt builds don't symlink `/bin` into `/usr/bin`, so a hardcoded path silently misreported "no package management" on a perfectly normal install. - `fix(ui): stop sending an empty ssh_password over the saved router connection` — the OpenWrt Gateway panel's action functions were falling back to never-populated local form refs instead of omitting params so the backend's saved-config fallback would apply, intermittently sending an empty password over an otherwise-working saved connection. - Bumps the pinned TollGate release `v0.2.0 -> v0.5.0` (`fix(openwrt): bump pinned TollGate release`), which fixes an upstream crash-loop on an empty/broken default mint keyset and adds CBOR/V4 Cashu token support to the bundled captive-portal JS. Also adds a native `.apk` install fast-path for architectures with a native v0.5.0 build, replacing a fragile manual `ar`/`tar` `.ipk` extraction for those targets. - Docs additions from the live install/troubleshooting pass: the transient post-reboot `apk update failed` timing issue, the Ctrl+T/LuCI workaround needed to set a router's initial root password from a kiosk-mode display, and a "Verifying a successful install" section covering what a correct install actually looks like on the wire (nodogsplash bound to `br-tollgate` via its *rendered* config, not just UCI intent — installing by hand instead of through the UI/RPC flow leaves nodogsplash gating `br-lan` by default and locks out router admin access). ## Test plan - [x] Live-installed on physical GL.iNet GL-MT3000 hardware, flashed to stock OpenWrt 25.12.5, end to end through the UI: Connect → WAN/WISP (WISP mode) → Install TollGate. - [x] Verified `tollgate-wrt` running, nodogsplash's rendered config gating `br-tollgate` (not `br-lan`), router LAN/SSH admin access unaffected, and TollGate's own mint probes succeeding. - [x] Verified the two backend/frontend fixes against the live failure modes that originally surfaced them (opkg path resolution; empty-password submission with a saved connection). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_0176RpCxFNS9ZaSJjL72W9Z5
ssmithx added 9 commits 2026-09-07 03:07:55 +00:00
Walks a node operator through pairing an OpenWrt router over SSH,
running the WAN/WISP wizard, and provisioning TollGate pay-as-you-go
WiFi — plus an RPC/architecture reference for developers. Distills
the openwrt crate, RPC handlers, and Vue panel into user-facing steps
that didn't exist anywhere in docs/ before.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176RpCxFNS9ZaSJjL72W9Z5
Worked example for the Beryl AX (GL-MT3000, mediatek/filogic) verified
against the OpenWrt wiki and firmware selector: exact sysupgrade image
filename, GL.iNet UI / LuCI flash path, post-flash SSH state, and the
U-Boot recovery procedure if the flash goes sideways.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176RpCxFNS9ZaSJjL72W9Z5
Step 4 described a single "Provision TollGate" action that prompts for
price/step/mint upfront. The real UI (OpenWrtGateway.vue) doesn't work
that way: "Install TollGate" is a one-click action with no config form
that installs with defaults, and price/step/mint/enabled are only
editable afterward via a separate "Edit" panel. Caught while walking
through a live install.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176RpCxFNS9ZaSJjL72W9Z5
opkg_check() and every opkg/apk invocation hardcoded /usr/bin/opkg and
/usr/bin/apk. Official OpenWrt images don't all symlink /bin into
/usr/bin — the glinet_gl-mt3000 24.10.2 build keeps them as separate
real directories with opkg living in /bin — so the check silently
missed a perfectly normal install and TollGate provisioning failed
with "this router's firmware may not support package management".

Switched every call to resolve through the router's own $PATH
(command -v / bare opkg / apk) instead. Reproduced and fixed live
against archy-x250-pa3, 2026-09-05.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176RpCxFNS9ZaSJjL72W9Z5
provisionTollgate/saveTollgateConfig/scanWifi/configureWan all fell
back to the Connect form's local refs (host/sshUser/sshPassword) when
connectedParams was null. Those refs only get populated if the form
was actually submitted this session — on a normal page load the
router reconnects via the server-persisted config instead, leaving
sshPassword at its default ''. Sending that as an explicit
(empty-but-present) ssh_password overrides the backend's saved-config
fallback, so every action auths with a blank password instead of the
real saved one.

Added authParams(): omit host/ssh_user/ssh_password entirely unless
connectedParams is actually set, same as the status poll already does.
Caught live: dropbear on archy-x250-pa3's router logged a single bad
password attempt at the exact moment "Install TollGate" was clicked,
sandwiched between periodic status-poll connections succeeding with
the real saved password.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176RpCxFNS9ZaSJjL72W9Z5
Observed live on archy-x250-pa3: right after WAN reconnects (fresh
boot or WAN reconfigure), the first Install attempt can fail with
"apk update failed ... router may have no internet access" purely
because the WiFi-uplink STA association hasn't finished yet — it's
not a real error, just retry a few seconds later. Also cross-referenced
the now-fixed /usr/bin/opkg hardcoding bug for anyone hitting it on an
older build.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176RpCxFNS9ZaSJjL72W9Z5
The install code was hardcoded to the Oct 2025 v0.2.0 release —
nine releases behind. Its changelog covers exactly the failures hit
live against archy-x250-pa3: a mint with an empty/broken keyset
crash-looped tollgate-wrt forever (v0.5.0 adds "graceful degradation
when Cashu mints fail"), and the bundled captive-portal JS had zero
CBOR support, hard-rejecting the cashuB (NUT-00 V4) tokens modern
wallets like Minibits generate by default.

Also: v0.5.0 publishes native .apk packages for aarch64_cortex-a53
and x86_64. install_tollgate_apk_native now prefers those directly
(apk add handles deps/postinst/uci-defaults itself) instead of always
falling back to the manual ar/tar .ipk extraction dance, which only
exists because earlier releases had no native apk build at all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176RpCxFNS9ZaSJjL72W9Z5
Archipelago's Connect form only authenticates with an existing password;
it has no flow for setting one on a fresh, passwordless router. On the
node's kiosk display there's no visible tab bar, so Ctrl+T to open a new
tab to LuCI is the way to set it before Connect will work.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176RpCxFNS9ZaSJjL72W9Z5
Adds a verification checklist (service running, nodogsplash bound to
br-tollgate not br-lan via the rendered config not just UCI, LAN/SSH
untouched, mint probes succeeding) plus notes on the dev-build test-mint
injection and the default-route race between a router's LAN interface
and the node's other uplinks before the router's own WAN/WISP is live.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176RpCxFNS9ZaSJjL72W9Z5
chaum merged commit c4ede96517 into main 2026-09-07 07:24:34 +00:00
Sign in to join this conversation.