🔧 New tool: gen-family - generate/view Happy Family keys - Supports --force flag to overwrite existing keys without backup prompt 🐳 Dockerfiles: gen-family in both Dockerfile and Dockerfile.edge 🔧 Entrypoint: - Phase 2: detect *.secret_family_key, log found keys (informational only) - Guard/exit config gen: append FamilyId + MyFamily from ENV vars - Bridge intentionally excluded 📊 Status tool: show family key count + Happy Family config state 📚 Docs: - README: Happy Family section (generate / import), persistence table, flowchart - ARCHITECTURE: all mermaid diagrams updated (Phase 2, config gen, tools, dirs) - TOOLS: full gen-family reference with examples and exit codes - DEPLOYMENT, MIGRATION, MIGRATION-V1.1.X, TROUBLESHOOTING: 5 -> 6 tools - FAQ, example configs: version bump + FamilyId/MyFamily placeholders - Directory authority voting: how 9 dirauths vote on relay flags (5/9 consensus) - CIISS v2 ContactInfo: field reference, generator link, proof:uri-rsa verification - All TOR_CONTACT_INFO examples updated to CIISS v2 format across templates and docs 📋 Templates: - Guard/exit/multi-relay compose: TOR_FAMILY_ID + TOR_MY_FAMILY env vars - All cosmos-compose + docker-compose versions -> 1.1.7 👷 CI: validate.yml gen-family in 8 spots (threshold 6), security tests, quick-test 🛡️ SECURITY.md: 1.1.7 active, 1.1.6 maintenance, gen-family in tools list 🔖 Version bump 1.1.6 -> 1.1.7 across 30+ files, tool count 5 -> 6, CHANGELOG entry No breaking changes. TOR_FAMILY_ID and TOR_MY_FAMILY are optional.
Tor Relay Templates Guide
This directory contains deployment templates for running Tor relays in 3 modes: Guard/Middle, Exit, and Bridge (obfs4).
📁 Template Files Overview
Cosmos Cloud Templates (JSON)
| File | Mode | ENV Naming | Use Case |
|---|---|---|---|
cosmos-compose-guard.json |
Guard/Middle | TOR_* | Standard guard relay, ENV-based config |
cosmos-compose-exit.json |
Exit | TOR_* | Exit relay with reduced policy, ENV-based config |
cosmos-compose-bridge.json |
Bridge (obfs4) | TOR_* | Bridge relay, ENV-based config |
cosmos-compose-bridge-official.json |
Bridge (obfs4) | OR_PORT, PT_PORT, EMAIL | Drop-in replacement for thetorproject/obfs4-bridge |
cosmos-compose-multi-relay.json |
All 3 modes | TOR_* | Run guard, exit, and bridge simultaneously |
cosmos-bind-config-guard-relay.json |
Guard/Middle | TOR_* | Standard guard relay, mounted config |
cosmos-bind-config-bridge.json |
Bridge (obfs4) | TOR_* | Bridge relay, mounted config |
Docker Compose Templates (YAML)
| File | Mode | ENV Naming | Use Case |
|---|---|---|---|
docker-compose-guard-env.yml |
Guard/Middle | TOR_* | Standard Docker Compose guard relay |
docker-compose-exit.yml |
Exit | TOR_* | Standard Docker Compose exit relay |
docker-compose-bridge.yml |
Bridge (obfs4) | TOR_* | Standard Docker Compose bridge |
docker-compose-bridge-official.yml |
Bridge (obfs4) | OR_PORT, PT_PORT, EMAIL | Drop-in replacement for thetorproject/obfs4-bridge |
docker-compose-multi-relay.yml |
All 3 modes | TOR_* | Run multiple relay modes |
🔧 Configuration Methods
You can configure Tor relays using TWO methods:
Method 1: Environment Variables (Recommended for Simple Setups)
Pros:
- ✅ No config file needed
- ✅ Easy to customize via Cosmos/Portainer/docker-compose
- ✅ Simple deployment
Cons:
- ❌ Limited to basic options
- ❌ Can't use all advanced Tor features
Example (Bridge):
docker run -d \
--name tor-bridge \
--network host \
--security-opt no-new-privileges:true \
-e TOR_RELAY_MODE=bridge \
-e TOR_NICKNAME=MyBridge \
-e TOR_CONTACT_INFO="email:admin[]example.com ciissversion:2" \
-e TOR_ORPORT=9001 \
-e TOR_OBFS4_PORT=9002 \
-v tor-data:/var/lib/tor \
r3bo0tbx1/onion-relay:latest
All available ENV variables:
# Core (required for ENV-based config)
TOR_RELAY_MODE=guard|exit|bridge # Relay mode
TOR_NICKNAME=MyRelay # Relay nickname (1-19 chars, alphanumeric)
TOR_CONTACT_INFO="email:admin[]example.com ciissversion:2" # Contact info (CIISS v2)
# Ports (configurable)
TOR_ORPORT=9001 # ORPort for relay traffic (default: 9001)
TOR_DIRPORT= # DirPort for guard/exit only (default: 0)
TOR_OBFS4_PORT=9002 # obfs4 port for bridge mode (default: 9002)
# Bandwidth (optional)
TOR_BANDWIDTH_RATE=50 MBytes
TOR_BANDWIDTH_BURST=100 MBytes
# Exit policy (exit mode only, optional)
TOR_EXIT_POLICY=accept *:80,accept *:443,reject *:*
Method 2: Mounted Config File (Advanced Configurations)
Pros:
- ✅ Full access to all Tor configuration options
- ✅ Can use complex exit policies, custom options, etc.
- ✅ Better for production deployments
Cons:
- ❌ Requires creating and maintaining a torrc file
- ❌ Slightly more complex
Example (Bridge with mounted config):
docker run -d \
--name tor-bridge \
--network host \
--security-opt no-new-privileges:true \
-v /path/to/relay-bridge.conf:/etc/tor/torrc:ro \
-v tor-data:/var/lib/tor \
r3bo0tbx1/onion-relay:latest
Cosmos Cloud JSON (remove environment, add bind mount):
{
"volumes": [
{
"type": "bind",
"source": "/path/to/relay-bridge.conf",
"target": "/etc/tor/torrc",
"read_only": true
},
{
"type": "volume",
"source": "tor-bridge-data",
"target": "/var/lib/tor"
}
]
}
Config file examples: See examples/relay-guard.conf, examples/relay-exit.conf, examples/relay-bridge.conf
🌉 Bridge Mode: Two ENV Naming Conventions
We support BOTH naming conventions for maximum compatibility:
TOR_* Naming (Our Standard)
TOR_RELAY_MODE=bridge
TOR_NICKNAME=MyBridge
TOR_CONTACT_INFO="email:admin[]example.com ciissversion:2"
TOR_ORPORT=9001
TOR_OBFS4_PORT=9002
Official Tor Project Naming (Drop-in Compatibility)
# These map to TOR_* internally:
NICKNAME=MyBridge # → TOR_NICKNAME
EMAIL=admin@example.com # → TOR_CONTACT_INFO
OR_PORT=9001 # → TOR_ORPORT
PT_PORT=9002 # → TOR_OBFS4_PORT
Auto-detection: Setting PT_PORT automatically sets TOR_RELAY_MODE=bridge.
Advanced Bridge Options (OBFS4V_* Variables)
For advanced torrc options (like AddressDisableIPv6, MaxMemInQueues, etc.):
-
Enable processing:
OBFS4_ENABLE_ADDITIONAL_VARIABLES=1 -
Add OBFS4V_ variables* (mapped to torrc options):
OBFS4V_AddressDisableIPv6=0 OBFS4V_MaxMemInQueues=1024 MB OBFS4V_NumCPUs=4 -
Whitelist: Only specific torrc options are allowed (security):
AddressDisableIPv6MaxMemInQueuesNumCPUsBandwidthRate,BandwidthBurstAccountingMax,AccountingStart- And other safe options (see
docker-entrypoint.shline 318-332)
-
For options NOT in whitelist: Use a mounted config file instead.
🔍 Common Questions
Q: Why are there 2 bridge templates?
A: For compatibility and flexibility:
cosmos-compose-bridge.json- Uses TOR_* naming (our standard)cosmos-compose-bridge-official.json- Uses OR_PORT/PT_PORT/EMAIL naming (drop-in replacement forthetorproject/obfs4-bridge)
Both work identically, choose based on your preference or migration needs.
Q: Why is TOR_DIRPORT set in Dockerfile when bridges don't use it?
A: TOR_DIRPORT=9030 is a Dockerfile default for guard/exit modes. The entrypoint DOES NOT add DirPort to bridge configurations (see docker-entrypoint.sh lines 276-290). Bridges only use ORPort and obfs4 port.
Port usage by mode:
- Guard/Middle: TOR_ORPORT (required), TOR_DIRPORT (optional, default = 0)
- Exit: TOR_ORPORT (required), TOR_DIRPORT (optional, default = 0)
- Bridge: TOR_ORPORT (required), TOR_OBFS4_PORT (required), TOR_DIRPORT (ignored/default = 0)
Q: Why does TOR_RELAY_MODE say "guard" in logs when I set PT_PORT?
A: This shouldn't happen anymore (fixed since v1.1.1). The entrypoint auto-detects bridge mode when PT_PORT is set (lines 29-31):
if [ -n "${PT_PORT:-}" ] && [ "${TOR_RELAY_MODE:-guard}" = "guard" ]; then
TOR_RELAY_MODE="bridge"
fi
If you see "guard" mode in bridge deployment:
- Verify you're using the latest image:
docker exec <container> cat /build-info.txt - Check container is actually running the new image:
docker inspect <container> --format='{{.Image}}' - Recreate container (don't just restart):
docker rm -f <container> && docker run ...
Q: What's the difference between { "driver": "local" } and {} for volumes?
A: They're identical. Both create a local named volume:
"tor-data": {}- Minimal syntax (default driver is "local")"tor-data": { "driver": "local" }- Explicit syntax (redundant but clear)
We use {} in templates (simpler), but both work the same.
Q: OBFS4V_* variables are being skipped with "dangerous characters" error?
A: This was a bug in v1.1.0 and earlier (busybox grep regex issue). Fixed since v1.1.1.
The entrypoint now properly validates values:
- Rejects actual newlines (not escaped \n)
- Rejects null bytes and control characters
- Allows spaces (e.g., "1024 MB")
If you still see this error after updating to the latest version:
- Check image version:
docker exec <container> cat /build-info.txt - Verify value doesn't have real newlines (JSON array formatting shouldn't cause this)
- Try using a mounted config file for complex options
Q: Should I use ENV variables or mounted config file?
A: Use this decision tree:
Use ENV variables if:
- ✅ Running a simple guard/middle/bridge relay
- ✅ Standard port configuration
- ✅ Basic bandwidth limits
- ✅ Easy deployment is priority
Use mounted config file if:
- ✅ Complex exit policies
- ✅ Advanced Tor options not in OBFS4V_* whitelist
- ✅ Multiple ORPort addresses (IPv4 + IPv6)
- ✅ Accounting limits with specific start times
- ✅ Production deployment requiring full control
You can also mix: Start with ENV variables, then migrate to mounted config later without losing your relay identity (keys in /var/lib/tor are preserved).
🚀 Quick Start Examples
Guard Relay (Cosmos Cloud)
- Import
cosmos-compose-guard.json - Change: TOR_NICKNAME, TOR_CONTACT_INFO
- Deploy
- Check:
docker exec tor-guard-relay status
Bridge (Drop-in Official Replacement)
- Import
cosmos-compose-bridge-official.json - Change: NICKNAME, EMAIL
- Deploy
- Get bridge line:
docker exec obfs4-bridge bridge-line
Exit Relay (Docker Compose)
- Copy
docker-compose-exit.yml - Edit ENV variables (nickname, contact, bandwidth)
- READ docs/LEGAL.md first!
- Run:
docker-compose up -d
📚 Additional Resources
- Full deployment guide:
docs/DEPLOYMENT.md - Example config files:
examples/relay-*.conf - Monitoring:
docs/MONITORING.md - Legal considerations (exit relays):
docs/LEGAL.md
🆘 Troubleshooting
Container restarts immediately
- Check logs:
docker logs <container> - Verify ENV variables are set correctly (TOR_NICKNAME and TOR_CONTACT_INFO required for ENV-based config)
- Ensure volume permissions are correct
Bridge mode detected as guard
- Update to latest version
- Recreate container (don't restart old one)
- Use
PT_PORTfor auto-detection or explicitly setTOR_RELAY_MODE=bridge
OBFS4V_* variables ignored
- Update to latest version (fixed in v1.1.1)
- Enable:
OBFS4_ENABLE_ADDITIONAL_VARIABLES=1 - Check whitelist in
docker-entrypoint.shline 318-332 - Use mounted config for non-whitelisted options
Ports not binding
- Verify
--network hostis set (required for IPv6) - Check firewall rules
- Ensure ports aren't already in use:
ss -tlnp | grep <port>
Version: 1.1.7 Last Updated: 2026-03-02 Maintainer: rE-Bo0t.bx1 r3bo0tbx1@brokenbotnet.com