Etoki

Docs

VPS setup (Ubuntu 24.04)

A complete server from a fresh VPS in six steps. You need released binaries and root access — no Rust toolchain, no compiler, nothing to build.

Before you start

  • A fresh Ubuntu 24.04 VPS with root access.
  • 1 vCPU and 1 GB RAM is enough for a small deployment; relays are I/O-bound, not CPU-bound.
  • A DNS A record pointing at the box if you want the TLS-camouflage gateway on :443.
  • The server binary archive for your architecture from the download page.
Want this automated? The deployment configurator generates one idempotent script per server from the same steps, and prints every etoki:// address when it finishes.

1. Install the binaries

Download the archive, verify its checksum, and install both binaries to /usr/local/bin. Do not skip the checksum — it is the only integrity check on a binary distribution.

on the server
# On a fresh Ubuntu 24.04 box, as root
apt update && apt install -y curl ca-certificates coturn

curl -fLO <download-url>/etoki-server-<version>-linux-x86_64.tar.gz
curl -fLO <download-url>/etoki-server-<version>-linux-x86_64.tar.gz.sha256
sha256sum -c etoki-server-<version>-linux-x86_64.tar.gz.sha256

tar xzf etoki-server-<version>-linux-x86_64.tar.gz
install -m 0755 etoki etoki-botrelay /usr/local/bin/
If sha256sum -c does not print OK, stop. Do not install the binary.

2. Stage the deploy tree

The deploy/ directory ships an idempotent installer plus verbatim systemd units for every service. Copy it to the box at /opt/etoki-deploy, then describe this server in its server.env:

server.env
# /opt/etoki-deploy/A/server.env — this box's facts
SERVER_NAME="A"
SERVER_IP="YOUR_SERVER_IP"
EXTERNAL_IP="YOUR_SERVER_IP"      # coturn external-ip
TLS_SNI="relay.example.com"      # gateway certificate name
HAS_BOTRELAY=1                   # 0 on boxes without the bot relay

Set HAS_BOTRELAY=0 on any box that should not run the bot relay. Everything else is identical between servers.

3. Bootstrap

Run the installer as root. It creates the dedicated service users, sets up state directories, templates the coturn configuration, and installs and enables the systemd units:

on the server
# Bootstrap: service users, state dirs, coturn, systemd units.
# Idempotent — safe to re-run for upgrades.
TURN_SECRET=$(openssl rand -hex 32) /opt/etoki-deploy/A/install.sh
The installer is idempotent. Re-running it never clobbers identity or state under /var/lib, so it is also the upgrade path.

Keep the TURN_SECRET value. You will need it again when adding the TURN server in the app, and every server in the same deployment should share it.

4. Record the service identities

On first start each service generates a long-term key and prints its address. The fingerprint in that address is what clients pin — there is no CA and no PKI, so these strings are the trust anchor:

on the server
# Each service prints its address on first start. Record these:
# clients pin the fingerprint, so it must not change.
journalctl -u etoki-router    -n 20 --no-pager | grep etoki://
journalctl -u etoki-directory -n 20 --no-pager | grep etoki://

Save the router and directory addresses somewhere safe. They survive restarts and upgrades because the identity lives in /var/lib.

5. Open the ports

on the server
ufw allow 22/tcp
ufw allow 443/tcp     # gateway (TLS camouflage)
ufw allow 5223/tcp    # router
ufw allow 5443/tcp    # file relay
ufw allow 5663/tcp    # directory
ufw allow 3478        # coturn (TCP + UDP)
ufw allow 5881/tcp    # bot relay HTTPS (only on the bot-relay host)
ufw enable

Only open 5881 on the host that actually runs the bot relay. The bot relay’s plain-HTTP listener stays on 127.0.0.1:5880 and should never be exposed.

6. Verify

on the server
systemctl status etoki-router etoki-filerelay etoki-directory etoki-gateway
curl -sk https://YOUR_SERVER_IP:5881/v1/healthz   # bot-relay host only

All units should report active (running). From the app, add your router address under relay management and run the built-in health check.

Running a second server

Repeat every step on the second box. Only two things differ: its TLS_SNI (each gateway needs its own certificate name) and whether it runs the bot relay. Point both servers’ bot relay at both directories so usernames resolve either way.

Two servers give you redundancy, not full unlinkability. With only two routers the entry hop is each side’s own queue host. For an entry that sees neither endpoint, run a third router and use it as the shared entry.

Upgrading

Replace the binary and restart. Identity, queues and registrations are all under /var/lib and are left untouched, so client-pinned fingerprints keep working:

upgrade
# Upgrade in place: state under /var/lib is untouched, so the
# router and directory fingerprints survive the restart.
scp etoki root@your.host:/usr/local/bin/etoki
ssh root@your.host 'systemctl restart etoki-router'