Cross-project overview of how WireGuard connects the Hydra streaming infrastructure. This is the central entry point — individual project docs cover their specific areas.
Hub-and-spoke WireGuard mesh with a single hub in Brussels (OVHcloud). All inter-site traffic routes through the hub.
┌─────────────────────────────┐
│ Hub (141.227.136.12) │
│ 10.10.0.1/24 │
│ OVHcloud Brussels │
│ │
│ Also runs: │
│ - hydraneckwebrtc controller│
│ - hydraneckwebrtc worker │
│ - coturn TURN server │
└──────────┬───────────────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
┌────────┴────────┐ ┌───────┴────────┐ ┌────────┴────────┐
│ Venues │ │ Air Units │ │ Neck Air │
│ 10.10.1-49.x │ │ 10.10.100.x │ │ 10.10.50-99.x │
│ + LAN subnet │ │ Windows bodies │ │ + LAN subnet │
│ (Omada/Gateway) │ │ (render nodes) │ │ (Mikrotik) │
└──────────────────┘ └─────────────────┘ └─────────────────┘
| Type | WG tunnel range | LAN range | Capacity | |------|----------------|-----------|----------| | Hub | 10.10.0.1/24 | -- | 1 | | Venues | 10.10.1-49.1/32 | 10.0.X.0/24 | 49 | | Neck Air | 10.10.50-99.1/32 | 10.0.X.0/24 | 50 | | Hydra Air | 10.10.100.1-254/32 | -- (no LAN) | 254 |
Manages the hub-and-spoke mesh from a single mesh.yaml inventory.
| What | Where |
|------|-------|
| Repo | github.com/cederikdotcom/hydraguard |
| Runs on | Hub server (141.227.136.12) |
| Source of truth | /root/.hydraguard/mesh.yaml |
| Generated config | /etc/wireguard/wg0.conf |
| API | http://hydraguard.experiencenet.com:8081 (keep stopped when not enrolling) |
| Binary | /usr/local/bin/hydraguard |
| Docs | runbook.md, DEPLOYMENT.md, OPERATIONS.md |
Key commands: hydraguard status, hydraguard air add <id>, hydraguard apply, hydraguard export
Provisions WireGuard on body machines via recipes. Calls hydraguard API to enroll peers.
| What | Where |
|------|-------|
| Repo | github.com/cederikdotcom/hydracluster |
| Runs on | hydracluster.experiencenet.com |
| Recipes | recipes/hydraguard-air-windows.yaml, recipes/hydraguard-air-linux.yaml |
| Config key | hydraguard.url + hydraguard.token in hydracluster config |
| Integration | pkg/api/handlers_body.go → provisionHydraGuardAir() calls /api/v1/air/provision |
When a node is assigned the hydraguard-air role:
Runs on the same box as the hub. Reaches body machines via WireGuard tunnel addresses (10.10.100.x) to pair with Sunshine on port 47990 and proxy WebRTC streams.
| What | Where |
|------|-------|
| Repo | github.com/cederikdotcom/hydraneckwebrtc |
| Runs on | Hub server (141.227.136.12) — same box as hydraguard |
| Connects to bodies via | WireGuard tunnel (10.10.100.x:47990 for Sunshine API) |
| TURN relay | coturn on same box, port 3478, forces iceTransportPolicy: relay |
The worker is on the hub's WireGuard interface (10.10.0.1), so it has direct mesh access to all peers without needing a separate WireGuard peer entry.
Runs on every body machine. Executes the hydraguard-air recipe steps that install and configure WireGuard.
| What | Where |
|------|-------|
| Repo | github.com/cederikdotcom/hydranode |
| Runs on | Every body machine (Windows/Linux) |
| WireGuard config (Windows) | C:\ProgramData\hydraguard-air\hydraguard-air.conf |
| Tunnel service (Windows) | WireGuardTunnel$hydraguard-air |
| Recipe execution | pkg/body/recipe.go → runPendingProvisions() |
1. Enroll body in hydracluster (web UI or API)
2. Assign hydraguard-air role
3. Hydracluster calls hydraguard API → peer added to mesh.yaml
4. Hydracluster sends recipe to hydranode agent
5. Hydranode installs WireGuard + writes config + starts tunnel
6. Peer handshakes with hub → body reachable at 10.10.100.x
7. hydraneckwebrtc can now create streaming sessions to the body
ubuntu@141.227.136.12)| File | Purpose |
|------|---------|
| /root/.hydraguard/mesh.yaml | Peer inventory (source of truth) |
| /root/.hydraguard/api.yaml | API server config (token, listen, auto_apply) |
| /etc/wireguard/hub.key | Hub WireGuard private key |
| /etc/wireguard/wg0.conf | Generated WireGuard config (from mesh.yaml) |
| /root/.hydraneckwebrtc/config.yaml | Worker config (sessions, TURN, controller URL) |
| /root/.hydraneckwebrtc-controller/config.yaml | Controller config (domain, admin token) |
| /root/.hydraneckwebrtc-turn-credential | coturn TURN credential |
| File | Purpose |
|------|---------|
| C:\ProgramData\hydraguard-air\hydraguard-air.conf | WireGuard tunnel config |
| C:\hydranode\hydranode.exe | Node agent binary |
| File | Purpose |
|------|---------|
| recipes/hydraguard-air-windows.yaml | Recipe: install WG, write config, start tunnel, configure Sunshine |
| recipes/hydraguard-air-linux.yaml | Same for Linux bodies |
| recipes/hydraguard-gateway-linux.yaml | Recipe for on-prem LAN gateways |
hydraguard status on the hubmesh.yamlhydracluster exec <nodeId> '& "C:\Program Files\WireGuard\wg.exe" show hydraguard-air'& 'C:\Program Files\WireGuard\wireguard.exe' /uninstalltunnelservice hydraguard-air
Start-Sleep 3
& 'C:\Program Files\WireGuard\wireguard.exe' /installtunnelservice 'C:\ProgramData\hydraguard-air\hydraguard-air.conf'
ping 10.10.100.xHydraGuard WG firewall rule allows remoteip=10.10.0.0/16hydracluster exec <nodeId> 'Get-Service SunshineService | Format-Table Name,Status'This can happen when the hydraguard API regenerates keypairs (issue #64). Symptoms: handshake never completes, transfer: 0 B received.
Fix:
hydracluster exec <nodeId> '& "C:\Program Files\WireGuard\wg.exe" show hydraguard-air'hydraguard export > /etc/wireguard/wg0.confwg set wg0 peer <correct-key> allowed-ips 10.10.100.x/32 (remove old key too)The hydranode agent reports the full distro name (e.g. Ubuntu 24.04) but recipes use os: linux. Fixed in hydracluster v1.9.32 — ensure the hydracluster server is on v1.9.32+.