Files
rE-Bo0t.bx1 90b65ee469 🔖 release(v1.1.6): bind mount fix, full repo audit, workflow fixes
🔧 Entrypoint:
- Detect wrong ownership on /var/lib/tor and /var/lib/tor/keys at startup
  with actionable chown commands before Tor fails cryptically in Phase 4
- Accept DEBUG=TRUE, DEBUG=1, DEBUG=yes (case-insensitive)
- Fix signal trap bug: inner cleanup_verify_tmp no longer overwrites
  the global TERM/INT handler (could skip graceful shutdown)

🛡️ Security:
- Deprecate all versions < v1.1.5 (CVE-2025-15467, OpenSSL CVSS 9.8)
- Add deprecation notice to README and SECURITY.md
- Update lifecycle tables in CHANGELOG and SECURITY

🐛 Bug Fixes:
- Fix bootstrap detection in migrate-from-official.sh
  (parsed non-existent "bootstrap_percent" field — now "bootstrap")
- Fix health JSON docs across 4 files: uptime_seconds → uptime,
  add missing pid/errors fields, correct reachable type to string
- Fix validate.yml: bash -n → sh -n (POSIX script, not bash)

📚 Documentation:
- Add "Bind Mount Ownership" troubleshooting section to README
- Fix chown 1000:1000 typo → 100:101 in TROUBLESHOOTING-BRIDGE-MIGRATION.md
- Add [1.1.6] changelog entry
- Update version references across 20+ files to v1.1.6
- Update 47x alpine:3.22.2 → 3.23.3 across migration docs/scripts
- Fix tool count 4 → 5 in DEPLOYMENT, ARCHITECTURE, TROUBLESHOOTING
- Remove 5 broken links (CLAUDE.md, CONTRIBUTORS.md, SECURITY-AUDIT-REPORT.md)
- Fix stale image tags (:1.1.1/:1.1.2 → :latest) in 4 files
- Rewrite PR template as clean reusable form

⚙️ Workflow (release.yml):
- Fix duplicate title in release body (name + body both had ## 🧅 header)
- Fix trailing --- not being stripped from changelog extract
- Fix Full Changelog link comparing current tag to itself
- Extract Alpine version from Dockerfile instead of hardcoding
- Add fetch-depth: 0 for git history in release-notes job
- Fix fallback commit range when no conventional commits found

🐳 Dockerfiles:
- Fix stale base.name label (alpine:3.23.0 → alpine:3.23.3)
- Fix trailing whitespace after backslash in Dockerfile.edge

📋 Templates:
- Update cosmos-compose and docker-compose versions to 1.1.6
2026-02-08 16:04:22 +05:30

13 KiB
Raw Permalink Blame History

Migration Scripts

This directory contains automated migration tools for upgrading from other Tor relay images to r3bo0tbx1/onion-relay.

migrate-from-official.sh

Automated migration assistant for users moving from the official thetorproject/obfs4-bridge image to this project.

What It Does

  1. Detects existing setup - Finds your running official bridge container and extracts configuration
  2. Backs up data - Creates tar.gz backup of your Tor data volume (keys, state)
  3. Fixes UID mismatch - Corrects ownership from Debian (UID 101) to Alpine (UID 100)
  4. Deploys new container - Creates new container with same configuration
  5. Validates migration - Verifies fingerprint preservation and bridge functionality
  6. Provides next steps - Clear guidance on monitoring and verification

Why You Need This

The official thetorproject/obfs4-bridge image uses:

  • Base: Debian
  • User: debian-tor (UID 101)

This project uses:

  • Base: Alpine Linux
  • User: tor (UID 100)

Without fixing the UID mismatch, you'll get permission errors:

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

Quick Start

# Interactive migration (recommended)
./scripts/migration/migrate-from-official.sh

# The script will:
# 1. Detect your existing container
# 2. Extract NICKNAME, EMAIL, OR_PORT, PT_PORT
# 3. Prompt for confirmation before each step
# 4. Create backup in ~/tor-backups/
# 5. Fix ownership automatically
# 6. Deploy new container
# 7. Validate fingerprint matches

Manual Mode

If you don't have a running official container, the script supports manual configuration:

./scripts/migration/migrate-from-official.sh

# When prompted "No thetorproject/obfs4-bridge container found":
# Choose "Continue with manual configuration"

# You'll be asked for:
# - Volume name (e.g., obfs4-data)
# - New container name (default: tor-bridge)
# - OR_PORT (default: 9001)
# - PT_PORT (default: 9002)
# - NICKNAME
# - EMAIL

What Gets Preserved

Identity keys - Your relay's cryptographic identity Fingerprint - Relay reputation and statistics Bridge credentials - obfs4 state and bridge line Tor state - Bootstrap state and consensus cache

Migration Checklist

Before running:

  • Note your current fingerprint: docker exec <container> cat /var/lib/tor/fingerprint
  • Save your bridge line: docker exec <container> cat /var/lib/tor/pt_state/obfs4_bridgeline.txt
  • Verify volume name: docker inspect <container> --format='{{range .Mounts}}{{.Name}}{{end}}'
  • Ensure sufficient disk space for backup (~100 MB typical)

After migration:

  • Verify fingerprint matches old fingerprint
  • Check bootstrap progress: docker exec tor-bridge status
  • Verify bridge line: docker exec tor-bridge bridge-line
  • Check Tor Metrics (may take 24h): https://metrics.torproject.org/rs.html#search/YOUR_FINGERPRINT
  • Monitor logs for 24 hours: docker logs -f tor-bridge
  • Keep backup for at least 1 week

Script Features

Automatic Detection:

  • Finds thetorproject/obfs4-bridge containers
  • Extracts ENV variables (NICKNAME, EMAIL, OR_PORT, PT_PORT)
  • Detects volume mounts automatically
  • Reads current fingerprint from volume

Safety Features:

  • Creates backup before any changes
  • Validates each step before proceeding
  • Preserves old container (stopped, not deleted)
  • Provides rollback instructions
  • Confirms before destructive operations

Validation:

  • Checks volume ownership (100:101)
  • Waits for container startup (60s timeout)
  • Waits for Tor bootstrap (300s timeout)
  • Compares old vs new fingerprint
  • Validates bridge line generation
  • Runs health checks

User Experience:

  • Color-coded output (errors, warnings, success)
  • Progress indicators with step numbers
  • Clear next steps after completion
  • Helpful error messages with troubleshooting

Example Output

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Migration Assistant: Official Tor Bridge → Onion Relay
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

This script automates migration from:
  Source: thetorproject/obfs4-bridge (Debian, UID 101)
  Target: r3bo0tbx1/onion-relay (Alpine, UID 100)


━━━ Step 1: Pre-flight Checks
✅ Docker is available

━━━ Step 2: Detect Existing Setup
✅ Found container: obfs4-bridge
 Configuration detected:
   Nickname: MyBridge
   Email: admin@example.com
   OR Port: 9001
   PT Port: 9002
 Volume mounts:
   obfs4-data → /var/lib/tor
 Checking current fingerprint...
✅ Current fingerprint: 1234567890ABCDEF1234567890ABCDEF12345678

❓ Proceed with migration? [y/N]: y

━━━ Step 3: Backup Current Data
❓ Create backup of volume 'obfs4-data'? [y/N]: y
 Creating backup of volume 'obfs4-data'...
✅ Backup created: /home/user/tor-backups/tor-backup-20250114-120000.tar.gz

━━━ Step 4: Stop Old Container
 Stopping container: obfs4-bridge
✅ Container stopped
❓ Remove old container 'obfs4-bridge'? (keeps volumes) [y/N]: y
✅ Container removed

━━━ Step 5: Fix Volume Ownership
 Current ownership: 101:101
 Fixing ownership: debian-tor (101) → tor (100)...
 Current ownership: 101:101
 New ownership: 100:101
✅ Ownership fixed successfully

━━━ Step 6: Deploy New Container
 Deploying new container: tor-bridge
 Image: r3bo0tbx1/onion-relay:latest
 Running command:
  docker run -d \
    --name tor-bridge \
    --network host \
    --restart unless-stopped \
    ...
✅ Container started

━━━ Step 7: Wait for Container to Start
 Waiting for container to start (max 60s)...
✅ Container is running

━━━ Step 8: Wait for Tor Bootstrap
 Waiting for Tor to bootstrap (max 300s)...
 Bootstrap progress: 5%
 Bootstrap progress: 25%
 Bootstrap progress: 75%
 Bootstrap progress: 90%
✅ Tor fully bootstrapped (100%)

━━━ Step 9: Validate Migration
 Checking fingerprint...
✅ Fingerprint: 1234567890ABCDEF1234567890ABCDEF12345678
✅ Fingerprint matches (relay identity preserved)
 Checking bridge line...
✅ Bridge line generated successfully
 Bridge line:
  obfs4 1.2.3.4:9002 1234567890ABCDEF1234567890ABCDEF12345678 cert=... iat-mode=0
 Checking health status...
✅ Health check passed

━━━ Migration Complete!

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Migration Successful
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Next Steps:

1⃣  Check container status:
   docker exec tor-bridge status

2⃣  View logs:
   docker logs -f tor-bridge

3⃣  Get bridge line (after bootstrap complete):
   docker exec tor-bridge bridge-line

4⃣  Check fingerprint on Tor Metrics:
   https://metrics.torproject.org/rs.html#details/1234567890ABCDEF1234567890ABCDEF12345678

5⃣  Monitor resource usage:
   docker stats tor-bridge

Troubleshooting

Migration Failed at Ownership Fix

Symptom: "Failed to fix ownership" error

Cause: Volume is mounted as read-only or insufficient permissions

Solution:

# Manually fix ownership
docker run --rm -v <volume-name>:/data alpine:3.23.3 chown -R 100:101 /data

# Verify
docker run --rm -v <volume-name>:/data alpine:3.23.3 ls -ldn /data
# Should show: drwx------ 5 100 101 ...

Fingerprint Mismatch After Migration

Symptom: Old and new fingerprints don't match

Cause: Identity keys were not preserved or volume mount incorrect

Solution:

# Check if keys exist in volume
docker run --rm -v <volume-name>:/data alpine:3.23.3 ls -la /data/keys/

# Should see:
# - secret_id_key
# - ed25519_master_id_public_key
# - ed25519_master_id_secret_key
# - ed25519_signing_cert
# - ed25519_signing_secret_key

# If keys are missing, restore from backup:
docker run --rm -v <volume-name>:/data -v /path/to:/backup alpine:3.23.3 \
  tar xzf /backup/tor-backup-*.tar.gz -C /data

# Fix ownership again
docker run --rm -v <volume-name>:/data alpine:3.23.3 chown -R 100:101 /data

# Recreate container
docker rm -f tor-bridge
./scripts/migration/migrate-from-official.sh

Bootstrap Timeout

Symptom: "Timeout waiting for bootstrap completion"

Cause: Tor network is slow or connectivity issues

Solution:

# Check if Tor is actually running
docker exec tor-bridge pgrep tor

# Check logs for errors
docker logs tor-bridge 2>&1 | tail -50

# Manual bootstrap check
docker exec tor-bridge health | jq .

# Wait longer (Tor can take 5-10 minutes on first run)
watch -n5 'docker exec tor-bridge health | jq .bootstrap'

Container Exits Immediately

Symptom: Container starts but immediately exits

Cause: Configuration error or volume permission issues

Solution:

# Check container logs
docker logs tor-bridge

# Common issues:
# 1. "Directory /var/lib/tor cannot be read: Permission denied"
#    → Run ownership fix again

# 2. "Invalid configuration"
#    → Check ENV variables: docker inspect tor-bridge --format='{{range .Config.Env}}{{println .}}{{end}}'

# 3. "Could not bind to 0.0.0.0:9001: Address already in use"
#    → Change OR_PORT or stop conflicting service

Bridge Line Not Generated

Symptom: docker exec tor-bridge bridge-line returns empty

Cause: Bootstrap not complete or obfs4 not configured

Solution:

# Check bootstrap status
docker exec tor-bridge status

# Should show "Bootstrap: 100% (done)"

# Check if lyrebird (obfs4) is running
docker exec tor-bridge pgrep lyrebird

# Check obfs4 state file
docker exec tor-bridge cat /var/lib/tor/pt_state/obfs4_state.json

# Wait 5 minutes after 100% bootstrap, then try again
docker exec tor-bridge bridge-line

Rollback Procedure

If migration fails or you want to revert:

# 1. Stop new container
docker stop tor-bridge
docker rm tor-bridge

# 2. Restore from backup (if needed)
docker run --rm \
  -v <volume-name>:/data \
  -v /path/to/backup:/backup \
  alpine:3.23.3 sh -c 'rm -rf /data/* && tar xzf /backup/tor-backup-*.tar.gz -C /data'

# 3. Fix ownership back to Debian UID 101 (if returning to official image)
docker run --rm -v <volume-name>:/data alpine:3.23.3 chown -R 101:101 /data

# 4. Restart old container
docker start obfs4-bridge

# OR deploy official image again
docker run -d \
  --name obfs4-bridge \
  --network host \
  -e NICKNAME="MyBridge" \
  -e EMAIL="admin@example.com" \
  -e OR_PORT=9001 \
  -e PT_PORT=9002 \
  -v <volume-name>:/var/lib/tor \
  thetorproject/obfs4-bridge:latest

Security Notes

The script is safe because:

  • Stops containers before modifying data
  • Creates backups before making changes
  • Validates each step before proceeding
  • Never deletes volumes (only fixes ownership)
  • Preserves old container until you confirm success
  • Uses official Alpine image for ownership fixes

What to verify after migration:

  • Container is running: docker ps | grep tor-bridge
  • Tor is bootstrapped: docker exec tor-bridge status
  • Fingerprint unchanged: Compare with your saved fingerprint
  • Bridge line works: Test obfs4 connection from client
  • Logs are clean: docker logs tor-bridge should show no errors
  • Tor Metrics updated (24h): Check bridge appears on metrics.torproject.org

Additional Resources

Support

If you encounter issues:

  1. Check logs: docker logs tor-bridge
  2. Run diagnostics: docker exec tor-bridge status
  3. Verify volume: docker run --rm -v <volume>:/data alpine ls -la /data
  4. Check FAQ: See docs/FAQ.md for common issues
  5. Review architecture: See docs/ARCHITECTURE.md for technical details

Contributing

Found a bug or have a suggestion? Open an issue or pull request on GitHub.

License

Same license as the main project (see repository root LICENSE file).