# VPN / Remote Access demo — gap report (2026-06-13)

<!-- doc-meta:start -->
| Field | Value |
|---|---|
| Author | Anton Afanasyeu |
| Revision | R1 |
| Creation date | 2026-06-13 |
| Last modification date | 2026-06-13 |
| Co-authored |  |
| Severity | medium |
| State | blocked by DEV |
| Document type | internal |
<!-- doc-meta:end -->

\newpage
\newpage

---


See also [REMOTE_ACCESS_VALIDATION.md](../REMOTE_ACCESS_VALIDATION.md), [REMOTE_ACCESS_IMPL.md](../REMOTE_ACCESS_IMPL.md).


---

---


---

## Table of contents

<!-- toc -->
- [Fixed today (prod BE)](#fixed-today-prod-be)
- [Fixed in repo (awaiting BE sync)](#fixed-in-repo-awaiting-be-sync)
- [Verified OK](#verified-ok)
- [Open (PO / device)](#open-po-device)
<!-- /toc -->

**Documentation index:** [README.md](README.md)

---

## Fixed today (prod BE)

- `config.php` **`remote_access` block** was missing — blocked real WireGuard connect credentials
- Installed via `examples/wireguard/install_be_remote_access.sh`
- **VPN traffic counters** in admin expanded device row (`WireGuardTrafficStats.php`)
- sudoers: `wg show wg0 dump` for nginx FPM user

## Fixed in repo (awaiting BE sync)

- **MariaDB `NULLS LAST`** — `listDevices()` ORDER BY broke dashboard on prod (HTTP 500); fixed to `(last_seen_at IS NULL), last_seen_at DESC`
- **Dashboard perf** — issue counts use indexed `reports.device_id` via `devices.external_id` instead of `payload_json LIKE`
- **Operational docs** — `REMOTE_ACCESS_IMPL.md` / `REMOTE_ACCESS_VALIDATION.md` now use prod **45340** and **172.200.2.0/16** (proposal doc still uses example 51820)
- **Orphan wg peer cleanup** — `WireGuardPeerProvisioner::pruneOrphanPeers()`, hourly via `purge_remote_access.php`; manual `scripts/sync_wg_peers.php --dry-run|--apply`
- **CLI defaults** — `ra_udp_debug.sh` / `ra_lib.sh` help and fallbacks match prod subnet

## Verified OK

- `wg0` on BE, endpoint `ra.apps.f0xx.org:45340`
- UDP 45340 open on public IP
- Heartbeat disable/enable API
- Mobile boot restores RA mode (`RemoteAccessCoordinator.onBootIfNeeded`)
- App wait-state + diagnostics (idle vs fail-reason); 30s heartbeat timeout

## Open (PO / device)

1. Full `ra_e2e_cli.sh` — needs admin login on laptop
2. UDP handshake + ping — needs phone or `ra_udp_debug.sh --apply`
3. SSH passthrough — RSSH track, not WG v1
4. Persistent traffic history — live stats only today
5. Whitelist + device E2E — human validation in progress

Journal: `/shared/journal/cluster0.journal.tsv` (tag `vpn-demo`).
