Files
tor-guard-relay/docs/FAQ.md
rE-Bo0t.bx1 be4f2bc125 feat(v1.1.7): Happy Family support (Tor 0.4.9+ FamilyId)
🔧 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.
2026-03-02 16:23:10 +08:00

18 KiB

Frequently Asked Questions (FAQ)

Common questions about Tor Guard Relay deployment, configuration, and troubleshooting.


📋 Table of Contents


🌐 General

What is this project?

Tor Guard Relay is a production-ready Docker container for running Tor relays. It supports three relay types:

  • Guard/Middle relay - First hop in Tor circuits (default)
  • Exit relay - Last hop (requires legal preparation)
  • Bridge relay - Helps users bypass censorship (obfs4 support)

Built on Alpine Linux 3.23.0 with a minimal 20MB image size, busybox-only tools, and weekly automated security rebuilds.

What makes this different from the official Tor images?

Feature This Project Official Images
Image size ~16.8 MB ~100+ MB
Base Alpine 3.23.0 Debian
Diagnostics 6 busybox tools + JSON API None
Multi-mode Guard/Exit/Bridge in one image Separate images
Weekly rebuilds Automated Manual
ENV configuration Full support Limited
Official bridge naming Drop-in compatible N/A

Is this production-ready?

Yes. Current version is v1.1.3 (Active/Stable). Used in production with:

  • Security-hardened (32 vulnerabilities fixed in >=v1.1.1)
  • Non-root execution (tor user, UID 100)
  • Weekly automated rebuilds with latest Tor + Alpine patches
  • Multi-architecture support (AMD64, ARM64)
  • Comprehensive documentation (11 guides)

🚀 Deployment & Configuration

How do I choose between ENV variables and mounted config file?

Use ENV variables if:

  • Simple guard/middle/bridge setup
  • Standard port configuration
  • Basic bandwidth limits
  • Quick deployment is priority

Use mounted config file if:

  • Complex exit policies
  • Advanced Tor options not in OBFS4V_* whitelist
  • Multiple ORPort addresses (IPv4 + IPv6)
  • Production deployment requiring full control

Example ENV-based deployment:

docker run -d \
  --name tor-relay \
  --network host \
  -e TOR_RELAY_MODE=guard \
  -e TOR_NICKNAME=MyGuardRelay \
  -e TOR_CONTACT_INFO="email:admin[]example.com ciissversion:2" \
  -e TOR_ORPORT=9001 \
  -e TOR_DIRPORT=9030 \
  -v tor-data:/var/lib/tor \
  ghcr.io/r3bo0tbx1/onion-relay:latest

Example mounted config:

docker run -d \
  --name tor-relay \
  --network host \
  -v /path/to/relay.conf:/etc/tor/torrc:ro \
  -v tor-data:/var/lib/tor \
  ghcr.io/r3bo0tbx1/onion-relay:latest

What is the ContactInfo Information Sharing Specification (CIISS)?

The CIISS v2 is a machine-readable format for the Tor relay ContactInfo field. Instead of a plain email, it uses structured key:value pairs that tools can parse and verify automatically.

Format:

email:your-email[]example.com url:https://example.com proof:uri-rsa ciissversion:2

Key fields:

Field Purpose Example
email: Contact email (@[]) email:tor[]example.com
url: Operator website url:https://example.com
proof: URL ownership verification proof:uri-rsa
pgp: 40-char PGP fingerprint pgp:EF6E286DDA85EA2A4BA7DE684E2C6E8793298290
abuse: Abuse contact (exits) abuse:abuse[]example.com
hoster: Hosting provider domain hoster:www.example-hoster.com
uplinkbw: Uplink bandwidth (Mbit/s) uplinkbw:1000
ciissversion: Spec version (mandatory) ciissversion:2

Why use it?

  • Tools like Tor Metrics can parse your info automatically
  • proof:uri-rsa lets anyone verify you own the URL (place relay fingerprints at https://your-domain/.well-known/tor-relay/rsa-fingerprint.txt)
  • Helps detect impersonation - operators can't fake verified URLs
  • Improves trust and visibility in the Tor network

Generate your string: Use the CIISS Generator - fill in the fields and copy the result into your ContactInfo line or TOR_CONTACT_INFO env var.

📖 Full spec: nusenu.github.io/ContactInfo-Information-Sharing-Specification

What's the difference between TOR_* and official bridge naming?

Both work identically - we support two naming conventions for 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 Compatible):

NICKNAME=MyBridge
EMAIL=admin@example.com
OR_PORT=9001
PT_PORT=9002  # Auto-detects bridge mode!

Key difference: Setting PT_PORT automatically enables bridge mode (no need for TOR_RELAY_MODE=bridge).

What's the difference between RelayBandwidthRate and BandwidthRate?

RelayBandwidthRate/Burst (Recommended):

  • Limits relay traffic only (connections between Tor nodes)
  • Directory requests and other Tor infrastructure traffic NOT limited
  • Best for relays to avoid degrading directory service

BandwidthRate/Burst (Global):

  • Limits ALL Tor traffic (relay + directory + everything)
  • Can slow down your relay's ability to serve directory information
  • Use only if you need strict total bandwidth control

ENV variables always use RelayBandwidthRate:

TOR_BANDWIDTH_RATE="50 MBytes"    # → RelayBandwidthRate in torrc
TOR_BANDWIDTH_BURST="100 MBytes"  # → RelayBandwidthBurst in torrc

In mounted config, you choose:

# Option 1 (recommended):
RelayBandwidthRate 50 MBytes
RelayBandwidthBurst 100 MBytes

# Option 2 (global limit):
BandwidthRate 50 MBytes
BandwidthBurst 100 MBytes

Can I use OBFS4V_* variables with spaces (like "1024 MB")?

Yes, as of v1.1.1! The busybox regex bug was fixed (docker-entrypoint.sh:309-321).

This now works:

OBFS4_ENABLE_ADDITIONAL_VARIABLES=1
OBFS4V_MaxMemInQueues=1024 MB
OBFS4V_AddressDisableIPv6=0
OBFS4V_NumCPUs=4

Prior to v1.1.1, spaces caused "dangerous characters" errors. Update to v1.1.1+ if experiencing this issue.

What ports need to be publicly accessible?

Guard/Middle Relay:

  • TOR_ORPORT (default: 9001) - PUBLIC 🌐
  • TOR_DIRPORT (default: 0) - PUBLIC 🌐 (optional, disabled by default)

Exit Relay:

  • TOR_ORPORT (default: 9001) - PUBLIC 🌐
  • TOR_DIRPORT (default: 0) - PUBLIC 🌐 (optional, disabled by default)

Bridge Relay:

  • TOR_ORPORT (default: 9001) - PUBLIC 🌐
  • TOR_OBFS4_PORT (default: 9002) - PUBLIC 🌐

No monitoring ports exposed - all diagnostics via docker exec only (security by design).

Firewall example (UFW):

# Guard relay
sudo ufw allow 9001/tcp

# Bridge relay
sudo ufw allow 9001/tcp
sudo ufw allow 9002/tcp

🧅 Relay Operation

Why is my relay not appearing on Tor Metrics?

Expected timeline:

Milestone Time What to Check
Bootstrap complete 10-30 min docker exec tor-relay status shows 100%
Appears on metrics 1-2 hours Search https://metrics.torproject.org/rs.html
First statistics 24-48 hours Bandwidth graphs appear
Guard flag 8+ days Relay trusted for entry connections

🗳️ Directory Authority Voting: Tor has 9 Directory Authorities that vote hourly on relay flags. A relay only earns a flag (Guard, Stable, Fast, HSDir, etc.) when at least 5 of 9 authorities agree in the consensus. This is why flags aren't instant - your relay must prove itself to a majority of independent authorities.

Troubleshooting:

  1. Check bootstrap: docker exec tor-relay status
    • Must show "Bootstrapped 100%"
  2. Check reachability: Logs should show "Self-testing indicates your ORPort is reachable"
  3. Verify firewall: Ports must be accessible from outside your network
  4. Check logs: docker logs tor-relay | grep -i error
  5. Verify fingerprint exists: docker exec tor-relay fingerprint

Still not showing?

  • Wait 24-48 hours (Tor network consensus updates slowly)
  • Ensure ExitRelay is 0 for guard relays (not publishing as exit)
  • Check PublishServerDescriptor 1 in config

How do I get my bridge line?

After 24-48 hours, run:

docker exec tor-bridge bridge-line

Output format:

Bridge obfs4 <IP>:<PORT> <FINGERPRINT> cert=<CERT> iat-mode=0

Alternative methods:

# Read directly from file
docker exec tor-bridge cat /var/lib/tor/pt_state/obfs4_bridgeline.txt

# Search logs
docker logs tor-bridge | grep "bridge line"

Share your bridge:

  • Share with people you trust
  • DO NOT publish publicly (defeats censorship circumvention)
  • Users can also get bridges from https://bridges.torproject.org/

Why is my relay using very little bandwidth?

This is normal for new relays! Tor network builds trust slowly.

Typical bandwidth progression:

  • Week 1-2: Almost no traffic (building reputation)
  • Week 3-4: Gradual increase as directory consensus includes you
  • Week 5-8: Significant traffic increase
  • 8+ days: May receive Guard flag (massive traffic increase)

Factors affecting bandwidth:

  1. Relay age - New relays are untrusted
  2. Uptime percentage - Must maintain 99%+ for Guard flag
  3. Relay flags - Guard, Fast, Stable flags increase usage (assigned by directory authority consensus - at least 5 of 9 authorities must vote for each flag)
  4. Configured bandwidth - Tor won't exceed your limits
  5. Exit policy - Exit relays typically get more traffic

Not a bug - be patient and maintain high uptime!


🔧 Troubleshooting

Container won't start - "Permission denied" errors

Problem: Directory /var/lib/tor cannot be read: Permission denied

Cause: Volume ownership mismatch (usually when migrating from Debian-based images)

Fix:

# Alpine uses UID 100 (tor user)
docker run --rm -v tor-data:/data alpine:3.23.3 chown -R 100:101 /data

# Verify fix
docker run --rm -v tor-data:/data alpine:3.23.3 ls -ldn /data
# Should show: drwx------ X 100 101 ...

Prevent in future: Always use same image consistently (don't switch between official and this image without migration).

"OBFS4V_MaxMemInQueues: dangerous characters" error

Problem: Bridge configuration rejected with this error (values with spaces)

Cause: Bug in v1.1.0 and earlier - busybox regex incompatibility

Fix: Update to v1.1.1+

docker pull ghcr.io/r3bo0tbx1/onion-relay:latest
docker stop tor-bridge
docker rm tor-bridge
docker run ...  # Recreate with new image

Verify fix:

docker exec tor-bridge cat /build-info.txt
# Should show: Version: 1.1.1 or later

# Verify OBFS4V variables work
docker exec tor-bridge cat /etc/tor/torrc | grep MaxMemInQueues
# Should show: MaxMemInQueues 1024 MB (if variable was set)

Why does TOR_RELAY_MODE say "guard" when I set PT_PORT?

Problem: Log shows guard mode but you expected bridge mode

Cause: Running old image (< v1.1.1) without PT_PORT auto-detection

Fix: Update to v1.1.1+ where PT_PORT automatically enables bridge mode:

# v1.1.1+ auto-detects bridge mode from PT_PORT
docker run -d \
  --name tor-bridge \
  --network host \
  -e PT_PORT=9002 \  # Auto-enables bridge mode!
  -e NICKNAME=MyBridge \
  -e EMAIL=admin@example.com \
  -v tor-data:/var/lib/tor \
  ghcr.io/r3bo0tbx1/onion-relay:latest

Verify:

docker logs tor-bridge | grep "Relay mode"
# Should show: 🎯 Relay mode: bridge

How do I restart vs recreate a container?

CRITICAL: Many issues arise from restarting old containers instead of recreating with new image.

Wrong (uses old image):

docker stop tor-relay
docker pull ghcr.io/r3bo0tbx1/onion-relay:latest  # Downloads new image
docker start tor-relay  # ❌ Still uses OLD image!

Correct (uses new image):

docker stop tor-relay
docker rm tor-relay  # Remove old container
docker pull ghcr.io/r3bo0tbx1/onion-relay:latest  # Download new image
docker run -d --name tor-relay ...  # ✅ New container with new image

Verify which image container is using:

# Get container's image ID
docker inspect tor-relay --format='{{.Image}}'

# Get current image ID
docker images ghcr.io/r3bo0tbx1/onion-relay:latest --format='{{.ID}}'

# IDs must match!

🔄 Migration

How do I migrate from thetorproject/obfs4-bridge?

Official image → This image migration:

  1. Backup your data:
docker run --rm -v obfs4-data:/data -v /tmp:/backup \
  alpine tar czf /backup/tor-backup.tar.gz /data
  1. Fix UID/GID (REQUIRED):
# Official image: UID 101 (debian-tor)
# Our image: UID 100 (tor)
docker run --rm -v obfs4-data:/data alpine:3.23.3 chown -R 100:101 /data
  1. Update configuration:
# Change ONLY the image name - keep same ENV variables!
# Old:
# image: thetorproject/obfs4-bridge:latest

# New:
image: ghcr.io/r3bo0tbx1/onion-relay:latest
  1. Recreate container:
docker stop obfs4-bridge
docker rm obfs4-bridge
docker run -d \
  --name obfs4-bridge \
  --network host \
  -e OR_PORT=9001 \
  -e PT_PORT=9002 \
  -e EMAIL=admin@example.com \
  -e NICKNAME=MyBridge \
  -v obfs4-data:/var/lib/tor \  # Same volume!
  ghcr.io/r3bo0tbx1/onion-relay:latest
  1. Verify fingerprint unchanged:
docker exec obfs4-bridge fingerprint
# Must match your old fingerprint!

See: MIGRATION.md for complete guide

How do I upgrade from v1.1.0 to >=v1.1.1?

Guard/Exit relays (no changes required):

docker pull ghcr.io/r3bo0tbx1/onion-relay:latest
docker stop tor-relay
docker rm tor-relay
docker run -d --name tor-relay ...  # Same config

Bridge relays (OBFS4V fix applies):

  • Same process as above
  • OBFS4V_* variables with spaces now work correctly
  • No config changes needed

Verify upgrade:

docker exec tor-relay cat /build-info.txt
# Should show: Version: 1.1.7

docker exec tor-relay fingerprint
# Verify fingerprint unchanged

Generally yes, but depends on jurisdiction and relay type:

Guard/Middle Relay:

  • Legal in most countries
  • Traffic is encrypted (you can't see content)
  • You're NOT the exit point
  • ⚠️ Inform your ISP (recommended)

Exit Relay:

  • ⚠️ Legal but complex - requires preparation
  • ⚠️ Your IP associated with exit traffic
  • ⚠️ You WILL receive abuse complaints
  • ⚠️ Read docs/LEGAL.md BEFORE running exit relay

Bridge Relay:

  • Legal in most countries
  • Helps censored users
  • Not published in main directory
  • ⚠️ Check local laws on censorship circumvention tools

Resources:

How secure is this container?

Security features:

  • Non-root execution (tor user, UID 100, GID 101)
  • Ultra-minimal image (~16.8 MB, Alpine 3.22.2)
  • Busybox-only (no bash, python, or unnecessary binaries)
  • No exposed monitoring ports (diagnostics via docker exec only)
  • Weekly automated security rebuilds (Sundays 18:30 UTC)
  • Tini init for proper signal handling
  • Security-first template configurations (no-new-privileges, minimal caps)
  • Comprehensive security audit (32 vulnerabilities fixed in v1.1.1)

Security updates:

  • Weekly rebuilds pull latest Alpine + Tor patches
  • Same version tag overwritten with updated packages (e.g., :1.1.1)
  • No package pinning - always latest stable Tor from Alpine edge

Verify security:

# Check build info
docker exec tor-relay cat /build-info.txt

# Run security validation
./scripts/utilities/security-validation-tests.sh

What data does the relay store?

Persistent data in /var/lib/tor:

  • Identity keys - Your relay's cryptographic identity (CRITICAL - don't lose!)
  • State file - Tor's runtime state
  • Cached directory - Tor network consensus
  • Bridge credentials - obfs4 state (bridge mode only)

Logs in /var/log/tor:

  • notices.log - Tor operational logs
  • Rotated automatically - No unbounded growth

Container does NOT store:

  • User traffic content (encrypted)
  • Websites visited through relay
  • User IP addresses
  • Browsing history

Backup requirements:

  • MUST backup: /var/lib/tor (contains identity keys)
  • Optional: Logs (for debugging only)

See: BACKUP.md for backup strategies


💡 Additional Resources

Where can I find more help?

How can I contribute?

  • 🧅 Run a relay - Strengthen the Tor network
  • 🐛 Report bugs - Open issues on GitHub
  • 📖 Improve docs - Fix typos, add examples, translate
  • 💻 Submit code - Bug fixes, features, optimizations
  • Star the repo - Show support!

See CONTRIBUTING.md for guidelines.


Last Updated: March 2026 (v1.1.7) Maintained by: @r3bo0tbx1