diff --git a/docs/README.md b/docs/README.md index 0ff22c46..4df75a51 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,6 +10,7 @@ disagree, the code wins and the doc is a bug. - [Talking to your node](COMMANDS.md) — the conversational command surface - [Seed Verification](SEED-VERIFICATION.md) — independently verify your 24-word backup - [Troubleshooting](troubleshooting.md) — common problems and how to resolve them +- [OpenWrt Gateway Setup](openwrt-gateway-setup.md) — pairing an OpenWrt router and provisioning TollGate pay-as-you-go WiFi - [Gamepad / Controller Navigation](GAMEPAD-NAV.md) — driving the UI from a controller - [Pine voice commands](pine-voice-commands.md) — the voice-satellite phrase surface diff --git a/docs/openwrt-gateway-setup.md b/docs/openwrt-gateway-setup.md new file mode 100644 index 00000000..f0e0392f --- /dev/null +++ b/docs/openwrt-gateway-setup.md @@ -0,0 +1,184 @@ +# OpenWrt Gateway Setup + +How to connect an OpenWrt router to an Archipelago node and, optionally, turn +it into a pay-as-you-go WiFi gateway with **TollGate**. Written for a node +operator following the UI; a developer-facing RPC/architecture reference is +at the bottom. + +This feature manages a **separate physical (or virtual) router** running +OpenWrt over SSH/UCI — it is not a containerized app. Archipelago itself does +not flash or install OpenWrt; you bring a router that already runs it. + +## What you get + +- **Status dashboard**: hostname, uptime, firmware release, WiFi interfaces, + WAN state — polled live from the router. +- **WAN/WISP wizard**: point the router's radio at an upstream WiFi network + (turns it into a wireless bridge/repeater) with DHCP + NAT configured for + you. +- **TollGate provisioning** (optional): installs the + [TollGate](https://tollgate.me) captive-portal package + (`tollgate-module-basic-go`) and stands up an `archipelago` SSID that + sells timed internet access for sats, settled against this node's local + Cashu mint. + +## Prerequisites + +1. **A router already flashed with OpenWrt.** Check the + [OpenWrt Table of Hardware](https://openwrt.org/toh/start) for your model + and follow OpenWrt's own install/flashing instructions — that part is + outside Archipelago's scope. +2. **SSH reachable.** Fresh OpenWrt images enable `dropbear` (SSH) on LAN by + default, listening as `root` with no password (or the password you set + during OpenWrt's first-boot wizard at `192.168.1.1`). Archipelago + connects with `ssh2` over a password (key-based auth is supported at the + library level but the UI only offers password so far). +3. **Same LAN as the Archipelago node**, at least for setup — plug the + router's LAN port into the same switch/network segment the node is on. +4. **For TollGate**: a running Cashu mint app (`nutshell`/`cashu-mint`) on + this node — provisioning defaults `mint_url` to + `http://:3338` and TollGate customers must be able to reach that + URL from outside the node's loopback. + +## Step 1: Open the OpenWrt Gateway panel + +1. In the Archipelago UI, go to **Server**. +2. Under the network status list, click **OpenWrt Gateway** + (`/dashboard/server/openwrt`). + +If no router has been connected before, you'll land on the connect form. + +## Step 2: Connect the router + +You have two options: + +- **Detect**: click **Detect** — this reads the node's own active wired + Ethernet interface, derives its subnet, and probes every host on it for + `TCP/22` + a valid `/etc/openwrt_release`. If it finds exactly one router + it fills in the host automatically; if it finds several you pick from the + list. A `/24` scan can take up to ~2 minutes (255 sequential probes at + 500 ms each on hosts that don't respond). +- **Manual**: type the router's LAN IP (commonly `192.168.1.1` on a router + freshly bridged in, or whatever address it has on your network) plus the + SSH username (default `root`) and password. + +Click **Connect**. On success the panel switches to the status dashboard and +the connection (host + credentials) is persisted server-side — you won't +need to re-enter them on future visits or from other views (e.g. the Home +dashboard's network tile also polls this without prompting again). + +> Credentials are stored in `router_config.json` under the node's data +> directory alongside other node config. There's no separate secrets +> vault entry for this yet — treat the router's SSH password like any other +> node-local config. + +## Step 3: (Optional) Configure WAN/WISP + +Use this to make the OpenWrt router pull its internet connection from an +upstream WiFi network instead of a wired uplink — useful for a +battery/off-grid TollGate node or extending coverage from an existing +network. + +1. From the status dashboard, start the **WAN setup** wizard. +2. **Scan** — the router's radio scans for visible networks (a few seconds + of SSH round-trips). +3. **Select network** — pick the upstream SSID from the list. +4. **Password** — enter the upstream network's WiFi password (encryption + defaults to `psk2`; leave blank only for open networks). +5. **DHCP / NAT** — review the LAN DHCP pool (default `.100`–`.249`) and + whether to enable NAT/masquerade on the WAN zone (leave this on unless + you have a specific reason not to). +6. **Connect** — this writes a `wwan` STA `wifi-iface` + `network` interface + over UCI, enables the radio if it was disabled (OpenWrt ships with + `radio0.disabled=1` on a fresh flash), and adds `wwan` to the WAN + firewall zone. + +The dashboard's WAN panel shows the resulting association state, assigned +IP, and whether the router currently has internet reachability. + +## Step 4: (Optional) Provision TollGate + +Once connected (and with a local Cashu mint app running), the dashboard +shows a **TollGate: not installed** state with a **Provision** action. + +1. Click **Provision TollGate**. +2. Set: + - **Price** (sats) + - **Step size** (minutes — billed in `step_size_ms` under the hood, + default 1 minute) + - **Minimum steps** a customer must buy at once + - **Mint URL** — leave as the auto-filled `http://:3338` unless + you're pointing at an external/different mint +3. Confirm. This can take a few minutes: the node downloads/installs + `tollgate-module-basic-go` on the router (via `opkg` on OpenWrt ≤24.x, or + a manual `.ipk` extract for 25.x images where `opkg` isn't available), + writes `/etc/tollgate/config.json`, and creates the `archipelago` SSID. +4. Once provisioned, the same panel lets you **edit** price/step/mint and + toggle TollGate enabled/disabled without reinstalling — changes are + pushed to `/etc/tollgate/config.json` and the daemon is restarted to + pick them up (it does not hot-reload). + +Anyone who joins the `archipelago` SSID sees TollGate's captive portal and +pays sats (via the configured Cashu mint) for timed access. + +## Reconfiguring or moving to a different router + +Use **Disconnect** on the status dashboard to return to the connect form — +this only clears the panel's client-side state, it doesn't delete the +persisted `router_config.json`, so reconnecting to the same router needs no +re-entry. To point at a *different* router, disconnect and connect with a +new host/credentials; the newly connected router becomes the persisted one. + +## Troubleshooting + +- **"No router configured"**: nothing has been connected yet, or the saved + config didn't include a host — go through Step 2 again. +- **Connect hangs or times out**: the router isn't reachable on `TCP/22` + from the node's network, or SSH auth failed. Confirm you can `ssh + root@` manually from the node (or a machine on the same LAN) + with the same credentials. +- **Router "moved networks" / stale saved host**: SSH/status calls are + bounded (5s TCP connect, 30s read/write) precisely so an unreachable + saved router can't stall other RPCs — but the dashboard will show a + connection error until you reconnect with the router's current address. +- **TollGate provision fails with "No pre-built TollGate package for + architecture..."**: your router's SoC isn't one of the prebuilt + `.ipk` targets (`mips_24kc`, `mipsel_24kc`, `aarch64_cortex-a53`, + `aarch64_cortex-a72`, `arm_cortex-a7`). You'll need a custom opkg feed or + to build `tollgate-module-basic-go` from source for your architecture. +- **TollGate download looks like it succeeded but provisioning still + fails**: the node sanity-checks the downloaded `.ipk` is at least 50 KB — + a smaller file usually means `wget` captured an HTML error page instead + (no internet access from the router, or a bad release URL). + +--- + +## Developer reference + +Backend crate: `core/openwrt` (`archipelago-openwrt`) — SSH/UCI plumbing, +WAN/WISP config, WiFi scanning, and TollGate install/config. See +[`architecture.md`](architecture.md) for where it sits in the workspace. + +RPC methods (`core/archipelago/src/api/rpc/openwrt.rs`, dispatched in +`core/archipelago/src/api/rpc/dispatcher.rs`): + +| Method | Purpose | +|---|---| +| `openwrt.scan` | Probe a subnet for OpenWrt routers (`subnet`, `prefix`, `ssh_user`, `ssh_password`) | +| `openwrt.get-status` | Full status: release, WiFi interfaces, WAN, TollGate state. No params → uses saved `router_config.json`; params with `host` also persist the connection | +| `openwrt.configure-wan` | Write WISP/WAN config (`ssid`, `password`, `encryption`, `dhcp_start`, `dhcp_limit`, `masq`) | +| `openwrt.scan-wifi` | Radio scan for visible upstream networks | +| `openwrt.provision-tollgate` | Install/reconfigure TollGate (`price_sats`, `step_size_ms`, `min_steps`, `mint_url`, `enabled`) | + +Note: these are distinct from the unrelated `router.*` methods +(`router.discover`, `router.configure`, `router.list-forwards`, ...), which +handle UPnP/NAT-PMP port forwarding on the node's own upstream home router — +not the OpenWrt gateway feature described here. + +Frontend: `neode-ui/src/views/server/OpenWrtGateway.vue`, routed at +`server/openwrt` (`neode-ui/src/router/index.ts`), linked from +`neode-ui/src/views/Server.vue`. + +Persisted connection state: `router_config.json` in the node's data +directory (`core/archipelago/src/network/router.rs`: +`load_router_config`/`save_router_config`).