Einstellungen → VPN → WireGuard → Clients: WireGuard-Datei des Kunden hochladen/einfuegen (editierbar), je Verbindung Schalter (an = auch nach Neustart, aus = bleibt aus), bearbeiten, Download, ℹ-Verlauf, loeschen; Log-Aufbewahrung im Reiter Einstellungen. Server-Reiter mit Anleitung fuer UDP 443 (NPM-Stream bzw. ohne Nginx), Server selbst folgt. Jede Verbindung ist ein eigener Container (aria-vpn-<id>, Image aus satellite/Dockerfile.vpn) mit eigenem Netz-Namensraum: WireGuard + normaler satellite.py (kind=vpn). Firewall im Container: Tunnel nur ausgehend, keine Verbindung Kundennetz → ARIA; ins ARIA-Netz nur RVS + Endpunkt. Routen ohne wg-quick, RVS-Weg nie durch den Tunnel (auch bei 0.0.0.0/0). Scan ueber den Tunnel aktiv per TCP (kein mDNS/ARP), FritzBox an Port 49000 erkannt. Satelliten-Ansicht: eigene Gruppe VPN-Satelliten. Lokal Ende-zu-Ende getestet (Kunde mit WG-Server + LAN, Fake-RVS): Tunnel, Verlauf, Scan, Sperren in beide Richtungen, Volltunnel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
163 lines
8.1 KiB
Markdown
163 lines
8.1 KiB
Markdown
# ARIA Satellit 🛰️
|
||
|
||
Ein eigenständiger **Außenposten-Container** für ein fremdes Netz (Büro, Werkstatt,
|
||
Ferienwohnung …). Er verbindet sich als RVS-Client in Stefans Raum und gibt ARIA
|
||
**Augen und Hände in genau diesem Netz** — ohne dass der Haupt-Stack dort stehen muss.
|
||
|
||
- **Augen (Info):** entdeckt Geräte via **mDNS/Zeroconf** (Chromecast, AirPlay, Sonos,
|
||
Drucker, NAS …), **SSDP/UPnP + DIAL** (Smart-TVs, Fire TV) und der **ARP-Tabelle**
|
||
(rohe Hosts). Meldet ARIA ein Live-Inventar.
|
||
- **Hände (Steuerung):** **DIAL-App-Launch** (z.B. YouTube-Video auf dem Fire TV),
|
||
**Wake-on-LAN**, generisches **HTTP**. Nur wenn freigeschaltet (siehe Sicherheit).
|
||
|
||
## ⚠️ Wichtig: der Satellit MUSS im echten Ziel-LAN laufen
|
||
|
||
Discovery (mDNS/SSDP-Multicast + ARP) funktioniert **nur**, wenn der Prozess
|
||
tatsächlich im selben LAN wie die Geräte hängt — z.B. `192.168.0.0/24`, wo der
|
||
Fire TV steht.
|
||
|
||
**Docker Desktop (Mac/Windows) geht NICHT.** Dort ist `network_mode: host` das Netz
|
||
der Docker-Linux-VM (NAT, `192.168.65.x` / `172.x`), **nicht** dein echtes LAN.
|
||
Der Satellit sieht dann nur Docker-Container statt der echten Geräte. (Der Satellit
|
||
erkennt das selbst und meldet eine ⚠-Warnung im Diagnostic + Log.)
|
||
|
||
Richtig deployen — zwei Wege:
|
||
|
||
**A) Linux-Box im Ziel-LAN mit Docker Engine** (empfohlen, z.B. Raspberry Pi / NUC im Büro):
|
||
```bash
|
||
cd satellite
|
||
cp .env.example .env # RVS-Zugang + SATELLITE_LOCATION
|
||
docker compose up -d --build
|
||
docker compose logs -f # "Netz: primary_ip=192.168.0.x" + "[scan] N Geraete"
|
||
```
|
||
`network_mode: host` (schon gesetzt) gibt hier echtes LAN + Multicast.
|
||
|
||
> **Fehler `KeyError: 'ContainerConfig'` beim Neubauen?**
|
||
> Das ist ein **Bug im alten `docker-compose` 1.29.2** (Python-Version), nicht im
|
||
> Satelliten: Beim *Ersetzen* eines bestehenden Containers mit Volume liest es ein
|
||
> Feld aus dem Image, das neuere Docker-Versionen nicht mehr schreiben. Zwei Fixes:
|
||
> ```bash
|
||
> docker compose up -d --build # v2 (mit LEERZEICHEN) — falls vorhanden
|
||
> # oder mit der alten Version: alten Container erst weg, dann neu anlegen
|
||
> docker-compose rm -sf satellite && docker-compose up -d --build
|
||
> ```
|
||
> Der `./data`-Ordner (Credentials, ADB-Schlüssel, APK-Cache) bleibt dabei erhalten —
|
||
> er ist ein Bind-Mount, kein Container-Volume.
|
||
|
||
**B) Nativ als Python-Prozess** (für Mac/Windows-Test oder ohne Docker) — läuft direkt
|
||
auf einer Maschine im Ziel-LAN. Das Script lädt die `.env` **selbst** (muss im
|
||
`satellite/`-Ordner liegen):
|
||
```bash
|
||
cd satellite
|
||
cp .env.example .env # RVS-Zugang + SATELLITE_LOCATION eintragen
|
||
pip install -r requirements.txt
|
||
python satellite.py # liest .env automatisch
|
||
```
|
||
(Echte Umgebungsvariablen haben Vorrang — `export RVS_TOKEN=...` überschreibt die
|
||
`.env`, falls du das lieber magst.)
|
||
|
||
`RVS_HOST/PORT/TLS/TOKEN` **identisch** zum Haupt-Stack (gleicher Raum, damit ARIA
|
||
den Satelliten erreicht). `SATELLITE_LOCATION` ist der Name, über den ARIA das Netz
|
||
anspricht („Büro").
|
||
|
||
**Satellit im selben Netz wie der RVS** (z.B. Rechenzentrum, direkt auf die
|
||
interne IP statt NAT-Hairpin): `RVS_HOST=<interne-ip>` + **`RVS_SNI=<zert-name>`**
|
||
(der Name, für den das Caddy-Zertifikat gilt). Ohne das scheitert TLS an
|
||
`tlsv1 alert internal error`. Zuhause / normal: `RVS_SNI` leer lassen.
|
||
|
||
**Kontrolle:** im Log/Diagnostic muss `primary_ip` im Ziel-LAN liegen
|
||
(`192.168.0.x`) — steht da `192.168.65.x` oder `172.x`, sitzt der Satellit im
|
||
falschen (Docker-)Netz.
|
||
|
||
## Als Dienst installieren (Autostart, ohne Docker)
|
||
|
||
Legt automatisch ein `.venv` an, installiert die Requirements und richtet einen
|
||
Dienst ein, der bei Boot startet und bei Absturz neu hochkommt. `.env` vorher
|
||
anlegen.
|
||
|
||
**Linux (systemd) / macOS (launchd):**
|
||
```bash
|
||
cd satellite
|
||
bash install.sh # installieren + starten
|
||
bash install.sh uninstall # entfernen
|
||
```
|
||
- Linux-Logs: `journalctl -u aria-satellite -f`
|
||
- macOS-Logs: `tail -f satellite.log` (evtl. „Lokales Netzwerk"-Zugriff erlauben)
|
||
|
||
**Windows (Scheduled Task) — PowerShell als Administrator:**
|
||
```powershell
|
||
cd satellite
|
||
powershell -ExecutionPolicy Bypass -File install.ps1 # installieren + starten
|
||
powershell -ExecutionPolicy Bypass -File install.ps1 -Uninstall # entfernen
|
||
```
|
||
- Log: `Get-Content -Wait satellite.log`
|
||
|
||
## So nutzt ARIA es
|
||
|
||
ARIA hat drei Brain-Tools:
|
||
- `satellite_list` — welche Netze/Satelliten sind online + was können sie.
|
||
- `satellite_devices(satellite)` — Inventar eines Netzes.
|
||
- `satellite_command(satellite, device, action, params)` — Aktion ausführen.
|
||
|
||
Beispiel „YouTube-Video auf dem Büro-Stick":
|
||
```
|
||
satellite_command(satellite="Büro", device="Fire TV",
|
||
action="dial.launch", params={"app":"YouTube","v":"<videoId>"})
|
||
```
|
||
|
||
## Sicherheit
|
||
|
||
Der Satellit scannt ein Netz **und** ist über einen Cloud-Relay erreichbar — deshalb:
|
||
|
||
- Reagiert **nur** auf den eigenen RVS-Raum (Token).
|
||
- **`CONTROL_ENABLED=false`** = reiner Info-Satellit (steuert nichts). Standard-sicher.
|
||
- Bei `true`: nur Aktionen aus **`CONTROL_ALLOWLIST`**, alles andere wird abgelehnt.
|
||
- Jede ausgeführte Aktion wird **geloggt**.
|
||
- Keine offenen Ports — reiner Client.
|
||
|
||
Empfehlung: in vertrauenswürdigen Netzen `CONTROL_ENABLED=true` mit enger Allowlist;
|
||
sonst `false` und nur beobachten.
|
||
|
||
## VPN-Satelliten (WireGuard, ohne Installation beim Kunden)
|
||
|
||
Ein VPN-Satellit ist ein Satellit, der **nicht im Kundennetz** läuft, sondern auf ARIA —
|
||
verbunden über einen WireGuard-Tunnel. Angelegt wird er in der Diagnostic unter
|
||
**Einstellungen → VPN → WireGuard**; im Reiter Satelliten steht er unter „VPN-Satelliten 🔐“.
|
||
|
||
**Clients** (ARIA wählt sich beim Kunden ein): die WireGuard-Datei des Kunden hochladen
|
||
oder einfügen, Namen vergeben, einschalten.
|
||
- **An** = Container mit Neustart-Automatik (verbindet sich nach einem Neustart wieder).
|
||
**Aus** = Container weg, Datei und Log bleiben — Kundennetze nur bei Bedarf.
|
||
- ✏️ bearbeiten · ⬇ Datei wieder herunterladen · ℹ Verlauf (wann verbunden, wie lange,
|
||
Datenmenge) · 🗑 löschen. Log-Aufbewahrung im Reiter Einstellungen.
|
||
|
||
**Wie es gebaut ist** (`Dockerfile.vpn`, `vpn_entry.py`, `diagnostic/vpn.js`):
|
||
- **Ein Container pro Verbindung** (`aria-vpn-<id>`, Netz `aria-vpn`, nur `NET_ADMIN`).
|
||
Eigener Netz-Namensraum: überlappende Kundennetze (überall `192.168.178.0/24`) stören
|
||
sich nicht, und lokale Satelliten im Host-Netz sehen die VPN-Netze nie.
|
||
- **Firewall im Container:** durch den Tunnel nur ausgehend, zurück kommen nur Antworten —
|
||
auch wenn die Gegenseite den Tunnel aufgebaut hat, führt keine Verbindung vom Kundennetz
|
||
zu ARIA. Ins ARIA-Netz/Internet darf der Container nur zum RVS und zum Tunnel-Endpunkt.
|
||
- `wg0` wird selbst aufgesetzt, nicht per `wg-quick`: `DNS`/`PostUp` aus fremden Dateien
|
||
werden ignoriert, und bei `AllowedIPs = 0.0.0.0/0` bleibt der Weg zum RVS trotzdem
|
||
außerhalb des Tunnels. Endpunkte mit Hostnamen (DynDNS) werden neu aufgelöst, solange
|
||
keine Verbindung steht.
|
||
- **Scan:** über WireGuard gibt es kein mDNS/SSDP/ARP — der VPN-Satellit klopft die Netze
|
||
aktiv ab (`SCAN_NETS`, Standard = AllowedIPs ohne `0.0.0.0/0`; typische Ports, auch
|
||
„Verbindung abgelehnt“ zählt als Gerät). FritzBoxen erkennt er an Port 49000.
|
||
- Daten pro Verbindung unter `aria-data/config/diag-state/vpn/<id>/` (`tunnel/wg.conf`
|
||
mit privatem Schlüssel, `status.json`, `events.jsonl`, `data/` = Zugangsdaten usw.).
|
||
|
||
**Voraussetzungen auf der ARIA-VM:**
|
||
- WireGuard-Kernelmodul: `modprobe wireguard` und dauerhaft
|
||
`echo wireguard > /etc/modules-load.d/wireguard.conf`
|
||
- Image bauen: `docker compose up -d --build vpn-satellite-image` (baut nur das Image,
|
||
der Container beendet sich sofort wieder — das ist richtig so).
|
||
|
||
**Server** (Kunden wählen sich bei ARIA ein, z.B. per FritzBox) kommt als nächster Schritt.
|
||
Erreichbar über **UDP 443** auf dem RVS-Hostnamen (TCP 443 bleibt beim RVS):
|
||
- *Mit Nginx Proxy Manager:* Hosts → Streams → Incoming Port 443, Forward Host = ARIA-VM,
|
||
**nur UDP** (TCP würde mit den Proxy-Hosts kollidieren); im NPM-Compose `'443:443/udp'`
|
||
ergänzen; am Router UDP 443 ebenfalls auf den NPM-Rechner.
|
||
- *Ohne Nginx:* den RVS-Port am Router zusätzlich als **UDP** direkt auf die ARIA-VM weiterleiten.
|