# Alpine 5G Router – Web GUI Web interface with login and role-based access (admin and support). **One HTML page per function** (Status, Logs, Restart 5G, Config, Firewall, Routes, Users) with shared navigation. **As of Rev 2, the Web GUI includes integrated 5G connection management.** It now handles: - Modem AT commands via native Python (pyserial) - 5G connection lifecycle (connect, disconnect, reconnect) - Watchdog for automatic reconnection - NAT/firewall configuration The standalone `5g-router` service is no longer needed; `5g-webgui` is the recommended single service. ## Access - **URL:** `http://:5000` (e.g. `http://10.130.60.121:5000`) - **Default users:** - **admin** / **admin** – full access (config, firewall, routes, users, logs, status, restart 5G) - **support** / **support** – view status, view logs, restart 5G only (no config/firewall/users) **Change default passwords** after first login (admin: Users tab → set password). ## Permissions | Feature | Admin | Support | |--------------------|-------|--------| | View status | ✓ | ✓ | | View logs | ✓ | ✓ | | Restart 5G | ✓ | ✓ | | Connect/Disconnect | ✓ | ✓ | | Edit config | ✓ | – | | Edit firewall | ✓ | – | | View routes | ✓ | – | | Manage users | ✓ | – | ## Install and run ### On the device (after main install) ```bash # Install Python, Flask, and pyserial (Alpine) apk add python3 py3-flask pip install pyserial # If you used scripts/install.sh, Web GUI is already under /usr/local/share/5g-webgui # Enable and start the service: rc-update add 5g-webgui default service 5g-webgui start # Or run manually (foreground) cd /usr/local/share/5g-webgui && ./run.sh ``` ### From repo (development) ```bash cd web pip install -r requirements.txt # Flask and pyserial python3 app.py # Open http://localhost:5000 ``` ## API Endpoints for 5G Control | Endpoint | Method | Description | |----------|--------|-------------| | `/api/status` | GET | Connection status + modem info | | `/api/5g/status` | GET | Detailed connection status | | `/api/5g/connect` | POST | Manually connect 5G | | `/api/5g/disconnect` | POST | Manually disconnect 5G | | `/api/5g/restart` | POST | Disconnect then reconnect | ## Architecture ``` 5g-webgui service ├── Flask App (port 5000) ├── ATClient (pyserial → /dev/ttyUSB1) └── ConnectionManager ├── connect() - APN, PDP, IP, NAT ├── disconnect() ├── check_health() └── watchdog_loop() (background thread) ``` The connection auto-starts when the service starts (on first web request). If `WATCHDOG_INTERVAL` is set in `/etc/5g-router.conf`, a background thread periodically checks connection health and reconnects if needed. ## Security - Set **SECRET_KEY** in production: `export SECRET_KEY="your-random-secret"` before starting the app (or in the OpenRC service). - Use HTTPS in production (put the app behind nginx/caddy with TLS). - Change default admin and support passwords immediately. ## SQLite database The Web GUI uses **SQLite** (`web/data/alpine5g.db`) for: - **users** – login accounts (admin/support); migrated from `users.json` on first run if that file existed. - **iptables_rules** – firewall rules (table, rule line, enabled, order). On first load, if the DB is empty, rules are imported from `/etc/iptables/rules.v4`. - **static_routes** – static routes (destination, gateway, dev, metric). Apply runs `ip route add` for each enabled route. Firewall and Routes pages in the GUI list/add/edit/delete from the DB and provide an **Apply** button to write iptables and run `iptables-restore`, or run `ip route add` for routes. ## Files | Path (on device) | Purpose | |-------------------------------|----------------------------| | `/usr/local/share/5g-webgui/` | App and static files | | `/usr/local/share/5g-webgui/data/alpine5g.db` | SQLite DB (users, rules, routes) | | `/etc/init.d/5g-webgui` | OpenRC service | | `/var/log/5g-webgui.log` | Service log | ## Troubleshooting: Modem not up If the modem/WAN is not coming up (Status shows WAN state DOWN, no IP, or “No modem AT data”): **On the device**, run: ```bash /usr/local/bin/diag-modem-up.sh ``` (or `./scripts/diag-modem-up.sh` from the repo). It reports: - **5g-router service** status - **Config** (WAN_IF, AT_PORT, APN) - **Modem USB** (lsusb Fibocom; Mode 40 vs 41) - **WAN interface** (exists, state, IP) - **Default route** (via 5G or other) - **AT port** (exists, AT response OK?) - **Last log lines** from `/var/log/5g-router.log` - **Ping** test and suggested fixes Use this to see why connect-5g.sh failed (e.g. AT port not ready, wrong USB mode, no modem IP). ## Troubleshooting: No modem AT data If the Status page shows **“No modem AT data (check AT port)”**, run the diagnostic **on the device** (SSH or console): ```bash /usr/local/bin/diag-at-port.sh ``` (or `./scripts/diag-at-port.sh` from the repo). It reports: - User and groups (whether you’re in **dialout** for serial access) - Serial devices (`/dev/ttyUSB*`, permissions) - Modem in `lsusb` (Fibocom / 0e8d) - Config `AT_PORT` and whether it exists - Raw **AT** probe on each ttyUSB (which port returns **OK**) - Result of `modem-status-at.sh` **Typical fixes:** Add the web server user (e.g. the one running gunicorn) to group **dialout**; set `AT_PORT` in `/etc/5g-router.conf` to the port that responds (e.g. `/dev/ttyUSB0`); ensure modem is in USB mode 40 (RNDIS) so the AT port is present. ## Optional: run behind reverse proxy Example with **nginx** (apk add nginx): ```nginx server { listen 80; server_name router.local; location / { proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` Then access via `http://router.local` (port 80) instead of port 5000.