Relay setup
This guide explains how to set up your own iroh relay server for CipherFS P2P synchronization.
Why Self-Host a Relay?
Advantages
- ✅ Privacy - All traffic goes through your own infrastructure
- ✅ Control - Full control over relay configuration and policies
- ✅ Compliance - Meet data sovereignty requirements
- ✅ Performance - Deploy closer to your users
- ✅ No limits - No usage limits or throttling
Disadvantages
- ❌ Maintenance - You need to maintain and monitor the server
- ❌ Cost - Server hosting costs
- ❌ Availability - You're responsible for uptime
Quick Start
Option 1: Use Docker (Recommended)
# Clone the relay repository
git clone https://github.com/n0-computer/iroh
cd iroh
# Build the relay Docker image
docker build -t iroh-relay -f crates/iroh-net/Dockerfile .
# Run the relay server
docker run -d \
--name iroh-relay \
-p 443:443 \
-p 3478:3478 \
-v /var/lib/iroh-relay:/data \
-e RUST_LOG=info \
iroh-relay
# Check logs
docker logs -f iroh-relayOption 2: Build from Source
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Clone and build
git clone https://github.com/n0-computer/iroh
cd iroh
cargo build --release --bin iroh-relay
# Run the relay
./target/release/iroh-relay
Configuration
Environment Variables
| Variable | Description | Default |
|---|---|---|
IROH_RELAY_PORT | QUIC relay port | 443 |
IROH_STUN_PORT | STUN port for hole punching | 3478 |
RUST_LOG | Log level | info |
IROH_RELAY_ADDR | Public address to advertise | Auto-detected |
Example Configuration
# /etc/iroh-relay/config.sh
export IROH_RELAY_PORT=443
export IROH_STUN_PORT=3478
export RUST_LOG=iroh_relay=debug
export IROH_RELAY_ADDR=relay.example.com
Production Deployment
Using Docker Compose
Create docker-compose.yml:
version: '3.8'
services:
iroh-relay:
image: iroh-relay:latest
container_name: iroh-relay
restart: unless-stopped
ports:
- "443:443" # QUIC relay
- "3478:3478" # STUN
volumes:
- relay-data:/data
- ./logs:/var/log/iroh
environment:
- RUST_LOG=info
- IROH_RELAY_ADDR=relay.yourdomain.com
# Resource limits
deploy:
resources:
limits:
cpus: '2'
memory: 4G
reservations:
cpus: '0.5'
memory: 512M
# Health check
healthcheck:
test: ["CMD", "nc", "-z", "localhost", "443"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Logging
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
volumes:
relay-data:
Deploy:
docker-compose up -dUsing systemd
Create /etc/systemd/system/iroh-relay.service:
[Unit]
Description=Iroh Relay Server
After=network.target
[Service]
Type=simple
User=iroh
Group=iroh
WorkingDirectory=/var/lib/iroh-relay
ExecStart=/usr/local/bin/iroh-relay
Restart=always
RestartSec=10
# Security
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
# Resource limits
LimitNOFILE=65536
MemoryMax=4G
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=iroh-relay
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable iroh-relay
sudo systemctl start iroh-relay
sudo systemctl status iroh-relay
Firewall Configuration
Required Ports
# Allow QUIC relay (UDP/TCP)
sudo ufw allow 443/tcp
sudo ufw allow 443/udp
# Allow STUN (UDP)
sudo ufw allow 3478/udpUsing firewalld
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --permanent --add-port=443/udp
sudo firewall-cmd --permanent --add-port=3478/udp
sudo firewall-cmd --reload
TLS Certificate
Using Let's Encrypt (Recommended)
# Install certbot
sudo apt install certbot
# Obtain certificate
sudo certbot certonly --standalone -d relay.yourdomain.com
# Certificate location:
# /etc/letsencrypt/live/relay.yourdomain.com/fullchain.pem
# /etc/letsencrypt/live/relay.yourdomain.com/privkey.pem
Configure relay to use certificates:
export IROH_RELAY_CERT=/etc/letsencrypt/live/relay.yourdomain.com/fullchain.pem
export IROH_RELAY_KEY=/etc/letsencrypt/live/relay.yourdomain.com/privkey.pemAuto-renewal
# Test renewal
sudo certbot renew --dry-run
# Certbot automatically sets up cron job
# Verify: cat /etc/cron.d/certbot
Monitoring
Health Check
# Check if relay is listening
nc -zv relay.yourdomain.com 443
# Check STUN
nc -zv relay.yourdomain.com 3478Metrics
iroh-relay exposes metrics on /metrics endpoint (Prometheus format):
# prometheus.yml
scrape_configs:
- job_name: 'iroh-relay'
static_configs:
- targets: ['relay.yourdomain.com:443']
metrics_path: /metricsLogging
# View logs
docker logs -f iroh-relay
# Or with systemd
journalctl -u iroh-relay -f
CipherFS Configuration
Using Your Relay
Update your CipherFS configuration:
use cipherfs_sync::iroh_p2p::{IrohNode, RelayConfig};
// Use your custom relay
let relay_config = RelayConfig::custom_relay(
"https://relay.yourdomain.com:443".to_string()
);
let node = IrohNode::new_with_config(
"/path/to/vault",
relay_config
).await?;CLI Usage
# Set custom relay
cipherfs config set relay.url "https://relay.yourdomain.com:443"
# Verify
cipherfs config get relay.url
Performance Tuning
Server Requirements
Minimum:
- CPU: 2 cores
- RAM: 2 GB
- Network: 100 Mbps
- Storage: 20 GB
Recommended (100+ concurrent connections):
- CPU: 4-8 cores
- RAM: 4-8 GB
- Network: 1 Gbps
- Storage: 50 GB SSD
Optimizations
# Increase UDP buffer sizes
sudo sysctl -w net.core.rmem_max=134217728
sudo sysctl -w net.core.wmem_max=134217728
# Make persistent
cat >> /etc/sysctl.conf <<EOF
net.core.rmem_max=134217728
net.core.wmem_max=134217728
net.core.rmem_default=262144
net.core.wmem_default=262144
EOF
sudo sysctl -p
Security Best Practices
- Use TLS - Always use HTTPS for relay connections
- Limit Resources - Set CPU/memory limits
- Monitor Usage - Track connections and bandwidth
- Update Regularly - Keep iroh-relay updated
- Backup Configuration - Backup certificates and keys
- Isolate - Run in separate container/VM
Troubleshooting
Relay Not Starting
# Check logs
docker logs iroh-relay
# Common issues:
# - Port already in use: sudo lsof -i :443
# - Permission denied: Run with appropriate user
# - Certificate missing: Check cert pathsClients Cannot Connect
# Test relay connectivity
telnet relay.yourdomain.com 443
# Check firewall
sudo ufw status
# Verify DNS
nslookup relay.yourdomain.com
# Test from client machine
curl -v https://relay.yourdomain.com:443High CPU Usage
# Check connection count
docker exec iroh-relay netstat -an | grep :443 | wc -l
# Limit connections if needed
# (requires iroh-relay restart with connection limit config)
Cost Estimation
Hosting Options
| Provider | Plan | Cost/Month | Suitable For |
|---|---|---|---|
| DigitalOcean | 4GB/2CPU | $24 | Small team (10-50 users) |
| AWS | t3.large | $60 | Medium team (50-200 users) |
| GCP | e2-standard-4 | $120 | Large team (200+ users) |
| Linode | 8GB/4CPU | $48 | Medium-large team |
Bandwidth
Estimate based on usage:
- Light (10 users, <1GB/day): ~10GB/month
- Medium (100 users, 10GB/day): ~300GB/month
- Heavy (1000 users, 100GB/day): ~3TB/month
Alternatives
Use n0.network (Free)
If you don't want to self-host, use the default n0.network relay:
// Default (no configuration needed)
let node = IrohNode::new("/path/to/vault").await?;Use Tailscale
Tailscale provides built-in DERP relay servers:
# Install Tailscale on all devices
# No relay configuration needed
# Tailscale handles everything
References
Last updated: 2026-01-14