Skip to content

paulmooreparks/tela

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

582 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Tela

Tela

CI Build Latest release License Go Version Downloads

Channels (see RELEASE-PROCESS.md for the model):

dev channel beta channel stable channel

Read the book for the full reference: getting started, configuration, deployment guides, use cases, and design rationale.

Tela is a free and open-source (FOSS) remote-access system that lets you reach TCP services on remote machines through an encrypted WireGuard tunnel. It works through firewalls, NATs, and corporate proxies without requiring inbound ports, VPN software, kernel drivers, or administrator privileges on either end.

You run a small agent (telad) on the machine you want to reach. It connects outbound to a relay hub (telahubd). From any other machine, you run the client (tela) or the desktop app (TelaVisor) to connect through the hub. The hub pairs the two sides and relays encrypted traffic between them. It never sees the plaintext.

graph LR
    Client["Native Client"]
    Tela["tela"]
    Hub["telahubd"]
    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
Loading

Why Tela

Most remote-access tools require at least one of the following: a VPN that needs administrator privileges to install, inbound firewall rules on the target machine, a cloud account with a specific vendor, or a TUN/TAP kernel driver. Tela requires none of these.

Tela uses WireGuard for encryption, but it runs WireGuard entirely in userspace through gVisor's network stack. There is no kernel module, no TUN device, and no need for root or Administrator. Both the agent and the client make outbound connections to the hub, so neither side needs to open inbound ports or configure port forwarding.

The hub acts as a blind relay. It forwards encrypted WireGuard packets between the agent and the client without being able to decrypt them. Even if the hub is compromised, session contents are not exposed.

Tela tunnels any TCP service. SSH, RDP, HTTP, PostgreSQL, SMB, VNC, or any other protocol that runs over TCP can be reached through a Tela tunnel. The hub does not need to understand the protocol being tunneled.

How it works

The agent (telad) and the client (tela) each create a userspace WireGuard tunnel using gVisor netstack. The hub (telahubd) relays encrypted WireGuard datagrams between them over WebSocket. After the initial connection, Tela automatically negotiates faster transports when available:

Transport Path When it is used
WebSocket tela -> hub -> telad Always available, works through corporate proxies
UDP relay tela -> hub:41820 -> telad When outbound UDP to the hub is open
Direct P2P tela -> telad When STUN hole-punching succeeds

Each transport tier falls back to the previous one automatically on failure. The hub always relays opaque WireGuard ciphertext regardless of which transport is active.

Components

Tela is built from three Go binaries and an optional desktop client:

Component Description
tela Client CLI. Connects to a hub, establishes a WireGuard tunnel, and binds services on 127.0.0.1 with mapped ports so native clients (ssh, mstsc, psql, etc.) can connect.
telad Agent daemon. Runs on the target machine, registers with the hub, and exposes local TCP services through the tunnel. Includes a built-in HTTP gateway for path-based routing to multiple services.
telahubd Hub server. Pairs agents with clients, relays encrypted traffic, and serves a built-in web console.
TelaVisor Desktop client. A graphical interface for managing connections, browsing remote files, and administering hubs. Built with Wails v2 (Go + JavaScript).

All three binaries are single-file executables with no runtime dependencies. They run on Windows, Linux, and macOS.

TelaVisor

TelaVisor wraps the tela CLI in a graphical interface. It manages hub credentials, connection profiles, and real-time tunnel status without requiring terminal access. You select which services to connect to, click Connect, and monitor tunnel state as it updates live.

TelaVisor Status tab, connected

TelaVisor uses a two-mode layout. Clients mode manages connections, profiles, files, and client settings. Infrastructure mode provides full hub and agent administration: hub settings, machines, per-identity access, tokens, history, agent configuration, remote management, and credential storage.

The Hub Settings view exposes lifecycle controls (View Logs, Update, Restart) and shows version badges that compare the running hub against the latest GitHub release. The same pattern is mirrored on the Agents tab for telad instances.

TelaVisor Hub Settings

The Tokens view lets you create identities, rotate tokens, delete identities, and generate one-time pairing codes that users or agents can exchange for permanent tokens.

TelaVisor Hubs, Tokens

The Agents tab lists all telad instances visible across your configured hubs without requiring an active tunnel connection. Each agent shows version, services, file share configuration, and management controls. The Software row updates the agent binary in place by downloading from GitHub releases and restarting through the OS service manager.

TelaVisor Agents tab

The Files tab provides a built-in file browser for machines with file sharing enabled. You can upload, download, rename, move, and delete files on remote machines through the encrypted tunnel. The file list updates in real time as changes happen on the remote machine.

TelaVisor Files tab

The persistent log panel at the bottom of the window collects output from TelaVisor itself, the tela process, the Commands log (every API call and CLI command issued), and any number of dynamic tabs you attach via the + button. Attaching a hub or agent log source streams the remote log buffer through the hub admin API. Open log tabs are remembered between sessions.

TelaVisor log panel attach popover

See the TelaVisor chapter in the book for the full reference, or TelaVisor.md for a short overview.

Quick start

Build

go build -o tela ./cmd/tela
go build -o telad ./cmd/telad
go build -o telahubd ./cmd/telahubd

Run locally (three terminals)

Start the hub:

./telahubd

Start the agent on the machine you want to reach. This example exposes SSH and RDP:

./telad -hub ws://localhost -machine mybox -ports "22:SSH,3389:RDP"

From a third terminal, list the available machines and connect:

./tela machines -hub ws://localhost
./tela connect -hub ws://localhost -machine mybox

You can also connect by service name:

./tela connect -hub ws://localhost -machine mybox -services ssh

Once connected, services bind on 127.0.0.1 with mapped ports. Use the address and port shown in the tela connect output with your usual tools:

ssh user@localhost -p 10022
mstsc /v:localhost:13389

To avoid repeating flags, set environment variables:

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

Hub remotes (name resolution)

If your hubs are listed on a directory service, you can add it as a remote and use short hub names:

tela remote add awansaya https://awansaya.net   # configure once
tela machines -hub myhub                         # short name resolved via remote
tela connect -hub myhub -machine mybox

Short hub names are resolved by querying configured remotes first, then falling back to the local hubs.yaml file.

Connection profiles

You can define all your tunnels in a single YAML file and open them in parallel with one command:

# ~/.tela/profiles/work.yaml
connections:
  - hub: corp-hub
    machine: prod-web01
    token: ${CORP_TOKEN}
    services:
      - remote: 22
      - remote: 8080

  - hub: corp-hub
    machine: staging-db
    token: ${CORP_TOKEN}
    services:
      - name: postgres
tela connect -profile work
# Opens parallel tunnels to both machines. Each auto-reconnects independently.
# Services bind on 127.0.0.1 with mapped ports shown in the connect output.

Profiles support environment variable expansion (${VAR}), service name resolution, deterministic loopback addressing, and connections across multiple hubs. See REFERENCE.md section 7 for the full profile schema.

Enable authentication (recommended)

On first startup, the hub auto-generates an owner token (secure by default). For Docker deployments, you can bootstrap authentication with an environment variable:

# 1. Generate an owner token
openssl rand -hex 32

# 2. Add to docker-compose.yml environment:
#    - TELA_OWNER_TOKEN=<your-token>

# 3. Redeploy
docker compose up --build -d

# 4. Manage remotely from any workstation:
tela admin access -hub wss://your-hub -token <owner-token>
tela admin tokens add bob -hub wss://your-hub -token <owner-token>
tela admin access grant bob barn connect -hub wss://your-hub -token <owner-token>

The tela admin access command shows a unified view of all identities and their per-machine permissions. See CONFIGURATION.md for the full auth schema and tela admin reference.

Authentication and security

Tela is designed to be secure by default. The hub auto-generates an owner token on first startup, and all administrative operations require authentication.

End-to-end encryption. All traffic between the client and agent is encrypted with WireGuard using Curve25519 for key exchange and ChaCha20-Poly1305 for data encryption. The hub relays opaque ciphertext and cannot read tunnel contents.

Token-based access control. The hub uses named token identities with four roles: owner, admin, user, and viewer. The unified access API (/api/admin/access) joins tokens and their per-machine permissions (register, connect, manage) into a single resource. A wildcard ACL (*) applies to all machines. Owner and admin tokens have implicit access to all machines.

Remote management. Owners and admins can manage access remotely using tela admin access (unified view), tela admin access grant (set permissions), and tela admin access revoke (remove permissions). No shell access to the hub is required.

Credential storage. The tela login and telad login commands store hub tokens in a local credential file (0600 permissions) so you do not need to pass tokens on every command.

One-time pairing codes. Administrators can generate short-lived pairing codes (e.g., ABCD-1234) for users and agents. Codes are single-use, time-limited (10 minutes to 7 days), and replace the need to copy 64-character hex tokens manually. Users paste a code in TelaVisor or run tela pair to exchange it for a permanent token.

File sharing. The agent can expose a sandboxed directory for file transfer through the tunnel. Upload, download, rename, move, and delete operations are available via the CLI (tela files) or the TelaVisor Files tab. File sharing is off by default and must be explicitly enabled per machine. Extension filtering, size limits, and read-only mode are configurable.

Explorer integration. tela mount starts a WebDAV server that mounts Tela file shares as a local drive. On Windows, run tela mount -mount T: to map a drive letter. On macOS and Linux, run tela mount -mount ~/tela to mount to a directory. Each connected machine with file sharing enabled appears as a top-level folder. No kernel drivers or third-party software required.

Gateway. The agent can run a built-in HTTP reverse proxy that routes requests by URL path to different local services. This lets you expose a multi-service application (web UI, REST API, metrics) through a single tunnel port without needing nginx, Caddy, or any other reverse proxy. See howto/gateway.md for a full walkthrough or REFERENCE.md for the configuration reference.

Upstreams. The agent can forward a service's outbound dependency calls to configurable targets. Services call localhost:PORT and telad routes to the real dependency, which can be local, on another machine, or in a different environment. This lets developers rewire service dependencies by editing a YAML file without changing code, containers, or remote environments. See REFERENCE.md for configuration details.

No admin required. All three binaries run in userspace. gVisor netstack provides a full WireGuard implementation without kernel modules, TUN devices, or elevated privileges.

Outbound-only. Both tela and telad initiate outbound connections to the hub. No inbound ports are needed on either end.

See CONFIGURATION.md for the full auth schema and admin API reference. See howto/telad.md for agent onboarding examples.

Networking and port requirements

Tela is outbound-only for agents and clients. Only the hub needs to be reachable from the internet.

At a minimum, the hub must accept inbound HTTPS/WebSocket traffic from both tela (client) and telad (agent). The agent must be able to reach the services it exposes, either on localhost or via a target host in gateway mode.

Component Inbound Outbound Notes
Hub (telahubd) TCP 443 for HTTPS + WebSocket None Optional: UDP 41820 for the UDP relay.
Agent (telad) None TCP 443 to the hub Optional: outbound UDP to hub:41820 and STUN.
Client (tela) None TCP 443 to the hub Optional: outbound UDP to hub:41820 and STUN. Binds loopback addresses for apps.
Portal TCP 80/443 for the portal UI and API HTTPS to each hub's /api/status and /api/history Proxies hub requests server-side. Browsers do not contact hubs directly.

See also: howto/networking.md, howto/hub.md, howto/telad.md.

Running as an OS service

All three binaries support native OS service management on Windows (SCM), Linux (systemd), and macOS (launchd). Configuration is stored in a YAML file in a system-wide directory. To reconfigure, edit the file and restart the service.

# Install telad as a service
telad service install -config telad.yaml
telad service start

# Install telahubd as a service
telahubd service install -name myhub -port 80
telahubd service start

# Install tela client as a service (always-on tunnel)
tela service install -config myprofile.yaml
tela service start

# Reconfigure: edit the config, then restart
telad service restart
telahubd service restart
tela service restart

See howto/services.md for full details.

Registering with a portal

Hub operators can register their hub with a Tela portal (such as Awan Saya) so that users who query the portal can discover the hub by name:

telahubd portal add awansaya https://awansaya.net
telahubd portal list
telahubd portal remove awansaya

The portal add command discovers the portal's hub directory endpoint via /.well-known/tela (RFC 8615), registers the hub via its API, and stores the association in the hub config. See Hub directories and portals in the book for the full explanation.

Project structure

cmd/tela/          Client CLI (connect, machines, services, status, remote, admin, files, profile, pair, service)
cmd/telad/         Agent daemon
cmd/telahubd/      Hub server
cmd/telagui/       Desktop client (Wails v2 app)
internal/service/  Cross-platform OS service management (Windows SCM, systemd, launchd)
internal/wsbind/   WireGuard conn.Bind over WebSocket/UDP/direct
console/           Hub console static files (embedded into telahubd at build time)
howto/             How-to guides (hub setup, services, networking, use cases)

Tradeoffs of the userspace approach

Running WireGuard in userspace is what makes Tela work without admin rights, kernel drivers, or TUN devices. It comes with real tradeoffs. An optional kernel TUN mode that removes most of these limitations is on the roadmap as a post-1.0 feature.

Performance. Kernel WireGuard processes packets in the kernel network stack with zero copies between kernel and userspace. Tela's gVisor netstack does the same work in a Go process, which means system calls for every packet and garbage collector pauses. For bulk throughput (large file transfers, streaming), kernel WireGuard will saturate a gigabit link where Tela's userspace stack tops out lower. For the interactive protocols Tela targets (SSH, RDP, database queries, HTTP APIs), the difference is not noticeable.

TCP only, no raw IP routing. Kernel WireGuard creates a real network interface that the OS routing table can use for arbitrary IP traffic, including UDP, ICMP, and multicast. Tela has no TUN device and no routing table entry. It tunnels TCP services only. No ping, no UDP, no "put my whole machine on the remote network." This is a deliberate design choice: the simplicity of TCP-only is what makes the no-admin, no-driver model work.

No OS-level integration. A kernel VPN interface is visible to every process on the machine. Tela's tunnels are visible only to processes that connect to the loopback ports Tela binds on 127.0.0.1. This is usually a feature (less invasive, does not interfere with existing networking), but it means you cannot bridge networks or run services that require a real interface across the tunnel.

Single-process failure domain. If the tela process crashes, all tunnels drop. A kernel WireGuard interface persists independently of any userspace process. Tela mitigates this by supporting OS service managers (systemd, Windows SCM, launchd) that restart the process automatically.

If you need a full Layer 3 VPN with arbitrary IP routing and line-rate throughput today, use kernel WireGuard or a tool built on it. If you need to reach specific TCP services through firewalls without installing drivers or requiring admin rights, the userspace tradeoff is worth it.

Glossary

Term Meaning
Group One hub and all the agents connected to it. The basic operational unit. Analogous to a carrier battle group: the hub is the carrier, the agents are the support vessels.
Fleet A collection of groups. A single-hub deployment is one group; a multi-site or multi-environment deployment is a fleet.
Hub The central relay server (telahubd). Pairs agents with clients and relays encrypted traffic. Also serves the hub console.
Hub Console The web interface served by a hub (e.g., https://hub.example.com/). Shows registered machines, services, and session history.
Agent / telad A long-lived daemon on a managed machine. Registers with the hub and exposes local services through the tunnel.
Client / tela The CLI tool on the user's machine. Connects through the hub to an agent and binds services on 127.0.0.1 with mapped ports for native clients.
TelaVisor The desktop client. Provides a graphical interface for connections, file browsing, and hub administration.
Machine A named resource registered by an agent (e.g., barn). One agent can register one or more machines.
Service A TCP endpoint exposed through a machine (e.g., SSH on port 22, RDP on port 3389).
Session An active encrypted tunnel between a client and an agent. Each session gets its own WireGuard keypair and virtual IP address.
Portal A multi-hub dashboard and directory service. Implements the hub directory API (/api/hubs). Can be added as a remote with tela remote add.
File Share A sandboxed directory on an agent machine that can be browsed, uploaded to, and downloaded from through the tunnel.
Gateway A built-in HTTP reverse proxy in telad that routes requests by URL path to different local services through a single tunnel port.
Upstream A dependency route in telad that forwards outbound service calls from localhost to a configurable target, providing a virtual dispatch layer for service-to-service communication.

Community

For confirmed bugs, open an issue. For security vulnerabilities, see SECURITY.md.

Documentation

License

Apache 2.0. See LICENSE.

About

FOSS remote-access and connectivity fabric — outbound-only tunnels, multiplexed TCP channels, zero-install client access

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors