towonel
open source · AGPL-3.0 · alpha

A tunnel that doesn't read your traffic.

Cloudflare Tunnel decrypts everything at their edge. Towonel is an open-source alternative that does TLS passthrough — the hub reads the SNI header to route, your keys stay on your machine. Control plane signed with ML-DSA-65, so even a malicious hub operator can't touch your routing.

What

A self-hosted tunnel for sharing a VPS with friends.

TLS passthrough by default

The hub reads SNI to route, then forwards the raw TLS stream. It sees source IPs, byte counts, hostnames. Nothing else.

Post-quantum signed control plane

Every config entry is signed with ML-DSA-65 (FIPS 204). Sharing a hub with people you don't fully trust is fine — they can't touch your routing.

Stateless agent

No disk, no init, no persistent identity. One invite token boots any number of replicas. Trivial in Kubernetes.

TCP and UDP proxy

Expose SSH, postgres, a TURN server, a game server, WireGuard. Not just HTTP. Cloudflare Tunnel doesn't do this.

Per-tenant scoping

Each invite is locked to its own hostnames and ports. Tenants manage their routing without operator intervention.

Lightweight

Rust. One container, one env file. SQLite by default, Postgres when you outgrow it.

Invite-shaped

You run the hub, you mint invites, you hand them to people you trust. No public signup.

Operable single-handed

Audit log on every privileged write. Recoverable from a backed-up DB and a KEK.

AGPL-3.0

Read it, fork it, audit it. Source on Codeberg.

How

Hub, edge, agent.

01

Agent

runs next to your service

Boots from one invite token. Derives an ML-DSA keypair from the seed inside the token; the private half never leaves the box. Dials the edges over iroh QUIC and waits.

02

Edge

public-facing

Accepts client TLS, reads the SNI, forwards the raw stream to the matching agent. Verifies the hub-signed credential the agent presents. Holds no tenant certs.

03

Hub

control plane

You run this on a VPS. Issues invites, signs short-lived agent credentials, keeps an audit log. Operator key for the CLI, session cookies for the web console.

Start

Run a hub. Mint an invite.

on the VPS
$ docker run -d --name towonel \
    -e TOWONEL_HUB_OPERATOR_API_KEY=$(openssl rand -hex 32) \
    -e TOWONEL_INVITE_HASH_KEY=$(openssl rand -hex 32) \
    -e TOWONEL_HUB_KEK=$(openssl rand -hex 32) \
    -p 8443:8443 -p 443:443 -p 51820:51820/udp \
    codeberg.org/towonel/towonel:latest

$ docker exec towonel \
    towonel invite create \
      --name alice \
      --hostnames '*.example.eu,app.alice.example.fr'

You hand the printed token to a friend, they TOWONEL_INVITE_TOKEN=… towonel-agent next to their service. Splitting one VPS across a few friends makes the monthly cost almost nothing.

Don't want to run a VPS? I hand out invites to my own hub in the home-operations Discord — drop in, say hi. The project runs on donations; if it's useful to you, buy me a coffee on Ko-fi.

Status: alpha. Running in production replacing my own Pangolin install, but the wire format may change between 0.0.x releases.