tela

module
v0.1.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 4, 2026 License: Apache-2.0

README

Tela

Secure remote access to TCP services (SSH, RDP, HTTP, etc.) through an encrypted WireGuard tunnel relayed over WebSocket. No admin privileges or TUN devices required on either end.

graph LR
    Client["Native Client"]
    Tela["tela"]
    Hub["hub.js"]
    Telad["telad"]
    Services["Local Services"]

    Client -->|TCP| Tela
    Tela <-->|"wss (WireGuard inside)"| Hub
    Hub <-->|ws| Telad
    Telad --> Services

    subgraph "WireGuard Tunnel (E2E encrypted)"
        direction LR
        Tela -.-|"gVisor netstack · Curve25519 + ChaCha20"| Telad
    end

How it works

tela (client) and telad (daemon) each create a userspace WireGuard tunnel using gVisor netstack — pure Go, no kernel TUN, no elevated privileges. The hub relays encrypted WireGuard datagrams between them over WebSocket, with automatic upgrades to faster transports when available:

Transport Path When
WebSocket tela → hub → telad Always works (even through corporate proxies)
UDP relay tela → hub:41820 → telad When outbound UDP is open
Direct P2P tela → telad When STUN hole-punch succeeds

The hub never sees plaintext — it relays opaque WireGuard ciphertext.

Components

Component Language Description
tela Go Client — connects to hub, establishes WG tunnel, binds localhost listeners
telad Go Daemon — registers with hub, exposes local services through WG tunnel
hub.js Node.js Relay — pairs agents with clients, relays WS/UDP, serves hub console

Quick start

Build
go build -o tela ./cmd/tela
go build -o telad ./cmd/telad
cd poc && npm install
Run locally (3 terminals)
# Terminal 1 — Hub
node poc/hub.js

# Terminal 2 — Daemon (exposes SSH + RDP)
./telad -hub ws://localhost:8080 -machine mybox -ports "22,3389"

# Terminal 3 — List machines
./tela machines -hub ws://localhost:8080

# Terminal 3 — Connect to a machine
./tela connect -hub ws://localhost:8080 -machine mybox

Or set environment variables to skip repeating flags:

export TELA_HUB=ws://localhost:8080 TELA_MACHINE=mybox
./tela connect
./tela machines
./tela services

Then connect: ssh localhost or mstsc /v:localhost

Portal login (hub name resolution)

If your hubs are registered on a portal (e.g., Awan Satu), log in once and use short hub names:

tela login https://awansatu.net    # authenticate once, config stored locally
tela machines -hub owlsnest         # hub name resolved via portal
tela connect -hub owlsnest -machine barn
tela logout                         # remove stored credentials

Short hub names are resolved via: (1) portal API, (2) local hubs.yaml fallback.

Run with Docker (production)
docker compose up --build -d

# With flags:
./tela connect -hub wss://your-hostname -machine barn

# Or log in to a portal and use hub names:
tela login https://your-portal.example
tela connect -hub your-hub -machine barn

See IMPLEMENTATION.md §8 for the full Docker Compose setup and Caddyfile.

Security

  • End-to-end encryption: WireGuard (Curve25519 key exchange, ChaCha20-Poly1305 data) between tela and telad. The hub is a blind relay.
  • Token authentication: -token flag on both sides; hub validates before pairing.
  • No admin required: gVisor netstack operates entirely in userspace — no TUN device, no root/Administrator.
  • Outbound-only: Both tela and telad initiate outbound connections to the hub. No inbound ports needed on either end.

Transport upgrade cascade

After the initial WebSocket connection, tela and telad automatically negotiate faster transports:

  1. UDP relay — Hub offers a UDP port alongside WebSocket. Both sides probe it; if reachable, WireGuard datagrams switch to UDP (eliminates TCP-over-TCP). Falls back to WebSocket on timeout.
  2. Direct tunnel — Both sides perform STUN discovery (RFC 5389) to learn their public IP:port, exchange endpoints via the hub, and attempt simultaneous UDP hole punching. On success, WireGuard datagrams flow peer-to-peer with zero relay overhead.

The cascade is fully automatic. Each tier falls through on failure with no user action.

Project structure

cmd/tela/          Client binary (subcommands: connect, machines, services, status, login, logout)
cmd/telad/         Daemon binary
internal/wsbind/   WireGuard conn.Bind over WebSocket/UDP/direct
poc/hub.js         Hub relay server
poc/www/           Hub console (web UI)
docker/            Dockerfile and Caddyfile for production

Glossary

Term Meaning
Hub Central relay that pairs agents with clients. Serves the hub console.
Hub Console Web interface for a hub (e.g., https://tela.awansatu.net/).
Agent / telad Long-lived daemon on a managed machine that registers with the hub.
Client / tela Binary on the user's laptop that tunnels through the hub to an agent.
Machine A named resource registered by an agent (e.g., barn).
Service A TCP endpoint exposed through a machine (e.g., SSH :22, RDP :3389).
Session An active encrypted tunnel between a client and an agent.
Portal Multi-hub dashboard (e.g., Awan Satu). The CLI resolves hub names via the portal API.
Awan Satu Cloud platform built on Tela (hub registry, relay, hosted hubs).

Documentation

License

Apache 2.0 — see LICENSE.

Directories

Path Synopsis
cmd
tela command
tela — Tela Client
tela — Tela Client
telad command
telad — Tela Daemon (WireGuard Agent)
telad — Tela Daemon (WireGuard Agent)
internal
wsbind
Package wsbind implements a WireGuard conn.Bind that transports WireGuard datagrams as binary WebSocket messages, with an optional upgrade to UDP relay for better performance.
Package wsbind implements a WireGuard conn.Bind that transports WireGuard datagrams as binary WebSocket messages, with an optional upgrade to UDP relay for better performance.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL