| 1 | # π€ Relay mode β self-hosting with zero routing |
| 2 | |
| 3 | `lchat relay` is the permanent sibling of `lchat try` (issue #738, Phase 1): |
| 4 | your instance runs on your own machine, dials out, and keeps a **stable |
| 5 | public hostname** β no port forward, no domain, no DNS, no certificate, no |
| 6 | root. Ships dormant: it only works against a gateway that offers a relay |
| 7 | domain, and the fleet gateway doesn't yet. |
| 8 | |
| 9 | ```sh |
| 10 | lchat relay # run a space from ./lchat-relay.db, keep it relayed |
| 11 | lchat relay --local 127.0.0.1:1747 # relay an instance you already run |
| 12 | ``` |
| 13 | |
| 14 | ## What makes a relay different from a trial |
| 15 | |
| 16 | | | `lchat try` | `lchat relay` | |
| 17 | |---|---|---| |
| 18 | | Hostname | random, dies with the process | claimed by your keypair, permanent | |
| 19 | | Lifetime | 24 hours max | unlimited | |
| 20 | | Disconnect | address retires | address sleeps (503) for a grace window, then retires; reconnect revives it | |
| 21 | | Reconnect | new address | same address, automatic (backoff β€ ~32s) | |
| 22 | | Admission | 5/IP/hour | same for *new* claims; reconnects are never rate-limited | |
| 23 | |
| 24 | Everything else is identical: the door probe (only Eleven instances), the |
| 25 | per-tunnel connection cap, the re-probe every 10 minutes, and the E2EE |
| 26 | posture β the relay carries the same ciphertext any Eleven server carries. |
| 27 | |
| 28 | ## The identity |
| 29 | |
| 30 | On first run the client writes an Ed25519 seed to `<db>.relay-id` (or |
| 31 | `lchat-relay.id` with `--local`, or `--identity <path>`). **The file is the |
| 32 | hostname**: claiming works by signing a gateway nonce, so whoever holds the |
| 33 | key holds the name. Back it up; lose it and the name is gone (the gateway |
| 34 | operator can free an orphaned claim by deleting its row in the claims db). |
| 35 | |
| 36 | Wire shape (internal/tunnel): hello carries `mode:"relay"`; the gateway |
| 37 | answers `challenge{nonce}`; the client sends `claim{pubkey,sig}`. A hello |
| 38 | without `mode` is a trial and follows the original flow byte-for-byte, so |
| 39 | old clients are unaffected. |
| 40 | |
| 41 | ## Gateway operations |
| 42 | |
| 43 | ```sh |
| 44 | lchat tunnel serve --relay-domain <domain> [--claims /data/tunnel-claims.db] [--max-relays 200] [--claim-idle-days 45] |
| 45 | ``` |
| 46 | |
| 47 | - **Use a dedicated domain**, not the trial/instance domain β relayed |
| 48 | content shares its reputation. It needs a wildcard A record and a |
| 49 | wildcard cert (same DNS-01 setup 11ch.at uses). |
| 50 | - Claims persist in the gateway's own sqlite (`relay_claims`: host, pubkey, |
| 51 | timestamps). Routes are the ordinary registry `service` rows; on gateway |
| 52 | restart stale `r-%` rows are swept and reappear as clients reconnect |
| 53 | (within ~32s). |
| 54 | - Grace window: 15 minutes by default. A sleeping relay answers 503 with an |
| 55 | honest "this space's machine is offline" message. |
| 56 | - `lchat tunnel kill r-β¦.<domain>` withdraws the route; the claim stays, so |
| 57 | the same keypair gets the same hostname back on reconnect. Add `--forget` |
| 58 | to also delete the claim β the hostname returns to the pool and the |
| 59 | keypair starts fresh. That's the kick for a test or abusive relay. |
| 60 | - Abandoned claims free themselves: an hourly janitor deletes claims whose |
| 61 | owner hasn't connected for `--claim-idle-days` (default 45). |
| 62 | Currently-connected relays are never swept, however old their claim. |
| 63 | |
| 64 | ## Honest limits (put these on any page that sells it) |
| 65 | |
| 66 | - Your space's uptime is your machine's uptime. Lid closes, space naps. |
| 67 | - Throughput is your home uplink, relayed twice through the gateway box. |
| 68 | - TLS terminates at the gateway (hosted-grade transport trust; content is |
| 69 | E2EE regardless). Phase 2 β SNI passthrough, where your machine holds its |
| 70 | own certificate and the relay sees only opaque bytes β is designed in |
| 71 | #738 and is the reason relay routes stay a distinct concept. |
| 72 | |
| 73 | ## Not in Phase 1 (see #738) |
| 74 | |
| 75 | Memorable/chosen slugs, bring-your-own-domain (CNAME), SNI passthrough, |
| 76 | relay plans/billing, and gateway sharding. |
| 77 | |