1
0
mirror of git://f0xx.org/android_cast synced 2026-07-29 04:38:53 +03:00

footer changes, remote access changes

This commit is contained in:
Anton Afanasyeu
2026-06-04 15:14:08 +02:00
parent f818ec4f0c
commit a29d84038e
30 changed files with 1612 additions and 92 deletions

View File

@@ -6,8 +6,10 @@ See the full proposal: [20260602_REVERSE_SSH_proposals_summary.md](20260602_REVE
<!-- toc -->
- [App (developer settings)](#app-developer-settings)
- [BE](#be)
- [WireGuard third-party](#wireguard-third-party)
- [BE control plane](#be-control-plane)
- [Production deploy (no new nginx HTTP paths)](#production-deploy-no-new-nginx-http-paths)
- [WireGuard data plane (UDP, not nginx)](#wireguard-data-plane-udp-not-nginx)
- [WireGuard third-party (Android)](#wireguard-third-party-android)
- [Tests](#tests)
<!-- /toc -->
@@ -19,29 +21,130 @@ See the full proposal: [20260602_REVERSE_SSH_proposals_summary.md](20260602_REVE
- Dropdown: **Disabled** | **WireGuard** | **RSSH (greyed — not selectable)**
- Pref key: `dev_remote_access_mode` (`AppPreferences`)
- **Disabled:** stops `RemoteAccessService`, tears down VPN, POST `type:ra` + `status:disable`
- **WireGuard:** foreground poll 17 min`RemoteAccessService` → BE `heartbeat.php`
- **Disabled:** notifies BE (`status:disable`), tears down VPN, stops `RemoteAccessService`
- **WireGuard:** foreground service; jittered poll **17 min**`heartbeat.php` with `type: ra`
- Heartbeat URL derived from crash upload URL (`…/api/heartbeat.php`)
- Session credentials persisted until `expires_at`; expiry tears down tunnel locally
- Optional full userspace WG via `third-party/wireguard-android` (`:tunnel`); otherwise `RemoteAccessVpnService` TUN fallback
## BE
## BE control plane
- Migration: `sql/migrations/007_remote_access.sql`
- Repository: `src/RemoteAccessRepository.php`
- Device API: `public/api/heartbeat.php` (`type: ra`)
- Admin API: `public/api/remote_access.php`
- UI: `?view=remote_access` (nav + hub card)
- RBAC: `remote_access_view`, `remote_access_operate`, `remote_access_admin`
Uses the **existing crashes vhost** — no new nginx `location` blocks for HTTP.
## WireGuard third-party
| Piece | Path |
|-------|------|
| Migration | `sql/migrations/007_remote_access.sql` |
| Repository | `src/RemoteAccessRepository.php` |
| WG peers | `src/WireGuardPeerProvisioner.php` (`wg set wg0 peer …`) |
| Device API | `public/api/heartbeat.php` (`type: ra`) |
| Admin API | `public/api/remote_access.php` |
| UI | `?view=remote_access` (nav + hub card) |
| RBAC | `remote_access_view`, `remote_access_operate`, `remote_access_admin` |
| RBAC admin UI | `?view=rbac` — global roles (root), company roles, privilege sets |
| Cron | `scripts/purge_remote_access.php` (hourly recommended) |
**RBAC rules (enforced in API)**
| Permission | Scope |
|------------|--------|
| `remote_access_view` | List devices/sessions/events in allowed companies |
| `remote_access_operate` | Open session; close **own** sessions |
| `remote_access_admin` | Whitelist devices; close **any** session in company |
| Global admin / root | All companies; root edits global roles via `?view=rbac` |
Privilege sets (`remote_access_user`, `remote_access_admin`) on `company_memberships.permissions_json` grant extra actions to `member` rows — see crash console README § RBAC.
**Flow**
1. Device polls with `{type:ra, status:enable, capabilities:[wireguard], tunnel_mode:wireguard}`.
2. BE upserts `remote_access_devices`; returns `wait` until device is **whitelisted** and operator **opens session**.
3. Next eligible poll returns `action:connect` + ephemeral WG credentials; BE runs `wg set` when `provision_peers=true`.
4. Disable from app → `status:disable` → closes sessions, removes peers.
**URLs (production)**
- Dashboard: `https://apps.f0xx.org/app/androidcast_project/crashes/?view=remote_access`
- Heartbeat: `…/crashes/api/heartbeat.php`
- Admin API: `…/crashes/api/remote_access.php`
## Production deploy (no new nginx HTTP paths)
After syncing PHP/JS to the BE tree under
`…/androidcast_project/android_cast/examples/crash_reporter/backend/`:
### 1. Database
Migration **007** (already applied on prod per deploy notes). Tables auto-create on SQLite dev; MariaDB should use the migration file once as root.
### 2. `config.php` — required keys
```php
'remote_access' => [
'wg_endpoint' => 'ra.apps.f0xx.org:51820', // public UDP hostname:port (FE DNAT → BE)
'wg_server_public_key' => '…', // wg show wg0 public-key on BE — REQUIRED
'wg_interface' => 'wg0',
'provision_peers' => true, // wg set on connect/close
'require_wg_tools' => true, // reject connect if wg genkey missing
'session_ttl_s' => 3600,
'min_poll_interval_s' => 45, // poll rate limit per device
],
```
**Critical:** `wg_server_public_key` must match the live `wg0` interface. Empty value makes connect credentials unusable on real devices.
### 3. BE packages and permissions
```sh
apk add wireguard-tools wireguard-tools-wg
# wg0 configured separately (Address 10.66.66.1/24, ListenPort 51820, etc.)
# PHP-FPM user must run wg when provision_peers=true (same as CLI test):
sudo -u www-data wg show wg0
```
### 4. Cron (session cleanup)
```cron
0 * * * * cd /var/www/.../backend && php scripts/purge_remote_access.php --hours=24
```
### 5. Verify
```bash
cd examples/crash_reporter/backend
chmod +x scripts/verify_remote_access_prod.sh scripts/test_remote_access_api.sh
./scripts/verify_remote_access_prod.sh
BASE=https://apps.f0xx.org/app/androidcast_project/crashes ./scripts/test_remote_access_api.sh
```
### 6. Browser
Hard-refresh after deploying `public/assets/js/remote_access.js`.
## WireGuard data plane (UDP, not nginx)
HTTP control plane stays on FE→BE `:80`. **WireGuard traffic is UDP** — configure at the **FE firewall/DNAT**, not in nginx:
```text
Internet UDP :51820 → FE DNAT → BE wg0 :51820
```
Hostname `ra.apps.f0xx.org` (or similar) should resolve to the FE public IP. Devices use `wg_endpoint` from config/connect payload.
## WireGuard third-party (Android)
```bash
bash scripts/init-wireguard-submodule.sh
./gradlew :app:assembleDebug # includes :tunnel when submodule present
```
Optional `:tunnel` module from `third-party/wireguard-android`. Without it, `WireGuardTunnelBridge` uses `RemoteAccessVpnService` (TUN fallback).
Without the submodule, `WireGuardTunnelBridge` uses `RemoteAccessVpnService` (TUN only — sufficient for lab; prefer `:tunnel` for production tunnels).
## Tests
```bash
./gradlew :app:testDebugUnitTest
./gradlew :app:testDebugUnitTest --tests 'com.foxx.androidcast.remoteaccess.*'
bash examples/crash_reporter/backend/scripts/test_rbac_api.sh
bash examples/crash_reporter/backend/scripts/test_remote_access_api.sh
BASE=https://apps.f0xx.org/app/androidcast_project/crashes bash examples/crash_reporter/backend/scripts/test_remote_access_api.sh
```