# Security Policy πŸ”’ SPDX-License-Identifier: MIT ## Scope This policy covers the **Tor Guard Relay** Docker image, scripts, and workflows in this repository. Issues related to the Tor network itself should be reported directly to [The Tor Project](https://www.torproject.org/). --- ## Supported Versions We actively support the following versions with security updates: | Version | Status | Support Level | | --------- | --------------------- | ------------------------------------------- | | **1.1.7** | 🟒 πŸ›‘οΈ **Active** | Full support (current stable) | | **1.1.6** | 🟑 πŸ”§ **Maintenance** | Security + critical fixes only | | **< 1.1.5** | πŸ”΄ ❌ **Deprecated** | Removed - contains CVE-2025-15467 (OpenSSL CVSS 9.8). Upgrade immediately. | --- ## πŸ”’ Network Security Model ### Ultra-Minimal Port Exposure **This project follows an ultra-minimal security architecture:** - βœ… **NO monitoring HTTP endpoints** - Removed for maximum security - βœ… **NO exposed metrics ports** - All monitoring via `docker exec` only - βœ… **Only Tor protocol ports exposed** - ORPort, DirPort (configurable), obfs4 (bridge mode) - βœ… **~16.8 MB image** - Minimal attack surface ### Public Port Exposure (Configurable) **Ports exposed depend on relay mode and configuration:** #### Guard/Middle Relay Mode: ``` PUBLIC PORTS: TOR_ORPORT (default: 9001) β†’ Tor ORPort (relay traffic) TOR_DIRPORT β†’ Directory service (optional, disabled by default) ``` #### Exit Relay Mode: ``` PUBLIC PORTS: TOR_ORPORT (default: 9001) β†’ Tor ORPort (relay traffic) TOR_DIRPORT β†’ Directory service (optional, disabled by default) ``` #### Bridge Relay Mode: ``` PUBLIC PORTS: TOR_ORPORT (default: 9001) β†’ Tor ORPort (relay traffic) TOR_OBFS4_PORT (default: 9002) β†’ obfs4 pluggable transport ``` **All port numbers are fully configurable via environment variables.** ### No Monitoring Ports **ZERO exposed monitoring services:** - ❌ No metrics HTTP endpoints - ❌ No health check HTTP APIs - ❌ No dashboard web interfaces - βœ… All diagnostics via `docker exec` commands only **Available diagnostic tools (container exec only):** ```bash docker exec tor-relay status # Health report with emojis docker exec tor-relay health # JSON health output docker exec tor-relay fingerprint # Display fingerprint docker exec tor-relay bridge-line # Get bridge line (bridge mode) docker exec tor-relay gen-auth # Generate Control Port hash docker exec tor-relay gen-family # Generate/view Happy Family key (Tor 0.4.9+) ``` ### Network Architecture This project uses **host networking mode** (`--network host`) for best Tor performance: **Why host networking?** - βœ… **IPv6 Support** - Direct access to host's IPv6 stack - βœ… **No NAT** - Tor binds directly to ports without translation - βœ… **Better Performance** - Eliminates network overhead - βœ… **Tor Recommended** - Follows Tor Project best practices **Security with host networking:** - βœ… Runs as non-root user (`tor` UID 100) - βœ… Drops all capabilities, adds only required ones - βœ… Uses `no-new-privileges:true` - βœ… Minimal Alpine Linux base (~16.8 MB) - βœ… No exposed monitoring ports - βœ… Automatic permission healing ### Port Policy Rationale **Why this matters:** - βœ… **Minimizes attack surface** - Only Tor protocol ports exposed - βœ… **No monitoring vulnerabilities** - Cannot attack what doesn't exist - βœ… **Follows Tor best practices** - Standard relay configuration - βœ… **Defense in depth** - Ultra-minimal design philosophy **Security implications:** - Exposed ORPort: Required for Tor relay operation (configurable) - Exposed DirPort: Optional for directory service (can be disabled) - Exposed obfs4 port: Only in bridge mode (configurable) - NO other services are accessible (internal or external) ### Port Exposure Best Practices #### βœ… Secure Configuration (Recommended) ```bash # Docker CLI with host networking (recommended) docker run -d \ --name tor-relay \ --network host \ --security-opt no-new-privileges:true \ --restart unless-stopped \ -v $(pwd)/relay.conf:/etc/tor/torrc:ro \ -v tor-guard-data:/var/lib/tor \ -v tor-guard-logs:/var/log/tor \ r3bo0tbx1/onion-relay:latest # or ghcr.io/r3bo0tbx1/onion-relay:latest ``` ```yaml # Docker Compose with host networking services: tor-relay: image: r3bo0tbx1/onion-relay:latest container_name: tor-relay restart: unless-stopped network_mode: host volumes: - ./relay.conf:/etc/tor/torrc:ro - tor-guard-data:/var/lib/tor - tor-guard-logs:/var/log/tor ``` ### External Monitoring Access External monitoring is used for maximum security and minimal image size: #### Option 1: Docker Exec (Simplest) ```bash # Check status docker exec tor-relay status # Get JSON health (raw) docker exec tor-relay health # Parse with jq (requires jq on host) docker exec tor-relay health | jq . # View fingerprint docker exec tor-relay fingerprint ``` #### Option 2: JSON Health API Wrapper Create your own HTTP wrapper if needed: ```python #!/usr/bin/env python3 from flask import Flask, jsonify import subprocess import json app = Flask(__name__) @app.route('/health') def health(): result = subprocess.run( ['docker', 'exec', 'tor-relay', 'health'], capture_output=True, text=True ) return jsonify(json.loads(result.stdout)) if __name__ == '__main__': app.run(host='127.0.0.1', port=9100) # Bind to localhost only! ``` #### Option 3: External Prometheus Exporter Use dedicated Tor exporters for Prometheus integration: ```bash # Use tor_exporter for detailed metrics docker run -d --name tor-exporter \ --network host \ ghcr.io/atx/prometheus-tor_exporter:latest \ --tor.control-address=127.0.0.1:9051 ``` See [Monitoring Guide](docs/MONITORING.md) for complete integration examples. ### Firewall Configuration **Recommended firewall rules for guard/middle relay:** ```bash # UFW (Ubuntu/Debian) sudo ufw default deny incoming sudo ufw allow 9001/tcp # ORPort (or your custom port) sudo ufw allow 9030/tcp # DirPort (optional, or your custom port) sudo ufw enable # iptables sudo iptables -A INPUT -p tcp --dport 9001 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 9030 -j ACCEPT sudo iptables -A INPUT -j DROP # firewalld (RHEL/CentOS) sudo firewall-cmd --permanent --add-port=9001/tcp sudo firewall-cmd --permanent --add-port=9030/tcp sudo firewall-cmd --reload ``` **For bridge mode:** ```bash # UFW (Ubuntu/Debian) sudo ufw allow 9001/tcp # ORPort sudo ufw allow 9002/tcp # obfs4 port ``` **For custom ports:** ```bash # Replace with your configured ports sudo ufw allow /tcp sudo ufw allow /tcp # guard/exit only sudo ufw allow /tcp # bridge only ``` --- ## Security Updates - Security patches are released as soon as possible after discovery - Critical vulnerabilities are prioritized - Weekly automated builds include the latest Alpine and Tor security updates - Subscribe to [GitHub Releases](https://github.com/r3bo0tbx1/tor-guard-relay/releases) for notifications ### Automated Hardening To reduce patch-lag risk, GitHub Actions automatically: 1. Pulls the latest Alpine base image 2. Installs the latest Tor package 3. Applies security patches 4. Rebuilds multi-architecture images 5. Publishes to Docker Hub and GHCR **Rebuild schedule:** Sundays at 18:30 UTC These rebuilds include Alpine CVE patches and Tor security fixes without changing functionality. --- ## Reporting a Vulnerability **Do NOT report security vulnerabilities through public GitHub issues.** ### How to Report **Email:** r3bo0tbx1@brokenbotnet.com **Subject:** `[SECURITY] Tor Guard Relay – ` Please use my PGP key [0xB3BD6196E1CFBFB4 πŸ”‘](https://keys.openpgp.org/vks/v1/by-fingerprint/33727F5377D296C320AF704AB3BD6196E1CFBFB4) to encrypt if your report contains sensitive technical details. ### Information to Include 1. **Description** of the vulnerability 2. **Steps to reproduce** the issue 3. **Impact assessment** (who is affected, what's at risk) 4. **Suggested fix** (if you have one) 5. **Your contact information** for follow-up ### What to Expect - **Acknowledgment:** within 48 hours - **Initial assessment:** within 1 week - **Status updates:** every 2 weeks until resolved **Resolution timelines:** | Severity | Response Time | |-----------|----------------| | Critical | 1-7 days | | High | 1-4 weeks | | Medium | 1-3 months | | Low | Next release cycle | ### Coordinated Disclosure We follow responsible disclosure practices: 1. **Report received** β†’ We acknowledge and investigate 2. **Fix developed** β†’ We create and test a patch 3. **Coordinated release** β†’ We agree on disclosure timing 4. **Public disclosure** β†’ We release the fix and advisory 5. **Credit given** β†’ We acknowledge the reporter (unless anonymity is requested) --- ## Security Best Practices ### For Relay Operators #### Configuration Security ```bash # Secure your relay.conf file chmod 600 /path/to/relay.conf chown root:root /path/to/relay.conf # Use read-only mounts -v /path/to/relay.conf:/etc/tor/torrc:ro ``` #### Contact Information ```conf # CIISS v2 format (recommended) - generate at https://torcontactinfogenerator.netlify.app/ ContactInfo email:tor-relay[]example.com url:https://example.com proof:uri-rsa pgp:EF6E286DDA85EA2A4BA7DE684E2C6E8793298290 ciissversion:2 # With abuse contact (recommended for exits) ContactInfo email:tor-relay[]example.com abuse:abuse[]example.com url:https://example.com proof:uri-rsa ciissversion:2 ``` > πŸ“ **CIISS v2:** The [ContactInfo Information Sharing Specification](https://nusenu.github.io/ContactInfo-Information-Sharing-Specification/) provides a machine-readable, verifiable format. The `proof:uri-rsa` method lets tools verify your relay ownership by checking `https://your-domain/.well-known/tor-relay/rsa-fingerprint.txt` for your relay's fingerprint. #### Network Security ```bash # Regular security updates apt update && apt upgrade -y # Ubuntu/Debian yum update -y # RHEL/CentOS # Verify firewall rules sudo ufw status numbered sudo iptables -L -n -v # Pull latest security-patched image docker pull r3bo0tbx1/onion-relay:latest ``` #### Monitoring ```bash # Log monitoring docker logs tor-relay 2>&1 | grep -iE "(error|warn|critical)" # Health checks via diagnostic tools docker exec tor-relay status # JSON health check for automation (raw) docker exec tor-relay health # Parse with jq (requires jq on host) docker exec tor-relay health | jq . # Resource monitoring docker stats tor-relay --no-stream ``` --- ### For Contributors #### Code Security * Never commit secrets or API keys * Use `.gitignore` for sensitive files * Review dependencies for vulnerabilities * Follow the principle of least privilege * Validate all user inputs * Use POSIX sh only (no bash dependencies) #### Docker Security ```dockerfile # Always specify explicit base version FROM alpine:3.23.3 # Pinned version for reproducibility # Run as non-root user USER tor # Use Docker security options --security-opt no-new-privileges:true --cap-drop ALL --cap-add NET_BIND_SERVICE --cap-add CHOWN --cap-add SETUID --cap-add SETGID --cap-add DAC_OVERRIDE ``` #### Secret Management ```bash # NEVER do this: git add relay.conf # Contains sensitive info! # Instead: echo "*.conf" >> .gitignore echo "relay.conf" >> .gitignore ``` --- ## Known Security Considerations ### Host Network Mode **What‼️:** Container uses `--network host` **Why ⁉️:** Enables Tor dual-stack (IPv4 + IPv6) support and eliminates NAT overhead **Security Impact:** * βœ… Container runs as non-root user (`tor` UID 100) * βœ… Drops all capabilities, adds only required ones * βœ… Uses `no-new-privileges:true` * βœ… No exposed monitoring services * ⚠️ Shares host network namespace (required for IPv6) * ⚠️ Relies on firewall for port isolation **Mitigations:** * Drops all capabilities by default * Adds only NET_BIND_SERVICE, CHOWN, SETUID, SETGID, DAC_OVERRIDE * Uses `no-new-privileges:true` * Ultra-minimal Alpine base (~16.8 MB) * NO monitoring HTTP endpoints to attack * Automatic permission healing * Configuration validation before start ### Volume Permissions **What:** Persistent volumes store keys and state **Security Impact:** Keys live in `/var/lib/tor`; protect from unauthorized access **Mitigation:** ```bash # Check volume permissions docker volume inspect tor-guard-data # The container automatically sets: chmod 700 /var/lib/tor chown tor:tor /var/lib/tor ``` **UID/GID in Alpine:** - `tor` user: UID 100, GID 101 - Different from Debian-based images (UID 101) - Automatic permission healing on startup ### Configuration Exposure **What:** Configuration is mounted from the host **Impact:** May reveal bandwidth limits, ContactInfo, etc. **Mitigation:** * Use read-only mount (`:ro`) * Set restrictive file permissions (600) * Never commit configs to Git * Sanitize before sharing --- ## Security Features ### Built-in Protections * βœ… Non-root operation (user `tor` UID 100) * βœ… Minimal base image (Alpine Linux ~16.8 MB) * βœ… Drops all capabilities, adds only required ones * βœ… Read-only configuration mount * βœ… Automatic permission healing * βœ… Configuration validation on startup * βœ… NO exposed monitoring HTTP endpoints * βœ… Busybox-only tools (no bash/python dependencies) * βœ… Smart healthcheck.sh for Docker health checks * βœ… Input validation for all ENV variables * βœ… OBFS4V_* whitelist to prevent command injection ### Multi-Mode Support The container supports three relay modes: | Mode | Default Config | Security Risk | |------|----------------|---------------| | **guard** | Guard/middle relay | Low | | **exit** | Exit relay | **HIGH** - Legal implications | | **bridge** | obfs4 bridge | Low-Medium | **Default:** Guard/middle relay (lowest risk) **Changing modes:** ```bash -e TOR_RELAY_MODE=guard # Guard/middle relay (default) -e TOR_RELAY_MODE=exit # Exit relay (understand legal risks!) -e TOR_RELAY_MODE=bridge # obfs4 bridge ``` See [docs/MULTI-MODE.md](docs/MULTI-MODE.md) and [docs/LEGAL.md](docs/LEGAL.md) for details. ### Weekly Security Updates To ensure ongoing hardening, CI automatically: 1. Pulls latest Alpine base (weekly) 2. Installs updated Tor package 3. Applies available security patches 4. Rebuilds for AMD64 + ARM64 5. Publishes to Docker Hub and GHCR **Schedule:** Sundays at 18:30 UTC Enable automatic updates in Cosmos: ```json "cosmos-auto-update": "true", "cosmos-auto-update-notify": "true" ``` --- ## Compliance & Legal ### Tor Network Participation Running a Tor relay is legal in most countries, but: * ⚠️ Check local laws and ISP terms of service * ⚠️ Understand guard vs. exit vs. bridge differences * ⚠️ Keep contact information accurate * ⚠️ Read [docs/LEGAL.md](docs/LEGAL.md) before deployment **This project supports guard, exit, and bridge modes (configurable via TOR_RELAY_MODE).** ### Data Handling * Tor relays do **not** log traffic content * Relay fingerprints are public (guard/exit modes) * Bridge fingerprints are NOT public (distributed via BridgeDB) * Contact information and bandwidth statistics are public (guard/exit modes) ### Abuse Handling If you receive abuse complaints: 1. Verify it's actually your relay 2. Review Tor Project [abuse response templates](https://community.torproject.org/relay/community-resources/eff-tor-legal-faq/) 3. Respond professionally 4. Consider your legal position 5. Join [tor-relays mailing list](https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-relays) for help --- ## Security Resources ### Official Tor Resources * [Tor Relay Guide](https://community.torproject.org/relay/) * [Tor Security Documentation](https://support.torproject.org/) * [Good/Bad Relays Criteria](https://community.torproject.org/relay/community-resources/good-bad-isps/) * [EFF Tor Legal FAQ](https://community.torproject.org/relay/community-resources/eff-tor-legal-faq/) ### Docker Security * [Docker Security Best Practices](https://docs.docker.com/engine/security/) * [CIS Docker Benchmark](https://www.cisecurity.org/benchmark/docker) * [OWASP Docker Security Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html) ### Alpine Linux * [Alpine Security](https://alpinelinux.org/security/) * [Alpine Package Updates](https://pkgs.alpinelinux.org/packages) --- ## Network Security Audit ### Quick Security Checklist ```bash #!/bin/bash # security-audit.sh - Quick security audit for Tor Guard Relay echo "πŸ”’ Tor Guard Relay Security Audit" echo "===========================================" # Check container is using host networking echo "" echo "1. Checking network mode..." NETWORK_MODE=$(docker inspect tor-relay --format='{{.HostConfig.NetworkMode}}') if [ "$NETWORK_MODE" = "host" ]; then echo "βœ… Using host networking (recommended)" else echo "⚠️ Not using host networking: $NETWORK_MODE" fi # Test Tor ports echo "" echo "2. Testing Tor port accessibility..." PUBLIC_IP=$(curl -s https://icanhazip.com) timeout 5 nc -zv $PUBLIC_IP 9001 && echo "βœ… ORPort accessible" || echo "❌ ORPort not accessible" # Verify diagnostic tools work echo "" echo "3. Testing diagnostic tools..." docker exec tor-relay status > /dev/null 2>&1 && echo "βœ… status tool works" || echo "❌ status tool failed" docker exec tor-relay health > /dev/null 2>&1 && echo "βœ… health tool works" || echo "❌ health tool failed" # Check file permissions echo "" echo "4. Checking critical file permissions..." docker exec tor-relay ls -la /var/lib/tor | grep -E "keys|fingerprint" # Check process user echo "" echo "5. Checking process user..." docker exec tor-relay ps aux | grep -E "^tor" | grep -v grep | head -1 # Check capabilities echo "" echo "6. Checking container capabilities..." docker inspect tor-relay --format='{{.HostConfig.CapDrop}}' | grep -q "ALL" && echo "βœ… All capabilities dropped" || echo "⚠️ Capabilities not fully restricted" # Check volumes echo "" echo "7. Checking volume mounts..." docker inspect tor-relay --format='{{range .Mounts}}{{.Source}} β†’ {{.Destination}} ({{.Mode}}){{println}}{{end}}' echo "" echo "===========================================" echo "βœ… Audit complete!" ``` --- ## Hall of Fame πŸ† Security researchers who responsibly disclose vulnerabilities will be listed here: *No vulnerabilities reported yet.* --- ## Contact * **Security Issues:** [r3bo0tbx1@brokenbotnet.com](mailto:r3bo0tbx1@brokenbotnet.com) * **General Questions:** [GitHub Discussions](https://github.com/r3bo0tbx1/tor-guard-relay/discussions) * **Project Maintainer:** rE-Bo0t.bx1 --- **Thank you for helping keep this project secure!** πŸ”’πŸ§… --- *Last Updated: 2026-03-02 | Version: 1.1.7*