Skip to content
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

Terminal window
git clone https://github.com/tallowteam/Tallow.git
cd Tallow
cargo build -p tallow-relay --release

The binary is at target/release/tallow-relay.

Configuration

Create a relay.toml configuration file:

# Network
bind_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)
# Limits
max_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 minutes
max_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

Terminal window
./tallow-relay --config relay.toml

Or with environment variables:

Terminal window
TALLOW_RELAY_LISTEN=0.0.0.0:4433 ./tallow-relay

Systemd Service

Create /etc/systemd/system/tallow-relay.service:

[Unit]
Description=Tallow Relay Server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=tallow
Group=tallow
ExecStart=/opt/tallow/tallow-relay --config /etc/tallow/relay.toml
Restart=always
RestartSec=5
# Security hardening
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ReadOnlyPaths=/etc/tallow
[Install]
WantedBy=multi-user.target

Enable and start:

Terminal window
sudo systemctl enable tallow-relay
sudo systemctl start tallow-relay

Docker

FROM rust:1.86-slim AS builder
WORKDIR /build
COPY . .
RUN cargo build -p tallow-relay --release
FROM debian:bookworm-slim
RUN 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/tcp
ENTRYPOINT ["tallow-relay"]

Build and run:

Terminal window
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.toml

TLS Certificates

The relay requires TLS certificates for QUIC. Use Let’s Encrypt:

Terminal window
sudo certbot certonly --standalone -d relay.yourdomain.com

Or use a self-signed certificate for testing:

Terminal window
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:

Terminal window
# QUIC (UDP)
sudo ufw allow 4433/udp
# WebSocket (TCP)
sudo ufw allow 4434/tcp

Point Clients to Your Relay

Tell clients to use your relay:

Terminal window
# CLI
tallow send --relay your-relay.example.com:4433 file.txt
# Or set in config
tallow config set relay your-relay.example.com:4433

Security Considerations