WireGuard over WebSocket. Single Go binary. Free public ingress through any CDN — no VPS rental, no Cloudflare Spectrum, no vendor lock-in.
WireGuard speaks UDP. Most free CDNs (Cloudflare Free, Fastly, Bunny) only proxy HTTP/WS. The expensive workarounds — Cloudflare Spectrum, a Hetzner UDP relay, Tailscale's DERP servers — either cost monthly money or lock you into a third party.
arena-tunnel solves it by encapsulating each WireGuard UDP datagram inside one binary WebSocket frame. The server unwraps frames back into UDP packets and hands them to a local WireGuard kernel interface. The CDN sees what looks like a long-lived WSS session — perfectly normal traffic for a chat app or a notification service.
Result: a stable, encrypted, NAT-traversing tunnel that costs $0/month and survives hostile networks (corporate proxies, captive portals, ISP-imposed CGNAT). Latency cost: ~80–150 ms one-way through a free CF tunnel from most of LATAM.
Client side Public CDN Server side
───────────────────── ──────────────────────── ──────────────────────────
arena-byoc arena-tunnel-server
├─ wireguard-go (TUN) ↑
└─ WSS dialer ──► wss://your-host/... ──► cloudflared ──► │ WS upgrade
(free tier) ▼
WireGuard kernel iface
│
▼
MASQUERADE / route
│
▼
Your internal network
Wire protocol: one WS binary frame ↔ one UDP datagram. No framing on top. Nothing to reverse-engineer. ~50 lines of glue in each direction. Read the full ARCHITECTURE.md →
No VPS, no Spectrum, no Tailscale subscription. Cloudflare Free tier carries all the traffic.
~6 MB Go binary per platform. No installer, no runtime, no config file required.
WireGuard ChaCha20-Poly1305 inside. TLS 1.3 outside. The CDN sees opaque WSS frames.
Hotel WiFi, corporate proxies, captive portals. WSS:443 passes where raw UDP can't.
The control plane bakes WG keys into each user's binary via -ldflags. No copy-paste keys.
Forks must remain open. Standard for security infra.
You bring your own C2. ARENA lends you a redirector and this tunnel so your team server never touches the public internet — the scenario only ever sees the redirector. Here is the whole path, account → first beacon.
Sign in at arena.adversario.cl with your issued account. Open the Weapons tab.
The Weapons tab hands you a per-OS download — the same single binary listed under Download. No compiling. Pick your platform and save it.
Run the binary as root / Administrator (it creates a TUN device — same requirement as WireGuard or Tailscale). It opens your browser; authorize as your ARENA user. Keys are brokered server-side — you never paste a private key.
# Linux / macOS — rename to arena-byoc for a cleaner shell experience
chmod +x arena-tunnel-client-linux-amd64
sudo mv arena-tunnel-client-linux-amd64 /usr/local/bin/arena-byoc
# Run once — pairs on first launch, then brings up the tunnel
sudo arena-byoc
# → opens https://arena.adversario.cl/byoc2/connect?code=XXXXXX
# → authorize in the browser
# → interface "arena-byoc" comes up (10.201.x.x)
# → route 10.128.0.0/9 (all scenario VMs) installed automatically
# → connection banner prints: tunnel IP · edge IP · listener · SNI · attribution cookie
arena-byoc status # show identity + tunnel state
sudo arena-byoc logout # stop tunnel + revoke device server-side
sudo arena-byoc pair --force # force re-pair (new device or revoked peer)
SSH / no browser? Add --no-browser — the code and URL are printed to stdout, open the URL on any device that has a browser.
Windows: unzip and run the .exe as Administrator (bundles wintun.dll). The browser-pairing step is identical.
Stand up your team server — Adaptix (built from upstream source), Cobalt Strike, whatever you run. The Bring-Your-Own panel shows your redirector host, listener port, and the __arena_tenant attribution cookie. Configure your HTTP listener / malleable profile to:
__arena_tenant=<value> cookie ARENA gives you — that's how your beacons get attributed to you and scored.Generate your payload, land it on a scenario host. Beacons travel:
scenario host → redirector → arena-tunnel → your TeamServer
Your team server stays private the whole time.
The Status page shows redirector reachability and your recent beacons. Meanwhile ARENA's OPSEC engine grades your tradecraft — noisy moves (Kerberoasting, DCSync, SharpHound sweeps, loud C2 egress) cost points. Stay quiet.
Not on ARENA, or running your own endpoint? The same binary pairs with any WireGuard server fronted by a WS-proxying CDN, using explicit flags instead of the browser flow.
Run alongside a WireGuard server on the same host. Expose the HTTP port through Cloudflare Tunnel (or any other CDN that proxies WS).
# 1. Standard WireGuard server config
[Interface]
PrivateKey = <server-priv>
ListenPort = 51820
Address = 10.201.0.1/16
[Peer]
PublicKey = <client-pub>
AllowedIPs = 10.201.0.2/32
# 2. Run arena-tunnel server
arena-tunnel-server --listen 127.0.0.1:8888 --wg 127.0.0.1:51820
# 3. Cloudflared ingress rule
# wss://wg.example.com → http://127.0.0.1:8888
# Linux / macOS — needs root for /dev/net/tun
sudo arena-byoc \
-priv <peer-priv-b64> \
-pub <server-pub-b64> \
-ip 10.201.0.2 \
-host wg.example.com
Or bake credentials in at build time via build.sh for a zero-config, one-binary UX (this is how ARENA generates each student's download).
Grab the matching binary from the latest release:
Most servers, desktops, x86 laptops.
Raspberry Pi 4/5, AWS Graviton, Oracle Ampere.
Pre-M1 Mac.
M1, M2, M3, M4 — all Apple Silicon Macs.
ZIP includes wintun.dll. Run as Administrator.
Verify integrity with sha256sum -c.
| What's protected | How |
|---|---|
| Tunnel payload (your traffic) | WireGuard ChaCha20-Poly1305 — end-to-end |
| The transport leg | TLS 1.3 between client/server and Cloudflare |
| WG private keys | Generated server-side, baked into binary, never in JSON |
| Peer authenticity | WireGuard noise handshake; static pubkeys |
The CDN sees connection metadata but not content. Read SECURITY.md for the full threat model.