eleven / ocho Public

Clone
git clone https://amadan.net/eleven/ocho

Plain git — no account needed to clone.

Download

Download this file

1# 🤖 `lchat try` — the one-command trial tunnel
2
3`lchat try` is the zero-setup way to experience a real, self-run Eleven
4space: download the binary, run one command, get a public
5`https://try-<slug>.11ch.at` address serving a full instance from your own
6machine — through NAT, with no inbound ports, no DNS record, no certificate,
7and no root. Stop the command and the address retires; the space's data stays
8in `./lchat-try.db`.
9
10```sh
11curl -LO https://github.com/elevenmessenger/releases/releases/download/server/lchat-linux-amd64
12chmod +x lchat-linux-amd64
13./lchat-linux-amd64 try
14```
15
16It prints two links: the space's address, and a one-time setup link that makes
17you its admin (the same conversational setup a hosted space gets).
18
19## How it works
20
21Two halves, both in the single binary (`internal/tunnel/`):
22
23- **The client** (`lchat try`) starts a normal local instance (a subprocess
24 running the ordinary single-instance path against `lchat-try.db`), then
25 dials out to the gateway over one **control WebSocket**
26 (`wss://tunnel.11ch.at/api/tunnel/register`). The gateway assigns
27 `try-<slug>.11ch.at` and sends `{"type":"ready","host":…}`. For every
28 backend connection the public side needs, the gateway sends
29 `{"type":"dial","id":…}` and the client dials back one **data WebSocket**
30 (`/api/tunnel/conn/<id>`), which both ends treat as a plain byte pipe
31 (`websocket.NetConn`) spliced to the local instance's TCP port. Ordinary
32 HTTP/1.1 flows through it — including WebSocket upgrades, which is what
33 makes the chat itself work through the tunnel unmodified.
34- **The gateway** (`lchat tunnel serve`, unit `lchat-tunnel.service`) listens
35 on `/run/lchat/tunnel.sock` behind the ordinary router. Each live tunnel is
36 published as a plain registry route (`kind=service`, `host=try-…`,
37 `socket=/run/lchat/tunnel.sock`), so the router needs no tunnel awareness at
38 all: TLS comes from the existing `*.11ch.at` wildcard cert, and routing is
39 the same host→socket lookup every instance uses. The router notices new
40 routes via its registry watcher (a `PRAGMA data_version` poll every 2s), so
41 the unprivileged gateway never needs rights to signal anything.
42
43The E2EE story is unchanged: what crosses the tunnel is the same
44already-ciphertext traffic the router fronts for every instance. The gateway
45can see exactly what the router can see — nothing readable.
46
47## Why single-label slugs
48
49`try-x7k2m.11ch.at`, not `x7k2m.try.11ch.at`: TLS wildcards match one label,
50and the fleet's wildcard cert is `*.11ch.at`. A nested scheme would need its
51own wildcard cert and DNS; the prefix gets the same effect for free.
52
53## Operations
54
55- **Enable on a box:** `systemctl enable --now lchat-tunnel`, then route its
56 control host once: `lchat add-service tunnel.11ch.at --socket
57 /run/lchat/tunnel.sock`. (Bootstrap installs the unit everywhere; it's inert
58 until enabled.)
59- **Config** (`/data/tunnel.env`, optional): `LCHAT_TUNNEL_HOST`,
60 `LCHAT_TUNNEL_DOMAIN`, `LCHAT_TUNNEL_SOCKET`, plus `--max` (default 50
61 concurrent tunnels).
62- **Guardrails:** 5 new tunnels per IP per hour, 50 concurrent tunnels, 32
63 concurrent connections per tunnel, 24-hour lifetime, dial-back timeout 15s.
64 And the door check: before a hostname goes public — and every 10 minutes
65 after — the gateway probes the tunnelled backend through the tunnel
66 (`GET /api/version`) and refuses anything that isn't an Eleven instance,
67 so the trial domain never lends its name (or its TLS) to arbitrary
68 content. This is a trial surface, not free hosting — the limits say so
69 politely.
70- **Kill switch:** `lchat tunnel kill try-<slug>.11ch.at` removes the route
71 (the router stops serving it within seconds); `systemctl restart
72 lchat-tunnel` additionally drops every live tunnel connection.
73- **Cleanup is automatic:** a tunnel's route is removed when its client
74 disconnects; on gateway restart, leftover `try-%` rows pointing at its
75 socket are swept. `lchat instances` will show live trials as `service`
76 rows — transient by design.
77- **Self-hosters** can run their own gateway anywhere the router fronts a
78 wildcard domain; `lchat try --gateway https://tunnel.your.domain` points the
79 client at it.
80
81## Honest limits
82
83- A trial's address dies with the process (or at 24h). `lchat try` again
84 mints a fresh address; the data in `lchat-try.db` persists, but members'
85 saved links won't follow it. The printed copy says so — a keeper space
86 should graduate to a real install (`docs/self-hosting.md`).
87- The gateway is a relay for one machine's trial, not a CDN: throughput is
88 whatever the trial machine's uplink gives it.
89