Documentation (14 pages)
Repository publication is pending. The relay described here ships with the source release (AGPL-3.0); until the public repository is live, treat this as the self-hosting guide-in-waiting.
Self-Hosting Relay
Run your own Tallow relay server for complete infrastructure control. The relay is lightweight, stateless, and designed to be self-hosted.
Build from Source
git clone https://github.com/tallowteam/Tallow.gitcd Tallowcargo build -p tallow-relay --releaseThe binary is at target/release/tallow-relay.
Configuration
Create a relay.toml configuration file:
# Networkbind_addr = "0.0.0.0:4433" # QUIC (CLI clients)ws_bind_addr = "0.0.0.0:4434" # WebSocket (browser clients; front with TLS, e.g. Caddy)wt_bind_addr = "0.0.0.0:4435" # WebTransport (HTTP/3; terminates TLS directly)
# Limitsmax_connections = 10000 # Connection ceiling (reconciled with the memory budget at startup)max_rooms = 5000 # Concurrent-rooms ceiling (same reconciliation)room_timeout_secs = 600 # Rooms expire after 10 minutesmax_peers_per_room = 10 # Maximum peers per room (capped at 20)rate_limit = 100 # Room joins/min per IP (clamped 1..=600) + 5 concurrent connections
# Behind a loopback reverse proxy, trust its X-Forwarded-For — only loopback# peers are ever trusted. Keep false when the relay is exposed directly.trust_proxy = true
# TLS (required for QUIC + WebTransport)tls_cert = "/etc/tallow/cert.pem"tls_key = "/etc/tallow/key.pem"Key Settings
| Setting | Reference value | Description |
|---|---|---|
bind_addr |
0.0.0.0:4433 |
QUIC listener (CLI clients) |
ws_bind_addr |
0.0.0.0:4434 |
WebSocket listener (front with TLS) |
wt_bind_addr |
0.0.0.0:4435 |
WebTransport listener (HTTP/3) |
max_connections |
10000 |
Connection ceiling, reconciled with the memory budget at startup |
max_rooms |
5000 |
Concurrent-rooms ceiling |
room_timeout_secs |
600 |
Room expiry (binary default 60; minimum 10s) |
max_peers_per_room |
10 |
Maximum peers per room (capped at 20) |
rate_limit |
100 |
Room joins per minute per IP (1..=600) + 5 concurrent connections |
trust_proxy |
true |
Trust the loopback proxy’s X-Forwarded-For (loopback peers only) |
tls_cert / tls_key |
Required | PEM identity for QUIC + WebTransport |
Abuse control: shipped vs next. The shipped binary enforces the per-IP limits above (
rate_limit, plus the connection and room caps) — keying on nothing beyond the socket. The reference relay is migrating this to a proof-of-work challenge that needs no IP keying at all; that design and its challenge spec are published at Rate Limits (Proof-of-Work), and the relay-side change is tracked in the crypto register (row A09-30 / D-20). Until it lands, the binary reads none of the proof-of-work keys — configure the limits above.
Run
./tallow-relay --config relay.tomlOr with environment variables:
TALLOW_RELAY_LISTEN=0.0.0.0:4433 ./tallow-relaySystemd Service
Create /etc/systemd/system/tallow-relay.service:
[Unit]Description=Tallow Relay ServerAfter=network-online.targetWants=network-online.target
[Service]Type=simpleUser=tallowGroup=tallowExecStart=/opt/tallow/tallow-relay --config /etc/tallow/relay.tomlRestart=alwaysRestartSec=5
# Security hardeningNoNewPrivileges=yesProtectSystem=strictProtectHome=yesPrivateTmp=yesReadOnlyPaths=/etc/tallow
[Install]WantedBy=multi-user.targetEnable and start:
sudo systemctl enable tallow-relaysudo systemctl start tallow-relayDocker
FROM rust:1.86-slim AS builderWORKDIR /buildCOPY . .RUN cargo build -p tallow-relay --release
FROM debian:bookworm-slimRUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*COPY --from=builder /build/target/release/tallow-relay /usr/local/bin/EXPOSE 4433/udp 4434/tcpENTRYPOINT ["tallow-relay"]Build and run:
docker build -t tallow-relay .docker run -d -p 4433:4433/udp -p 4434:4434/tcp \ -v /path/to/relay.toml:/etc/tallow/relay.toml \ -v /path/to/certs:/etc/tallow/certs \ tallow-relay --config /etc/tallow/relay.tomlTLS Certificates
The relay requires TLS certificates for QUIC. Use Let’s Encrypt:
sudo certbot certonly --standalone -d relay.yourdomain.comOr use a self-signed certificate for testing:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem \ -days 365 -nodes -subj "/CN=relay.yourdomain.com"Firewall Rules
Open the required ports:
# QUIC (UDP)sudo ufw allow 4433/udp
# WebSocket (TCP)sudo ufw allow 4434/tcpPoint Clients to Your Relay
Tell clients to use your relay:
# CLItallow send --relay your-relay.example.com:4433 file.txt
# Or set in configtallow config set relay your-relay.example.com:4433Security Considerations
- The relay is zero-knowledge — it only forwards encrypted bytes
- Enable rate limiting to prevent abuse
- Use TLS certificates from a trusted CA for production
- Consider placing behind a reverse proxy for additional protection
- Monitor logs for unusual connection patterns
- Rooms are ephemeral and automatically expire