# ๐Ÿ” Backup & Recovery Guide - Tor Guard Relay Complete instructions for backing up and restoring your Tor relay's identity, keys, and configuration data. --- ## Table of Contents - [Why Backups Matter](#why-backups-matter) - [What to Backup](#what-to-backup) - [Backup Methods](#backup-methods) - [Recovery Procedures](#recovery-procedures) - [Migration Guide](#migration-guide) - [Best Practices](#best-practices) --- ## Why Backups Matter Your Tor relay's **identity is permanent**. Once established, it becomes part of the Tor network's fabric. Losing these keys means: - ๐Ÿšซ Loss of your relay's fingerprint - ๐Ÿ“‰ Loss of reputation built over time - ๐Ÿ”„ New relay starting from zero - โฐ 8+ days to regain guard flag **Backup your keys immediately after first successful bootstrap.** --- ## What to Backup ### ๐Ÿ”‘ Critical Files (Preserve Forever) Located in `/var/lib/tor/`: | File | Purpose | Restore Impact | |------|---------|-----------------| | `keys/ed25519_master_id_secret_key` | Master identity key | **CRITICAL** - Defines relay identity | | `keys/ed25519_signing_secret_key` | Signing key | **CRITICAL** - Signs all operations | | `keys/secret_onion_key` | Onion key | **CRITICAL** - Onion address generation | | `fingerprint` | Your relay fingerprint | Reference only (can regenerate) | ### ๐Ÿ“‹ Important Files (Backup Regularly) | File | Purpose | Restore Impact | |------|---------|-----------------| | `cached-consensus` | Current Tor consensus | Nice to have (rebuilds automatically) | | `cached-descriptors` | Relay descriptors | Nice to have (rebuilds automatically) | | `state` | Relay state file | Optional (recreated on startup) | ### โš™๏ธ Configuration (Backup Before Changes) | File | Location | Purpose | |------|----------|---------| | `relay.conf` | Host machine | Your relay configuration | | `torrc` | `/etc/tor/torrc` (in container) | Mounted copy of relay.conf | --- ## Backup Methods ### Quick Backup (Simplest) Copy the keys directory straight out of a running container: ```bash docker cp :/var/lib/tor/keys ./RelayKeyBackup ``` That's it. The `RelayKeyBackup/` folder now contains your relay's identity keys. Store it somewhere safe. --- ### Method 1: Docker Volume Backup (Recommended) **Pros:** Complete, easy to restore, version-controlled **Cons:** Requires disk space for full volume copy #### Step 1: Stop the Relay Gracefully ```bash # Stop relay (allows clean shutdown) docker stop guard-relay # Wait for graceful shutdown sleep 5 # Verify stopped docker ps | grep guard-relay ``` #### Step 2: Backup the Volume ```bash # Create backup directory mkdir -p ~/tor-relay-backups/$(date +%Y-%m-%d) # Backup the tor-guard-data volume docker run --rm \ -v tor-guard-data:/data \ -v ~/tor-relay-backups/$(date +%Y-%m-%d):/backup \ alpine tar czf /backup/tor-data-$(date +%s).tar.gz -C /data . # Verify backup created ls -lh ~/tor-relay-backups/$(date +%Y-%m-%d)/ ``` **Output:** ``` -rw-r--r-- 1 user user 2.5M Jan 1 12:00 tor-data-1704110400.tar.gz ``` #### Step 3: Backup the Logs Volume ```bash # Backup logs for audit trail docker run --rm \ -v tor-guard-logs:/data \ -v ~/tor-relay-backups/$(date +%Y-%m-%d):/backup \ alpine tar czf /backup/tor-logs-$(date +%s).tar.gz -C /data . # Verify ls -lh ~/tor-relay-backups/$(date +%Y-%m-%d)/ ``` #### Step 4: Restart the Relay ```bash # Restart relay docker start guard-relay # Monitor startup docker logs -f guard-relay ``` --- ### Method 2: Direct Key Extraction **Pros:** Minimal, extracts only critical keys **Cons:** Manual process, easier to miss files #### Extract Keys While Running ```bash # Create secure backup directory mkdir -p ~/tor-relay-backups/keys-only chmod 700 ~/tor-relay-backups/keys-only # Extract keys directly from container docker exec guard-relay tar czf - -C /var/lib/tor/keys . | \ tar xzf - -C ~/tor-relay-backups/keys-only/ # Verify contents ls -la ~/tor-relay-backups/keys-only/ ``` **Expected output:** ``` ed25519_master_id_secret_key ed25519_signing_secret_key secret_onion_key ``` #### Secure the Backup ```bash # Set restrictive permissions chmod 600 ~/tor-relay-backups/keys-only/* # Verify ownership ls -la ~/tor-relay-backups/keys-only/ ``` --- ### Method 3: Automated Daily Backup **Pros:** Hands-off, versioned history **Cons:** Requires cron setup, disk space #### Create Backup Script ```bash #!/bin/bash # Save as: /usr/local/bin/backup-tor-relay.sh set -euo pipefail BACKUP_DIR="/backups/tor-relay" RETENTION_DAYS=30 CONTAINER="guard-relay" TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S) # Create backup directory mkdir -p "$BACKUP_DIR/$TIMESTAMP" # Stop relay gracefully echo "๐Ÿ›‘ Stopping relay..." docker stop "$CONTAINER" || true sleep 5 # Backup data volume echo "๐Ÿ’พ Backing up data volume..." docker run --rm \ -v tor-guard-data:/data \ -v "$BACKUP_DIR/$TIMESTAMP":/backup \ alpine tar czf /backup/tor-data.tar.gz -C /data . # Backup logs volume echo "๐Ÿ“ Backing up logs..." docker run --rm \ -v tor-guard-logs:/data \ -v "$BACKUP_DIR/$TIMESTAMP":/backup \ alpine tar czf /backup/tor-logs.tar.gz -C /data . # Extract fingerprint for reference docker start "$CONTAINER" sleep 10 docker exec "$CONTAINER" cat /var/lib/tor/fingerprint > "$BACKUP_DIR/$TIMESTAMP/fingerprint.txt" || true # Create manifest cat > "$BACKUP_DIR/$TIMESTAMP/MANIFEST.txt" << EOF Tor Guard Relay Backup Timestamp: $TIMESTAMP Container: $CONTAINER Relay: $(grep Nickname /opt/tor-relay/relay.conf | cut -d' ' -f2) Files: - tor-data.tar.gz (Relay identity and state) - tor-logs.tar.gz (Tor logs for audit) - fingerprint.txt (Relay fingerprint reference) EOF # Cleanup old backups (keep last 30 days) echo "๐Ÿงน Cleaning up old backups..." find "$BACKUP_DIR" -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \; # Summary echo "โœ… Backup complete: $BACKUP_DIR/$TIMESTAMP" du -sh "$BACKUP_DIR/$TIMESTAMP" ``` #### Make Executable ```bash chmod +x /usr/local/bin/backup-tor-relay.sh ``` #### Add to Cron (Daily at 2 AM) ```bash # Edit crontab crontab -e # Add line: 0 2 * * * /usr/local/bin/backup-tor-relay.sh >> /var/log/tor-backup.log 2>&1 ``` #### Monitor Backup Logs ```bash # View backup logs tail -f /var/log/tor-backup.log # Check backup history ls -lah /backups/tor-relay/ ``` --- ### Method 4: Off-Site Backup (Cloud/External) **Pros:** Disaster recovery, geographic redundancy **Cons:** Security risk if not encrypted, potential costs #### Encrypt Backup Before Upload ```bash # Generate encryption key (save this somewhere secure!) openssl rand -base64 32 > ~/tor-relay-backup.key # Encrypt backup before upload gpg --symmetric --cipher-algo AES256 \ --output tor-data-encrypted.tar.gz.gpg \ tor-data-$(date +%s).tar.gz # Upload to cloud (e.g., AWS S3) aws s3 cp tor-data-encrypted.tar.gz.gpg s3://my-backups/tor-relay/ ``` #### Decrypt When Needed ```bash # Decrypt backup gpg --decrypt tor-data-encrypted.tar.gz.gpg > tor-data-restored.tar.gz # Verify integrity tar tzf tor-data-restored.tar.gz | head -10 ``` --- ## Recovery Procedures ### Scenario 1: Container Corruption **Problem:** Container is running but data is corrupted **Recovery time:** 15 minutes #### Steps ```bash # 1. Stop the relay docker stop guard-relay # 2. Remove corrupted volume docker volume rm tor-guard-data # 3. Create new volume docker volume create tor-guard-data # 4. Restore from backup docker run --rm \ -v tor-guard-data:/data \ -v ~/tor-relay-backups/2024-01-01:/backup \ alpine tar xzf /backup/tor-data-1704110400.tar.gz -C /data # 5. Verify permissions docker exec guard-relay chown -R tor:tor /var/lib/tor # 6. Restart relay docker start guard-relay # 7. Monitor startup docker logs -f guard-relay ``` --- ### Scenario 2: Server Failure - Full Restore **Problem:** Entire server lost, migrating to new hardware **Recovery time:** 30 minutes #### Steps ```bash # 1. Prepare new server with Docker # 2. Copy backup to new server scp -r ~/tor-relay-backups/2024-01-01 user@new-server:/tmp/ # 3. On new server, create volume and restore docker volume create tor-guard-data docker run --rm \ -v tor-guard-data:/data \ -v /tmp/2024-01-01:/backup \ alpine tar xzf /backup/tor-data-1704110400.tar.gz -C /data # 4. Copy relay configuration scp /opt/tor-relay/relay.conf user@new-server:/opt/tor-relay/ # 5. On new server, start relay docker run -d \ --name guard-relay \ --network host \ -v /opt/tor-relay/relay.conf:/etc/tor/torrc:ro \ -v tor-guard-data:/var/lib/tor \ -v tor-guard-logs:/var/log/tor \ --restart unless-stopped \ r3bo0tbx1/onion-relay:latest # 6. Verify relay is using old identity docker exec guard-relay fingerprint # Should match original fingerprint! ``` --- ### Scenario 3: Key Loss - Emergency Recovery **Problem:** All keys lost, only backup exists **Recovery time:** 5 minutes #### Restore Keys Only ```bash # Stop relay docker stop guard-relay # Clear tor data docker run --rm \ -v tor-guard-data:/data \ alpine rm -rf /data/* # Restore from backup docker run --rm \ -v tor-guard-data:/data \ -v ~/tor-relay-backups/keys-only:/backup \ alpine bash -c "cp -r /backup/* /data/" # Fix permissions docker exec guard-relay chown -R tor:tor /var/lib/tor docker exec guard-relay chmod 700 /var/lib/tor/keys # Restart docker start guard-relay # Verify identity recovered docker exec guard-relay fingerprint ``` --- ## Migration Guide ### Move Relay to New Server (Same Identity) **Goal:** Keep relay fingerprint, move to new hardware #### Pre-Migration Checklist - โœ… Recent full backup created - โœ… New server prepared with Docker - โœ… Network firewall rules ready - โœ… DNS/IP planning done - โœ… Maintenance window scheduled #### Step-by-Step Migration ```bash # === ON OLD SERVER === # 1. Create final backup docker stop guard-relay sleep 5 docker run --rm \ -v tor-guard-data:/data \ -v ~/tor-relay-backups/migration:/backup \ alpine tar czf /backup/tor-data-final.tar.gz -C /data . # 2. Verify backup ls -lh ~/tor-relay-backups/migration/ # === TRANSFER TO NEW SERVER === # 3. Copy backup securely scp -r ~/tor-relay-backups/migration user@new-server:/tmp/ # 4. Copy relay configuration scp /opt/tor-relay/relay.conf user@new-server:/opt/tor-relay/ # === ON NEW SERVER === # 5. Create volume and restore docker volume create tor-guard-data docker run --rm \ -v tor-guard-data:/data \ -v /tmp/migration:/backup \ alpine tar xzf /backup/tor-data-final.tar.gz -C /data # 6. Start relay on new server docker run -d \ --name guard-relay \ --network host \ -v /opt/tor-relay/relay.conf:/etc/tor/torrc:ro \ -v tor-guard-data:/var/lib/tor \ -v tor-guard-logs:/var/log/tor \ --restart unless-stopped \ r3bo0tbx1/onion-relay:latest # 7. Verify startup and identity docker logs -f guard-relay docker exec guard-relay fingerprint # === FINAL VERIFICATION === # 8. Check on Tor Metrics (should recognize old fingerprint within hours) # https://metrics.torproject.org/rs.html # 9. After verification, on old server: docker stop guard-relay docker rm guard-relay ``` #### Verification After Migration ```bash # Check logs for successful bootstrap docker logs guard-relay 2>&1 | grep "Bootstrapped 100" # Verify fingerprint matches backup docker exec guard-relay fingerprint # Compare with: cat ~/tor-relay-backups/migration/fingerprint.txt # Monitor for 24 hours for any issues docker stats guard-relay --no-stream ``` --- ### Zero-Downtime Migration (Advanced) **Goal:** Migrate relay without downtime by running dual servers #### Setup ```bash # 1. OLD SERVER: Create backup docker stop guard-relay docker run --rm \ -v tor-guard-data:/data \ -v ~/tor-relay-backups/dual:/backup \ alpine tar czf /backup/tor-data.tar.gz -C /data . # 2. NEW SERVER: Restore backup and start docker volume create tor-guard-data docker run --rm \ -v tor-guard-data:/data \ -v /tmp/dual:/backup \ alpine tar xzf /backup/tor-data.tar.gz -C /data docker run -d \ --name guard-relay \ --network host \ -v /opt/tor-relay/relay.conf:/etc/tor/torrc:ro \ -v tor-guard-data:/var/lib/tor \ -v tor-guard-logs:/var/log/tor \ --restart unless-stopped \ r3bo0tbx1/onion-relay:latest # 3. Verify NEW server is running docker logs guard-relay | grep "Bootstrapped" # 4. Wait 30 minutes for NEW server to stabilize sleep 1800 # 5. OLD SERVER: Restart old relay docker start guard-relay # 6. Both servers now running same relay identity # Tor network handles this gracefully # 7. OLD SERVER: After 24 hours, shut down docker stop guard-relay ``` --- ## Best Practices ### โœ… DO - โœ… **Backup immediately after bootstrap** - Preserve identity - โœ… **Use strong encryption** for off-site backups - โœ… **Test restores regularly** - Backups are worthless if unverifiable - โœ… **Document fingerprints** - Keep reference copy of fingerprint - โœ… **Automate backups** - Set and forget with cron - โœ… **Store backups securely** - Encrypt sensitive data - โœ… **Keep multiple copies** - Local + off-site minimum - โœ… **Version your backups** - Date-stamped directories ### โŒ DON'T - โŒ **Don't backup `/etc/tor/torrc`** - Mount as read-only from host - โŒ **Don't share backup media unencrypted** - Keys are sensitive - โŒ **Don't rely on single backup** - 3-2-1 rule applies - โŒ **Don't ignore backup failures** - Monitor logs - โŒ **Don't delete old backups immediately** - Keep 30+ days ### ๐Ÿ“Š 3-2-1 Backup Rule Maintain at minimum: - **3 copies** of your data - Original (running relay) - Backup 1 (local storage) - Backup 2 (off-site) - **2 different media types** - NVMe/SSD - USB external drive - **1 off-site copy** - Cloud storage (encrypted) - Or remote server --- ## Troubleshooting ### Backup Failed: "Volume is in use" ```bash # Problem: Cannot backup running volume # Solution: Stop relay first docker stop guard-relay sleep 5 # Retry backup command ``` ### Restore Failed: "File permissions denied" ```bash # Problem: Restored files have wrong ownership # Solution: Fix permissions docker exec guard-relay chown -R tor:tor /var/lib/tor docker exec guard-relay chmod 700 /var/lib/tor/keys ``` ### Fingerprint Changed After Restore ```bash # Problem: Restored relay has different fingerprint # Cause: Keys weren't backed up, only state # Solution: Use Method 2 (Direct Key Extraction) for future backups # For now, accept new identity: docker exec guard-relay fingerprint # This is your new permanent fingerprint ``` --- ## Reference **Backup Command Cheat Sheet:** ```bash # Quick backup (stop relay) docker stop guard-relay && \ docker run --rm -v tor-guard-data:/data -v ~/backups:/backup alpine tar czf /backup/tor-$(date +%s).tar.gz -C /data . && \ docker start guard-relay # Quick restore docker run --rm -v tor-guard-data:/data -v ~/backups:/backup alpine tar xzf /backup/tor-1704110400.tar.gz -C /data # Verify backup integrity tar tzf ~/backups/tor-1704110400.tar.gz | head -20 # Calculate backup size du -sh ~/backups/tor-1704110400.tar.gz ``` --- ## Support - ๐Ÿ“– [Main README](../README.md) - ๐Ÿš€ [Deployment Guide](./DEPLOYMENT.md) - ๐Ÿ› [Report Issues](https://github.com/r3bo0tbx1/tor-guard-relay/issues) - ๐Ÿ’ฌ [Tor Relay Forum](https://forum.torproject.org/)