mirror of
https://github.com/r3bo0tbx1/tor-guard-relay.git
synced 2026-04-05 16:22:01 +02:00
✨ 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.
This commit is contained in:
18
.github/workflows/validate.yml
vendored
18
.github/workflows/validate.yml
vendored
@@ -78,7 +78,7 @@ jobs:
|
||||
else
|
||||
# Check all files in tools/ (no .sh extension)
|
||||
TOOL_COUNT=0
|
||||
for script in tools/status tools/health tools/fingerprint tools/bridge-line tools/gen-auth; do
|
||||
for script in tools/status tools/health tools/fingerprint tools/bridge-line tools/gen-auth tools/gen-family; do
|
||||
if [ -f "$script" ]; then
|
||||
echo "📄 Checking $(basename "$script")..."
|
||||
sh -n "$script" || exit 1
|
||||
@@ -115,7 +115,7 @@ jobs:
|
||||
if [ -d "tools" ]; then
|
||||
echo ""
|
||||
echo "🔍 ShellCheck: tools/*"
|
||||
for tool in tools/status tools/health tools/fingerprint tools/bridge-line tools/gen-auth; do
|
||||
for tool in tools/status tools/health tools/fingerprint tools/bridge-line tools/gen-auth tools/gen-family; do
|
||||
if [ -f "$tool" ]; then
|
||||
echo " Checking $(basename $tool)..."
|
||||
shellcheck -S warning "$tool" || true
|
||||
@@ -168,8 +168,8 @@ jobs:
|
||||
if [ $HAS_SH_EXT -eq 1 ]; then
|
||||
echo "❌ Some tools have .sh extension (should not have it)"
|
||||
exit 1
|
||||
elif [ $NO_EXT_COUNT -lt 4 ]; then
|
||||
echo "❌ Expected 5 tools (status, health, fingerprint, bridge-line, gen-auth)"
|
||||
elif [ $NO_EXT_COUNT -lt 5 ]; then
|
||||
echo "❌ Expected 6 tools (status, health, fingerprint, bridge-line, gen-auth, gen-family)"
|
||||
exit 1
|
||||
else
|
||||
echo "✅ All tools have correct format (no .sh extension)"
|
||||
@@ -335,7 +335,7 @@ jobs:
|
||||
docker run --rm --entrypoint /bin/sh tor-relay:test -c "ls -la /usr/local/bin/" || exit 1
|
||||
echo ""
|
||||
echo "🛠️ Available diagnostic tools:"
|
||||
docker run --rm --entrypoint /bin/sh tor-relay:test -c "ls -1 /usr/local/bin/status /usr/local/bin/health /usr/local/bin/fingerprint /usr/local/bin/bridge-line /usr/local/bin/gen-auth" || exit 1
|
||||
docker run --rm --entrypoint /bin/sh tor-relay:test -c "ls -1 /usr/local/bin/status /usr/local/bin/health /usr/local/bin/fingerprint /usr/local/bin/bridge-line /usr/local/bin/gen-auth /usr/local/bin/gen-family" || exit 1
|
||||
|
||||
- name: 🧅 Verify Tor Installation
|
||||
run: |
|
||||
@@ -564,7 +564,7 @@ jobs:
|
||||
if: matrix.test-case == 'help-flags'
|
||||
run: |
|
||||
echo "🧪 Testing tool existence..."
|
||||
for tool in status health fingerprint bridge-line; do
|
||||
for tool in status health fingerprint bridge-line gen-auth gen-family; do
|
||||
TOOL_PATH="/usr/local/bin/$tool"
|
||||
if docker run --rm --entrypoint /bin/sh tor-relay:test -c "test -f $TOOL_PATH"; then
|
||||
echo "✅ $tool exists at $TOOL_PATH"
|
||||
@@ -579,7 +579,7 @@ jobs:
|
||||
run: |
|
||||
echo "🔐 Verifying file permissions for tools..."
|
||||
docker run --rm --entrypoint /bin/sh tor-relay:test -c "
|
||||
for tool in /usr/local/bin/status /usr/local/bin/health /usr/local/bin/fingerprint /usr/local/bin/bridge-line /usr/local/bin/gen-auth; do
|
||||
for tool in /usr/local/bin/status /usr/local/bin/health /usr/local/bin/fingerprint /usr/local/bin/bridge-line /usr/local/bin/gen-auth /usr/local/bin/gen-family; do
|
||||
if [ -f \"\$tool\" ]; then
|
||||
test -x \"\$tool\" && echo \"✅ \$(basename \$tool) is executable\" || exit 1
|
||||
fi
|
||||
@@ -607,7 +607,7 @@ jobs:
|
||||
run: |
|
||||
echo "🔧 Testing tool execution..."
|
||||
docker run --rm --entrypoint /bin/sh tor-relay:test -c "
|
||||
for tool in /usr/local/bin/status /usr/local/bin/health /usr/local/bin/fingerprint /usr/local/bin/bridge-line /usr/local/bin/gen-auth; do
|
||||
for tool in /usr/local/bin/status /usr/local/bin/health /usr/local/bin/fingerprint /usr/local/bin/bridge-line /usr/local/bin/gen-auth /usr/local/bin/gen-family; do
|
||||
if [ -f \"\$tool\" ]; then
|
||||
BASENAME=\$(basename \"\$tool\")
|
||||
echo \"🔍 Testing \$BASENAME...\"
|
||||
@@ -653,7 +653,7 @@ jobs:
|
||||
- 🏗️ Docker image build (multi-arch ready)
|
||||
- 🚀 Container smoke test
|
||||
- 🧅 Tor installation verification
|
||||
- 🔧 Tool availability check (status, health, fingerprint, bridge-line, gen-auth)
|
||||
- 🔧 Tool availability check (status, health, fingerprint, bridge-line, gen-auth, gen-family)
|
||||
- 🔐 Permission verification
|
||||
- 🛡️ Security scanning with Trivy
|
||||
- 🧪 Test matrix execution
|
||||
|
||||
57
CHANGELOG.md
57
CHANGELOG.md
@@ -16,11 +16,59 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
---
|
||||
|
||||
## [1.1.7] - 2026-03-02
|
||||
|
||||
### 🎉 Happy Family Support (Tor 0.4.9+)
|
||||
|
||||
This release introduces full support for Tor's new **Happy Family** system (`FamilyId`), which replaces the legacy `MyFamily` fingerprint-exchange workflow. Relay operators can now link all their relays into a family using a single cryptographic key instead of manually listing every fingerprint on every relay.
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **New Tool: `gen-family`**: Generate or view Tor Happy Family keys inside the container. Supports `gen-family <Name>` (generate), `gen-family --show` (view existing), `gen-family --force` (overwrite without backup), and `gen-family --help`.
|
||||
- **`FamilyId` ENV Support**: New `TOR_FAMILY_ID` environment variable to set the `FamilyId` directive in generated torrc (guard/middle/exit modes).
|
||||
- **`MyFamily` ENV Support**: New `TOR_MY_FAMILY` environment variable (comma-separated fingerprints) for backward compatibility with the legacy `MyFamily` directive.
|
||||
- **Family Key Detection**: Phase 2 of the entrypoint now scans `/var/lib/tor/keys/*.secret_family_key` and logs detected keys at startup.
|
||||
- **Import Workflow**: Operators can import existing family keys from bare-metal Tor installations via `docker cp` + ownership fix (`chown 100:101`).
|
||||
|
||||
### ⚙️ Changed
|
||||
|
||||
- **Entrypoint** (`docker-entrypoint.sh`): Phase 2 now detects family keys; config generation for guard/middle and exit modes appends `FamilyId` and `MyFamily` lines when the corresponding ENV vars are set.
|
||||
- **Dockerfiles** (`Dockerfile`, `Dockerfile.edge`): Added `COPY` and `chmod +x` for the new `gen-family` tool.
|
||||
- **`status` Tool** (`tools/status`): Now displays family key count and Happy Family configuration status after the fingerprint section.
|
||||
- **Tool Count**: Increased from 5 to **6** diagnostic tools (status, health, fingerprint, bridge-line, gen-auth, **gen-family**).
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- **README.md**: Added comprehensive "Happy Family (Tor 0.4.9+)" section with Option A (generate new key) and Option B (import existing key), persistence safety table, updated tools table (6 tools), updated features list, added gen-family to flowchart diagram, and added troubleshooting entries.
|
||||
- **docs/ARCHITECTURE.md**: Updated all mermaid diagrams - container lifecycle, Phase 2, config generation (guard + exit), diagnostic tools subgraph, directory structure. Updated tool characteristics table, references table, and bumped doc version to 1.1.0.
|
||||
- **docs/TOOLS.md**: Added full `gen-family` documentation section with usage, output examples, exit codes, and "Set Up Happy Family" workflow. Updated count from 5 → 6 tools and FAQ.
|
||||
- **docs/DEPLOYMENT.md**: Updated diagnostic tool count references (5 → 6) across 3 locations.
|
||||
- **docs/MIGRATION.md**: Added `gen-family --show` to post-migration diagnostic checklist.
|
||||
- **docs/MIGRATION-V1.1.X.md**: Added `gen-family` to diagnostic tool verification checklist.
|
||||
- **Example Configs**: Added commented `FamilyId` and `MyFamily` placeholders to `relay-guard.conf`, `relay-exit.conf`, and `relay-bridge.conf`.
|
||||
- **Docker Compose Templates**: Added `TOR_FAMILY_ID` and `TOR_MY_FAMILY` env vars to guard, exit, and multi-relay templates with setup instructions (Option A/B).
|
||||
- **Directory Authority Voting**: Added explanation of how Tor's 9 directory authorities vote on relay flags (Guard, Stable, Fast, HSDir) and that at least 5 of 9 must agree in consensus, across README, FAQ, DEPLOYMENT, and MULTI-MODE docs.
|
||||
- **CIISS v2 ContactInfo**: Added documentation for the [ContactInfo Information Sharing Specification v2](https://nusenu.github.io/ContactInfo-Information-Sharing-Specification/) with field reference table, generator link, and `proof:uri-rsa` verification explanation. Updated all `TOR_CONTACT_INFO` examples to use CIISS v2 format.
|
||||
|
||||
### 🔁 CI/CD
|
||||
|
||||
- **validate.yml**: Added `gen-family` to shell lint, ShellCheck, tool extension verification (threshold 5 → 6), integration tool checks, help-flags test, file-permissions test, and tool-executability test. Updated build summary.
|
||||
- **scripts/utilities/security-validation-tests.sh**: Added `gen-family` to tool security checks and syntax validation loops.
|
||||
- **scripts/utilities/quick-test.sh**: Added Test 4.5 for `gen-family --help` executability. Updated summary line.
|
||||
|
||||
### 🛡️ Security
|
||||
|
||||
- **SECURITY.md**: Updated supported versions table (1.1.7 active, 1.1.6 maintenance). Added `gen-family` to diagnostic tools list.
|
||||
|
||||
> **BREAKING CHANGES:** None. The `TOR_FAMILY_ID` and `TOR_MY_FAMILY` environment variables are entirely optional. Existing deployments continue to work without changes.
|
||||
|
||||
---
|
||||
|
||||
## [1.1.6] - 2026-02-08
|
||||
|
||||
### 🐛 Fixed
|
||||
* **Bind Mount Ownership:** Added startup detection for bind-mounted data/keys directories with incorrect ownership. The entrypoint now warns users with actionable `chown` commands when volumes are not writable by the `tor` user (UID 100, GID 101).
|
||||
* **DEBUG Flag:** Made the `DEBUG` environment variable case-insensitive — now accepts `true`, `TRUE`, `1`, `yes`, `YES`.
|
||||
* **DEBUG Flag:** Made the `DEBUG` environment variable case-insensitive - now accepts `true`, `TRUE`, `1`, `yes`, `YES`.
|
||||
* **Documentation Typo:** Fixed incorrect `chown 1000:1000` → `chown 100:101` in bridge migration troubleshooting guide.
|
||||
|
||||
### 🛡️ Security
|
||||
@@ -455,7 +503,7 @@ BREAKING CHANGES: None
|
||||
## 📊 Release Information
|
||||
|
||||
* **🎉 First Release:** v1.0.0 (November 1, 2025)
|
||||
* **📦 Current Stable:** v1.1.6 (February 8, 2026)
|
||||
* **📦 Current Stable:** v1.1.7 (March 2, 2026)
|
||||
* **🔗 Latest Release:** [GitHub Releases](https://github.com/r3bo0tbx1/tor-guard-relay/releases/latest)
|
||||
* **🐳 Docker Images:**
|
||||
|
||||
@@ -468,14 +516,15 @@ BREAKING CHANGES: None
|
||||
|
||||
| Version | Status | Support Level |
|
||||
| --------- | --------------------- | ------------------------------------------- |
|
||||
| **1.1.6** | 🟢 🛡️ **Active** | Full support (current stable) |
|
||||
| **1.1.5** | 🟡 🔧 **Maintenance** | Security + critical fixes only |
|
||||
| **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. |
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Release Links
|
||||
|
||||
[1.1.7]: https://github.com/r3bo0tbx1/tor-guard-relay/releases/tag/v1.1.7
|
||||
[1.1.6]: https://github.com/r3bo0tbx1/tor-guard-relay/releases/tag/v1.1.6
|
||||
[1.1.5]: https://github.com/r3bo0tbx1/tor-guard-relay/releases/tag/v1.1.5
|
||||
[1.1.4]: https://github.com/r3bo0tbx1/tor-guard-relay/releases/tag/v1.1.4
|
||||
|
||||
@@ -60,6 +60,7 @@ COPY tools/health /usr/local/bin/health
|
||||
COPY tools/fingerprint /usr/local/bin/fingerprint
|
||||
COPY tools/bridge-line /usr/local/bin/bridge-line
|
||||
COPY tools/gen-auth /usr/local/bin/gen-auth
|
||||
COPY tools/gen-family /usr/local/bin/gen-family
|
||||
|
||||
RUN set -eux \
|
||||
&& chmod +x /usr/local/bin/docker-entrypoint.sh \
|
||||
@@ -69,6 +70,7 @@ RUN set -eux \
|
||||
/usr/local/bin/fingerprint \
|
||||
/usr/local/bin/bridge-line \
|
||||
/usr/local/bin/gen-auth \
|
||||
/usr/local/bin/gen-family \
|
||||
&& echo "🧩 Registered diagnostic tools:" \
|
||||
&& ls -lh /usr/local/bin/status /usr/local/bin/health /usr/local/bin/fingerprint /usr/local/bin/bridge-line
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ COPY tools/health /usr/local/bin/health
|
||||
COPY tools/fingerprint /usr/local/bin/fingerprint
|
||||
COPY tools/bridge-line /usr/local/bin/bridge-line
|
||||
COPY tools/gen-auth /usr/local/bin/gen-auth
|
||||
COPY tools/gen-family /usr/local/bin/gen-family
|
||||
|
||||
RUN set -eux \
|
||||
&& chmod +x /usr/local/bin/docker-entrypoint.sh \
|
||||
@@ -69,6 +70,7 @@ RUN set -eux \
|
||||
/usr/local/bin/fingerprint \
|
||||
/usr/local/bin/bridge-line \
|
||||
/usr/local/bin/gen-auth \
|
||||
/usr/local/bin/gen-family \
|
||||
&& echo "🧩 Registered diagnostic tools:" \
|
||||
&& ls -lh /usr/local/bin/status /usr/local/bin/health /usr/local/bin/fingerprint /usr/local/bin/bridge-line
|
||||
|
||||
|
||||
156
README.md
156
README.md
@@ -30,7 +30,7 @@
|
||||
- 🛡️ **Security-First** - Hardened Alpine Linux, non-root operation, and minimized port exposure
|
||||
- 🪶 **Very light** - Ultra-minimal 16.8 MB image
|
||||
- 🎯 **Simple** - One command to deploy, minimal configuration needed
|
||||
- 📊 **Observable** - 5 busybox-only diagnostic tools with JSON health API
|
||||
- 📊 **Observable** - 6 busybox-only diagnostic tools with JSON health API
|
||||
- 🌉 **Multi-Mode** - Supports guard, exit, and bridge (obfs4) relays
|
||||
- 🔄 **Automated** - Weekly security rebuilds, CI/CD ready
|
||||
- 📚 **Documented** - Comprehensive guides for deployment, monitoring, backup, and more
|
||||
@@ -157,11 +157,11 @@ We offer **two build variants** to match your risk tolerance and requirements:
|
||||
```bash
|
||||
# Pull from Docker Hub (easiest)
|
||||
docker pull r3bo0tbx1/onion-relay:latest
|
||||
docker pull r3bo0tbx1/onion-relay:1.1.6
|
||||
docker pull r3bo0tbx1/onion-relay:1.1.7
|
||||
|
||||
# Pull from GHCR
|
||||
docker pull ghcr.io/r3bo0tbx1/onion-relay:latest
|
||||
docker pull ghcr.io/r3bo0tbx1/onion-relay:1.1.6
|
||||
docker pull ghcr.io/r3bo0tbx1/onion-relay:1.1.7
|
||||
```
|
||||
|
||||
### Edge Variant (Testing Only)
|
||||
@@ -180,7 +180,7 @@ docker pull r3bo0tbx1/onion-relay:edge
|
||||
|
||||
# Pull from GHCR
|
||||
docker pull ghcr.io/r3bo0tbx1/onion-relay:edge
|
||||
docker pull ghcr.io/r3bo0tbx1/onion-relay:1.1.6-edge
|
||||
docker pull ghcr.io/r3bo0tbx1/onion-relay:1.1.7-edge
|
||||
```
|
||||
|
||||
**When to use edge:**
|
||||
@@ -230,7 +230,7 @@ See [Deployment Guide](docs/DEPLOYMENT.md) for complete instructions.
|
||||
|
||||
## 🔧 Diagnostic Tools
|
||||
|
||||
Five busybox-only diagnostic tools are included (since v1.1.1).
|
||||
Six busybox-only diagnostic tools are included.
|
||||
|
||||
| Tool | Purpose | Usage |
|
||||
|------|---------|--------|
|
||||
@@ -239,6 +239,7 @@ Five busybox-only diagnostic tools are included (since v1.1.1).
|
||||
| fingerprint | Show fingerprint | `docker exec tor-relay fingerprint` |
|
||||
| bridge-line | obfs4 line | `docker exec tor-relay bridge-line` |
|
||||
| gen-auth | Credentials for Nyx | `docker exec tor-relay gen-auth` |
|
||||
| gen-family | Happy Family key gen | `docker exec tor-relay gen-family MyRelays` |
|
||||
|
||||
```bash
|
||||
# Full health report with emojis
|
||||
@@ -263,7 +264,7 @@ Example JSON:
|
||||
}
|
||||
```
|
||||
|
||||
> 📖 **Complete reference:** See [Tools Documentation](docs/TOOLS.md) for all 5 tools with examples, JSON schema, and integration guides.
|
||||
> 📖 **Complete reference:** See [Tools Documentation](docs/TOOLS.md) for all 6 tools with examples, JSON schema, and integration guides.
|
||||
|
||||
---
|
||||
|
||||
@@ -340,10 +341,11 @@ STATUS=$(echo "$HEALTH" | jq -r '.status')
|
||||
- ✅ Graceful shutdown with cleanup
|
||||
|
||||
### Operations & Automation
|
||||
- ✅ **5 busybox-only diagnostic tools** (status, health, fingerprint, bridge-line, gen-auth)
|
||||
- ✅ **6 busybox-only diagnostic tools** (status, health, fingerprint, bridge-line, gen-auth, gen-family)
|
||||
- ✅ **JSON health API** for monitoring integration
|
||||
- ✅ **Multi-mode support** (guard, exit, bridge with obfs4)
|
||||
- ✅ **ENV-based config** (TOR_RELAY_MODE, TOR_NICKNAME, etc.)
|
||||
- ✅ **Happy Family support** (Tor 0.4.9+ key-based relay families)
|
||||
- ✅ **ENV-based config** (TOR_RELAY_MODE, TOR_NICKNAME, TOR_FAMILY_ID, etc.)
|
||||
- ✅ **Multi-architecture** builds (AMD64, ARM64)
|
||||
- ✅ **Weekly security rebuilds** via GitHub Actions
|
||||
- ✅ **Docker Compose templates** for single/multi-relay
|
||||
@@ -383,7 +385,7 @@ STATUS=$(echo "$HEALTH" | jq -r '.status')
|
||||
|
||||
### Technical Reference
|
||||
- **[Architecture](docs/ARCHITECTURE.md)** - ⭐ **NEW!** Technical architecture with Mermaid diagrams
|
||||
- **[Tools Reference](docs/TOOLS.md)** - ✨ **UPDATED!** Complete guide to all 5 diagnostic tools
|
||||
- **[Tools Reference](docs/TOOLS.md)** - ✨ **UPDATED!** Complete guide to all 6 diagnostic tools
|
||||
- **[Monitoring Guide](docs/MONITORING.md)** - ✨ **UPDATED!** External monitoring integration, JSON health API, alerts, and observability
|
||||
- **[Control Port Guide](docs/CONTROL-PORT.md)** - ⭐ **NEW!** Authentication setup and Nyx integration
|
||||
- **[Backup Guide](docs/BACKUP.md)** - Data persistence, recovery, and disaster planning
|
||||
@@ -409,7 +411,7 @@ STATUS=$(echo "$HEALTH" | jq -r '.status')
|
||||
|
||||
```ini
|
||||
Nickname MyTorRelay
|
||||
ContactInfo your-email@example.com
|
||||
ContactInfo email:your-email[]example.com url:https://example.com proof:uri-rsa ciissversion:2
|
||||
ORPort 9001
|
||||
ORPort [::]:9001
|
||||
DirPort 0
|
||||
@@ -419,6 +421,8 @@ DataDirectory /var/lib/tor
|
||||
Log notice file /var/log/tor/notices.log
|
||||
```
|
||||
|
||||
> 📝 **ContactInfo format:** We recommend the [ContactInfo Information Sharing Specification (CIISS) v2](https://nusenu.github.io/ContactInfo-Information-Sharing-Specification/), a machine-readable format that replaces `@` with `[]` and includes structured fields like `email:`, `url:`, `proof:`, `pgp:`, `hoster:`, and more. Use the [CIISS Generator](https://torcontactinfogenerator.netlify.app/) to create yours.
|
||||
|
||||
### Production Configuration
|
||||
|
||||
```ini
|
||||
@@ -438,6 +442,109 @@ Examples are found in the [`examples/`](examples/) directory for complete, annot
|
||||
|
||||
> 📖 **Configuration help:** See [Deployment Guide](docs/DEPLOYMENT.md#configuration) for complete reference.
|
||||
|
||||
### Happy Family (Tor 0.4.9+)
|
||||
|
||||
Tor 0.4.9 introduces **Happy Families**, a cryptographic key-based replacement for `MyFamily`. Instead of listing every relay fingerprint in every relay's config, all relays in a family share one secret key.
|
||||
|
||||
**Why upgrade?**
|
||||
- Eliminates huge `MyFamily` lists that waste bandwidth and memory
|
||||
- Simpler to maintain - one key file instead of N×N fingerprint entries
|
||||
- Required for future Arti Relay compatibility
|
||||
|
||||
#### Option A: Generate a new family key in Docker
|
||||
|
||||
Use this if you don't already have a family key from another setup.
|
||||
|
||||
```bash
|
||||
# 1. Generate a family key (run on any ONE relay container)
|
||||
docker exec tor-relay gen-family MyRelays
|
||||
|
||||
# 2. Note the FamilyId output - you need it for your torrc
|
||||
# FamilyId <value>
|
||||
|
||||
# 3. Copy the key to all your other relay containers
|
||||
docker cp tor-relay:/var/lib/tor/keys/MyRelays.secret_family_key .
|
||||
docker cp MyRelays.secret_family_key other-relay:/var/lib/tor/keys/
|
||||
|
||||
# 4. Fix ownership and permissions inside the target container
|
||||
docker exec -u 0 other-relay chown 100:101 /var/lib/tor/keys/MyRelays.secret_family_key
|
||||
docker exec -u 0 other-relay chmod 600 /var/lib/tor/keys/MyRelays.secret_family_key
|
||||
|
||||
# 5. Add FamilyId to each relay's torrc, then restart
|
||||
docker restart tor-relay other-relay
|
||||
```
|
||||
|
||||
#### Option B: Import an existing family key into Docker
|
||||
|
||||
Use this if you already generated a family key on a bare-metal or source-built Tor relay and want to use the same key for your Docker relays.
|
||||
|
||||
```bash
|
||||
# 1. Transfer the .secret_family_key file to your Docker host
|
||||
# (via scp, sftp, or any secure method)
|
||||
scp user@source-server:/var/lib/tor/keys/MyRelays.secret_family_key ~/tor-keys/
|
||||
|
||||
# 2. Copy the key into each running container (no restart needed yet)
|
||||
docker cp ~/tor-keys/MyRelays.secret_family_key tor-relay:/var/lib/tor/keys/
|
||||
|
||||
# 3. Fix ownership and permissions inside the container
|
||||
# The tor user in the container runs as UID 100, GID 101
|
||||
docker exec -u 0 tor-relay chown 100:101 /var/lib/tor/keys/MyRelays.secret_family_key
|
||||
docker exec -u 0 tor-relay chmod 600 /var/lib/tor/keys/MyRelays.secret_family_key
|
||||
|
||||
# 4. Verify the key is in place
|
||||
docker exec tor-relay ls -la /var/lib/tor/keys/MyRelays.secret_family_key
|
||||
|
||||
# 5. Add the FamilyId line to your torrc (same value from your source server)
|
||||
# FamilyId <your-family-id-value>
|
||||
# Keep your existing MyFamily lines during the transition period
|
||||
|
||||
# 6. Restart the container to pick up the config change
|
||||
docker restart tor-relay
|
||||
```
|
||||
|
||||
Repeat steps 2-6 for each container that should be in the family.
|
||||
|
||||
> **This is safe for running containers.** `docker cp` writes directly into the named Docker volume. Your relay identity keys, family key, and all data persist in the volume across container restarts, image updates, and `docker compose up --force-recreate`. Volumes are **only** deleted if you explicitly run `docker volume rm` or `docker compose down -v`.
|
||||
|
||||
#### Torrc configuration
|
||||
|
||||
During the transition period, configure **both** `FamilyId` and `MyFamily` in your torrc:
|
||||
|
||||
```ini
|
||||
# Happy Family (Tor 0.4.9+)
|
||||
FamilyId wweKJrJxUDs1EdtFFHCDtvVgTKftOC/crUl1mYJv830
|
||||
|
||||
# MyFamily (legacy - keep during transition)
|
||||
MyFamily 9A2B5C7D8E1F3A4B6C8D0E2F4A6B8C0D2E4F6A8B
|
||||
MyFamily 1F3E5D7C9B0A2F4E6D8C0B2A4F6E8D0C2B4A6F8E
|
||||
```
|
||||
|
||||
The Tor Project will announce when `MyFamily` can be removed.
|
||||
|
||||
#### ENV-based config (alternative to mounted torrc)
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
TOR_FAMILY_ID: "wweKJrJxUDs1EdtFFHCDtvVgTKftOC/crUl1mYJv830"
|
||||
TOR_MY_FAMILY: "FINGERPRINT1,FINGERPRINT2,FINGERPRINT3"
|
||||
```
|
||||
|
||||
#### Key persistence
|
||||
|
||||
The `.secret_family_key` file lives in `/var/lib/tor/keys/` inside your data volume. It persists across container restarts and image updates automatically.
|
||||
|
||||
| Scenario | Identity preserved? | Family key preserved? |
|
||||
|----------|:---:|:---:|
|
||||
| `docker restart` | ✅ | ✅ |
|
||||
| `docker compose up --force-recreate` | ✅ | ✅ |
|
||||
| `docker compose down` then `up` | ✅ | ✅ |
|
||||
| `docker compose down -v` | ❌ | ❌ |
|
||||
| `docker volume rm <volume>` | ❌ | ❌ |
|
||||
|
||||
> ⚠️ **Treat the `.secret_family_key` like a private key.** Anyone with this file can claim their relay belongs to your family. Back it up securely - losing it means regenerating for all relays.
|
||||
|
||||
> 📖 **Official docs:** [Tor Happy Family Guide](https://community.torproject.org/relay/setup/post-install/family-ids/)
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Monitoring Your Relay
|
||||
@@ -475,6 +582,8 @@ Search by:
|
||||
| First Statistics | 24-48 hours | Bandwidth graphs appear |
|
||||
| Guard Flag | 8+ days | Trusted for entry connections |
|
||||
|
||||
> 🗳️ **How relay flags work:** Tor has **9 Directory Authorities** that vote every hour on relay flags (Guard, Stable, Fast, HSDir, etc.). A relay only receives a flag when **at least 5 of 9** authorities agree in the consensus. This is why flags take time - your relay must prove itself to a majority of independent authorities.
|
||||
|
||||
> 📖 **Detailed monitoring:** See [Monitoring Guide](docs/MONITORING.md) for complete observability setup with Prometheus and Grafana.
|
||||
|
||||
---
|
||||
@@ -498,6 +607,10 @@ docker exec tor-relay bridge-line
|
||||
|
||||
# Generate Control Port hash
|
||||
docker exec tor-relay gen-auth
|
||||
|
||||
# Generate/view Happy Family key
|
||||
docker exec tor-relay gen-family MyRelays
|
||||
docker exec tor-relay gen-family --show
|
||||
```
|
||||
|
||||
### Common Issues
|
||||
@@ -520,7 +633,7 @@ If you use **host bind mounts** (e.g. `-v /my/path:/var/lib/tor`) instead of nam
|
||||
[warn] Failed to parse/validate config: Couldn't access private data directory "/var/lib/tor//keys"
|
||||
```
|
||||
|
||||
**Fix — set correct ownership on the host:**
|
||||
**Fix - set correct ownership on the host:**
|
||||
```bash
|
||||
chown -R 100:101 /path/to/your/tor-data
|
||||
chown -R 100:101 /path/to/your/tor-keys # if mounted separately
|
||||
@@ -537,7 +650,7 @@ chown -R 100:101 /path/to/your/tor-keys # if mounted separately
|
||||
> 📐 **NEW:** See the complete [Architecture Documentation](docs/ARCHITECTURE.md) for detailed technical design with Mermaid diagrams covering:
|
||||
> - Container lifecycle and initialization flow (6 phases)
|
||||
> - ENV compatibility layer and configuration priority
|
||||
> - Config generation for guard/exit/bridge modes
|
||||
> - Config generation for guard/exit/bridge modes with Happy Family support
|
||||
> - OBFS4V security validation
|
||||
> - Diagnostic tools architecture
|
||||
> - Signal handling and graceful shutdown
|
||||
@@ -627,6 +740,10 @@ flowchart TB
|
||||
━━━━━━━━━━
|
||||
Generate Control
|
||||
Port Auth Data"]
|
||||
Tools --> GenFamily["👨👩👧 gen-family
|
||||
━━━━━━━━━━
|
||||
Happy Family Key
|
||||
Generation & Import"]
|
||||
end
|
||||
|
||||
Running -->|docker stop SIGTERM| Shutdown
|
||||
@@ -659,6 +776,7 @@ flowchart TB
|
||||
style Finger fill:#4DD0E1,stroke:#0097A7,stroke-width:2px,color:#000
|
||||
style BLine fill:#4DD0E1,stroke:#0097A7,stroke-width:2px,color:#000
|
||||
style GenAuth fill:#4DD0E1,stroke:#0097A7,stroke-width:2px,color:#000
|
||||
style GenFamily fill:#4DD0E1,stroke:#0097A7,stroke-width:2px,color:#000
|
||||
|
||||
style Graceful fill:#FFB74D,stroke:#F57C00,stroke-width:2px,color:#000
|
||||
style End fill:#E57373,stroke:#C62828,stroke-width:2px,color:#fff
|
||||
@@ -766,7 +884,7 @@ See [`examples/`](examples/) directory for relay configurations.
|
||||
|
||||
✅ Store `relay.conf` with restricted permissions (`chmod 600`)
|
||||
✅ Never commit configs with sensitive info to Git
|
||||
✅ Use PGP key in ContactInfo for verification
|
||||
✅ Use [CIISS v2](https://nusenu.github.io/ContactInfo-Information-Sharing-Specification/) format in ContactInfo for verification
|
||||
✅ Regularly update Docker image for security patches
|
||||
✅ Monitor logs for suspicious activity
|
||||
✅ Configure firewall properly
|
||||
@@ -782,14 +900,14 @@ Images are automatically rebuilt on separate schedules to include security patch
|
||||
**Stable Variant** (`:latest`)
|
||||
- **Schedule:** Every Sunday at 18:30 UTC
|
||||
- **Includes:** Latest Tor + Alpine 3.23.3 updates
|
||||
- **Strategy:** Overwrites last release version (e.g., `:1.1.6`) with updated packages
|
||||
- **Tags Updated:** `:latest` and version tags (e.g., `:1.1.6`)
|
||||
- **Strategy:** Overwrites last release version (e.g., `:1.1.7`) with updated packages
|
||||
- **Tags Updated:** `:latest` and version tags (e.g., `:1.1.7`)
|
||||
|
||||
**Edge Variant** (`:edge`)
|
||||
- **Schedule:** Every 3 days at 12:00 UTC (independent schedule)
|
||||
- **Includes:** Latest Tor + Alpine edge (bleeding-edge) updates
|
||||
- **Strategy:** Overwrites last release version (e.g., `:1.1.6-edge`) with updated packages
|
||||
- **Tags Updated:** `:edge` and version tags (e.g., `:1.1.6-edge`)
|
||||
- **Strategy:** Overwrites last release version (e.g., `:1.1.7-edge`) with updated packages
|
||||
- **Tags Updated:** `:edge` and version tags (e.g., `:1.1.7-edge`)
|
||||
- **Frequency:** ~2-3x more frequent updates than stable
|
||||
|
||||
All images auto-published to Docker Hub and GitHub Container Registry
|
||||
@@ -824,7 +942,7 @@ All images auto-published to Docker Hub and GitHub Container Registry
|
||||

|
||||

|
||||
|
||||
**Current Version:** v1.1.6 • **Status:** Production Ready
|
||||
**Current Version:** v1.1.7 • **Status:** Production Ready
|
||||
**Image Size:** 16.8 MB • **Retention:** Last 7 Releases
|
||||
**Registries:** Docker Hub • GHCR
|
||||
|
||||
@@ -904,4 +1022,4 @@ Or via **[AnonPay](https://trocador.app/anonpay?ticker_to=xmr&network_to=Mainnet
|
||||
📚 [Documentation](docs/README.md)
|
||||
⬆ [Back to top](#readme-top)
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
19
SECURITY.md
19
SECURITY.md
@@ -14,9 +14,9 @@ We actively support the following versions with security updates:
|
||||
|
||||
| Version | Status | Support Level |
|
||||
| --------- | --------------------- | ------------------------------------------- |
|
||||
| **1.1.6** | 🟢 🛡️ **Active** | Full support (current stable) |
|
||||
| **1.1.5** | 🟡 🔧 **Maintenance** | Security + critical fixes only |
|
||||
| **< 1.1.5** | 🔴 ❌ **Deprecated** | Removed — contains CVE-2025-15467 (OpenSSL CVSS 9.8). Upgrade immediately. |
|
||||
| **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. |
|
||||
|
||||
---
|
||||
|
||||
@@ -74,6 +74,7 @@ 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
|
||||
@@ -324,13 +325,15 @@ chown root:root /path/to/relay.conf
|
||||
#### Contact Information
|
||||
|
||||
```conf
|
||||
# Use a dedicated email for relay operations
|
||||
ContactInfo tor-relay@example.com <0xPGP_FINGERPRINT>
|
||||
# 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
|
||||
|
||||
# Optionally include abuse contact
|
||||
ContactInfo your-email proof:uri-rsa abuse:abuse@example.com
|
||||
# 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
|
||||
@@ -658,4 +661,4 @@ Security researchers who responsibly disclose vulnerabilities will be listed her
|
||||
|
||||
---
|
||||
|
||||
*Last Updated: 2026-02-08 | Version: 1.1.6*
|
||||
*Last Updated: 2026-03-02 | Version: 1.1.7*
|
||||
|
||||
@@ -50,7 +50,7 @@ cleanup_and_exit() {
|
||||
|
||||
startup_banner() {
|
||||
log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
log "🧅 Tor Guard Relay v1.1.6 - Initialization"
|
||||
log "🧅 Tor Guard Relay v1.1.7 - Initialization"
|
||||
log "https://github.com/r3bo0tbx1/tor-guard-relay"
|
||||
log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
log ""
|
||||
@@ -90,10 +90,24 @@ phase_2_permissions() {
|
||||
if [ -d "$TOR_DATA_DIR/keys" ] && [ ! -w "$TOR_DATA_DIR/keys" ]; then
|
||||
warn "Keys directory $TOR_DATA_DIR/keys has wrong ownership!"
|
||||
KEYS_OWNER=$(stat -c '%u:%g' "$TOR_DATA_DIR/keys" 2>/dev/null || echo "unknown")
|
||||
warn " Current owner: $KEYS_OWNER — Expected: $CURRENT_UID:$CURRENT_GID"
|
||||
warn " Current owner: $KEYS_OWNER - Expected: $CURRENT_UID:$CURRENT_GID"
|
||||
warn " Fix on the host: chown -R $CURRENT_UID:$CURRENT_GID <host-keys-path>"
|
||||
fi
|
||||
|
||||
# Check for Happy Family key files
|
||||
FAMILY_KEY_COUNT=0
|
||||
if [ -d "$TOR_DATA_DIR/keys" ]; then
|
||||
for fk in "$TOR_DATA_DIR/keys"/*.secret_family_key; do
|
||||
[ -f "$fk" ] || continue
|
||||
FAMILY_KEY_COUNT=$((FAMILY_KEY_COUNT + 1))
|
||||
FK_NAME=$(basename "$fk" .secret_family_key)
|
||||
info "Found Happy Family key: $FK_NAME"
|
||||
done
|
||||
fi
|
||||
if [ "$FAMILY_KEY_COUNT" -gt 0 ]; then
|
||||
success "$FAMILY_KEY_COUNT family key(s) detected in keys directory"
|
||||
fi
|
||||
|
||||
success "Permissions configured securely"
|
||||
log ""
|
||||
}
|
||||
@@ -218,6 +232,19 @@ BridgeRelay 0
|
||||
EOF
|
||||
[ -n "${TOR_BANDWIDTH_RATE:-}" ] && echo "RelayBandwidthRate ${TOR_BANDWIDTH_RATE}" >> "$TOR_CONFIG"
|
||||
[ -n "${TOR_BANDWIDTH_BURST:-}" ] && echo "RelayBandwidthBurst ${TOR_BANDWIDTH_BURST}" >> "$TOR_CONFIG"
|
||||
|
||||
# Happy Family (Tor 0.4.9+)
|
||||
[ -n "${TOR_FAMILY_ID:-}" ] && echo "" >> "$TOR_CONFIG" && echo "# Happy Family (Tor 0.4.9+)" >> "$TOR_CONFIG" && echo "FamilyId ${TOR_FAMILY_ID}" >> "$TOR_CONFIG"
|
||||
|
||||
# MyFamily (legacy, keep during transition)
|
||||
if [ -n "${TOR_MY_FAMILY:-}" ]; then
|
||||
echo "" >> "$TOR_CONFIG"
|
||||
echo "# MyFamily (legacy - keep during transition to Happy Family)" >> "$TOR_CONFIG"
|
||||
echo "$TOR_MY_FAMILY" | tr ',' '\n' | while IFS= read -r fp; do
|
||||
fp=$(printf "%s" "$fp" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||
[ -n "$fp" ] && echo "MyFamily $fp" >> "$TOR_CONFIG"
|
||||
done
|
||||
fi
|
||||
;;
|
||||
|
||||
exit)
|
||||
@@ -234,6 +261,19 @@ ${TOR_EXIT_POLICY:-ExitPolicy reject *:*}
|
||||
EOF
|
||||
[ -n "${TOR_BANDWIDTH_RATE:-}" ] && echo "RelayBandwidthRate ${TOR_BANDWIDTH_RATE}" >> "$TOR_CONFIG"
|
||||
[ -n "${TOR_BANDWIDTH_BURST:-}" ] && echo "RelayBandwidthBurst ${TOR_BANDWIDTH_BURST}" >> "$TOR_CONFIG"
|
||||
|
||||
# Happy Family (Tor 0.4.9+)
|
||||
[ -n "${TOR_FAMILY_ID:-}" ] && echo "" >> "$TOR_CONFIG" && echo "# Happy Family (Tor 0.4.9+)" >> "$TOR_CONFIG" && echo "FamilyId ${TOR_FAMILY_ID}" >> "$TOR_CONFIG"
|
||||
|
||||
# MyFamily (legacy, keep during transition)
|
||||
if [ -n "${TOR_MY_FAMILY:-}" ]; then
|
||||
echo "" >> "$TOR_CONFIG"
|
||||
echo "# MyFamily (legacy - keep during transition to Happy Family)" >> "$TOR_CONFIG"
|
||||
echo "$TOR_MY_FAMILY" | tr ',' '\n' | while IFS= read -r fp; do
|
||||
fp=$(printf "%s" "$fp" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||
[ -n "$fp" ] && echo "MyFamily $fp" >> "$TOR_CONFIG"
|
||||
done
|
||||
fi
|
||||
;;
|
||||
|
||||
bridge)
|
||||
|
||||
@@ -58,12 +58,14 @@ flowchart TD
|
||||
DiagTools -->|fingerprint| FingerprintTool[🆔 tools/fingerprint]
|
||||
DiagTools -->|bridge-line| BridgeTool[🌉 tools/bridge-line]
|
||||
DiagTools -->|gen-auth| GenAuthTool[🔑 tools/gen-auth]
|
||||
DiagTools -->|gen-family| GenFamilyTool[👨👩👧 tools/gen-family]
|
||||
|
||||
StatusTool --> Running
|
||||
HealthTool --> Running
|
||||
FingerprintTool --> Running
|
||||
BridgeTool --> Running
|
||||
GenAuthTool --> Running
|
||||
GenFamilyTool --> Running
|
||||
|
||||
Trap --> StopTail[🧽 Kill tail -F PID]
|
||||
StopTail --> StopTor[📨 Send SIGTERM to Tor]
|
||||
@@ -94,6 +96,7 @@ flowchart TD
|
||||
|
||||
subgraph P2["🔐 Phase 2: Permission Hardening"]
|
||||
P2_1[🔒 chmod 700 data dir] --> P2_2[📁 chmod 755 log dir]
|
||||
P2_2 --> P2_3[👨👩👧 Detect family keys]
|
||||
end
|
||||
|
||||
subgraph P3["⚙️ Phase 3: Configuration Setup"]
|
||||
@@ -136,7 +139,7 @@ flowchart TD
|
||||
| Phase | Purpose | Key Operations | Error Handling |
|
||||
|-------|---------|----------------|----------------|
|
||||
| **1** | Directory Setup | `mkdir -p` data/log/run, show disk space | Fail if mkdir fails |
|
||||
| **2** | Permissions | `chmod 700` data, `chmod 755` log | Warn on failure (read-only mount) |
|
||||
| **2** | Permissions | `chmod 700` data, `chmod 755` log, detect family keys | Warn on failure (read-only mount) |
|
||||
| **3** | Configuration | Priority: mounted > ENV > error | Die if no config source |
|
||||
| **4** | Validation | `tor --verify-config` syntax check | Die if invalid config |
|
||||
| **5** | Build Info | Show version/arch/mode/source | Warn if missing |
|
||||
@@ -351,8 +354,14 @@ flowchart TD
|
||||
G4 -->|Not set| G6
|
||||
G5 --> G6{TOR_BANDWIDTH_BURST?}
|
||||
G6 -->|Set| G7[Add RelayBandwidthBurst]
|
||||
G6 -->|Not set| GuardDone
|
||||
G7 --> GuardDone([Guard Config Done])
|
||||
G6 -->|Not set| G8
|
||||
G7 --> G8{TOR_FAMILY_ID?}
|
||||
G8 -->|Set| G9[Add FamilyId]
|
||||
G8 -->|Not set| G10
|
||||
G9 --> G10{TOR_MY_FAMILY?}
|
||||
G10 -->|Set| G11[Add MyFamily entries]
|
||||
G10 -->|Not set| GuardDone
|
||||
G11 --> GuardDone([🛡️ Guard Config Done])
|
||||
end
|
||||
|
||||
subgraph ExitConfig["🚪 Exit Config (lines 260-273)"]
|
||||
@@ -364,8 +373,14 @@ flowchart TD
|
||||
E5 -->|Not set| E7
|
||||
E6 --> E7{TOR_BANDWIDTH_BURST?}
|
||||
E7 -->|Set| E8[Add RelayBandwidthBurst]
|
||||
E7 -->|Not set| ExitDone
|
||||
E8 --> ExitDone([Exit Config Done])
|
||||
E7 -->|Not set| E9
|
||||
E8 --> E9{TOR_FAMILY_ID?}
|
||||
E9 -->|Set| E10[Add FamilyId]
|
||||
E9 -->|Not set| E11
|
||||
E10 --> E11{TOR_MY_FAMILY?}
|
||||
E11 -->|Set| E12[Add MyFamily entries]
|
||||
E11 -->|Not set| ExitDone
|
||||
E12 --> ExitDone([🚪 Exit Config Done])
|
||||
end
|
||||
|
||||
subgraph BridgeConfig["🌉 Bridge Config (lines 276-343)"]
|
||||
@@ -402,6 +417,7 @@ flowchart TD
|
||||
```
|
||||
|
||||
**Base Config Includes:** Nickname, ContactInfo, ORPort, SocksPort 0, DataDirectory, Logging
|
||||
**Family Config (guard/exit):** Optional FamilyId (Tor 0.4.9+) and MyFamily (legacy, comma-separated fingerprints via TOR_MY_FAMILY)
|
||||
|
||||
**Code Reference:** `docker-entrypoint.sh` lines 222-350 (generate_config_from_env)
|
||||
|
||||
@@ -456,7 +472,7 @@ flowchart TD
|
||||
style Enable fill:#e3f2fd
|
||||
```
|
||||
|
||||
**Security Features (fixed in v1.1.1, improved through v1.1.6):**
|
||||
**Security Features (fixed in v1.1.1, improved through v1.1.7):**
|
||||
- **Newline detection:** `wc -l` instead of busybox-incompatible `grep -qE '[\x00\n\r]'`
|
||||
- **Control char detection:** `tr -d '[ -~]'` removes printable chars, leaves control chars
|
||||
- **Whitelist enforcement:** Only known-safe torrc options allowed
|
||||
@@ -468,7 +484,7 @@ flowchart TD
|
||||
|
||||
## Diagnostic Tools
|
||||
|
||||
Five busybox-only diagnostic tools provide observability:
|
||||
Six busybox-only diagnostic tools provide observability:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -478,6 +494,7 @@ flowchart TD
|
||||
Choice -->|health| HealthFlow
|
||||
Choice -->|fingerprint| FingerprintFlow
|
||||
Choice -->|bridge-line| BridgeFlow
|
||||
Choice -->|gen-family| FamilyFlow
|
||||
|
||||
subgraph StatusFlow["📊 tools/status - Full Health Report"]
|
||||
S1[🔍 Check Tor process running] --> S2[📈 Read bootstrap %]
|
||||
@@ -518,10 +535,25 @@ flowchart TD
|
||||
FingerprintFlow --> Output3([🟢 Fingerprint + URL])
|
||||
BridgeFlow --> Output4([🟢 Bridge line or error])
|
||||
|
||||
subgraph FamilyFlow["👨👩👧 tools/gen-family - Happy Family Management"]
|
||||
FM1{Which action?}
|
||||
FM1 -->|gen-family Name| FM2[🔑 Check Tor version]
|
||||
FM2 --> FM3{Key already exists?}
|
||||
FM3 -->|Yes| FM4[⚠️ Warn: key exists]
|
||||
FM3 -->|No| FM5[🔐 tor --keygen-family Name]
|
||||
FM5 --> FM6[📤 Output FamilyId + instructions]
|
||||
FM1 -->|gen-family --show| FM7[🔍 Scan keys dir for .secret_family_key]
|
||||
FM7 --> FM8[📝 Show FamilyId from torrc]
|
||||
FM8 --> FM9[ℹ️ Show MyFamily status]
|
||||
end
|
||||
|
||||
FamilyFlow --> Output5([🟢 Key + FamilyId or status])
|
||||
|
||||
style Output1 fill:#b2fab4
|
||||
style Output2 fill:#b2fab4
|
||||
style Output3 fill:#b2fab4
|
||||
style Output4 fill:#b2fab4
|
||||
style Output5 fill:#b2fab4
|
||||
```
|
||||
|
||||
**JSON Output Fields:** status, pid, uptime, bootstrap, reachable, errors, fingerprint, nickname
|
||||
@@ -535,6 +567,7 @@ flowchart TD
|
||||
| **fingerprint** | Relay identity | Text + URL | busybox: cat, awk |
|
||||
| **bridge-line** | Bridge sharing | obfs4 bridge line | busybox: grep, sed, awk, wget |
|
||||
| **gen-auth** | Credential generation | Text (Pass + Hash) | busybox: head, tr, tor |
|
||||
| **gen-family** | Happy Family key mgmt | Text (Key + FamilyId) | busybox: tor --keygen-family, grep, basename |
|
||||
|
||||
**All tools:**
|
||||
- Use `#!/bin/sh` (POSIX sh, not bash)
|
||||
@@ -576,11 +609,13 @@ graph TD
|
||||
Lib["📁 /var/lib"]
|
||||
TorData["📦 /var/lib/tor VOLUME"]
|
||||
Keys["🔑 keys/"]
|
||||
FamilyKey["👨👩👧 *.secret_family_key"]
|
||||
FingerprintFile["🆔 fingerprint"]
|
||||
PTState["🌀 pt_state/"]
|
||||
|
||||
Lib --> TorData
|
||||
TorData --> Keys
|
||||
Keys --> FamilyKey
|
||||
TorData --> FingerprintFile
|
||||
TorData --> PTState
|
||||
end
|
||||
@@ -620,6 +655,7 @@ graph TD
|
||||
Fingerprint["🧬 fingerprint"]
|
||||
BridgeLine["🌉 bridge-line"]
|
||||
GenAuth["🔑 gen-auth"]
|
||||
GenFamily["👨👩👧 gen-family"]
|
||||
|
||||
UsrLocal --> Bin
|
||||
Bin --> Entrypoint
|
||||
@@ -628,6 +664,8 @@ graph TD
|
||||
Bin --> Health
|
||||
Bin --> Fingerprint
|
||||
Bin --> BridgeLine
|
||||
Bin --> GenAuth
|
||||
Bin --> GenFamily
|
||||
end
|
||||
Usr --> UsrLocal
|
||||
|
||||
@@ -661,7 +699,7 @@ graph TD
|
||||
|
||||
class TorData,TorLog volumeStyle
|
||||
class TorRC configStyle
|
||||
class Entrypoint,Healthcheck,Status,Health,Fingerprint,BridgeLine scriptStyle
|
||||
class Entrypoint,Healthcheck,Status,Health,Fingerprint,BridgeLine,GenAuth,GenFamily scriptStyle
|
||||
class TorBin,Lyrebird,Tini binaryStyle
|
||||
class TorPID runtimeStyle
|
||||
class TorRCSample deletedStyle
|
||||
@@ -831,7 +869,7 @@ flowchart LR
|
||||
```
|
||||
|
||||
**Weekly Rebuild Strategy:**
|
||||
- Rebuilds use the **same version tag** as the last release (e.g., `1.1.6`)
|
||||
- Rebuilds use the **same version tag** as the last release (e.g., `1.1.7`)
|
||||
- Overwrites existing image with fresh Alpine packages (security updates)
|
||||
- No `-weekly` suffix needed - just updated packages
|
||||
- `:latest` always points to most recent release version
|
||||
@@ -902,6 +940,7 @@ flowchart TD
|
||||
| `tools/fingerprint` | Show relay identity | ~50 |
|
||||
| `tools/bridge-line` | Generate bridge line | ~80 |
|
||||
| `tools/gen-auth` | Generate Control Port auth | ~30 |
|
||||
| `tools/gen-family` | Happy Family key management | ~180 |
|
||||
|
||||
### External Documentation
|
||||
|
||||
@@ -913,6 +952,6 @@ flowchart TD
|
||||
---
|
||||
<div align="center">
|
||||
|
||||
**Document Version:** 1.0.5 • **Last Updated:** 2026-02-08 • **Container Version:** v1.1.6
|
||||
**Document Version:** 1.1.0 • **Last Updated:** 2026-03-02 • **Container Version:** v1.1.7
|
||||
|
||||
</div>
|
||||
@@ -54,7 +54,7 @@ nano relay-guard.conf
|
||||
|
||||
**Minimum required edits:**
|
||||
- `Nickname` - Your relay name
|
||||
- `ContactInfo` - Your email
|
||||
- `ContactInfo` - Your contact info ([CIISS v2](https://nusenu.github.io/ContactInfo-Information-Sharing-Specification/) format recommended)
|
||||
- `ORPort` - Usually 9001 or 443
|
||||
- `RelayBandwidthRate` - Your bandwidth limit
|
||||
|
||||
@@ -91,7 +91,7 @@ docker ps | grep tor-relay
|
||||
# Check logs and bootstrap progress
|
||||
docker logs -f tor-relay
|
||||
|
||||
# Run diagnostics (5 tools available)
|
||||
# Run diagnostics (6 tools available)
|
||||
docker exec tor-relay status # Full health report with emojis
|
||||
docker exec tor-relay health # JSON health data
|
||||
docker exec tor-relay fingerprint # Show fingerprint + Tor Metrics URL
|
||||
@@ -128,7 +128,7 @@ nano relay.conf
|
||||
|
||||
Edit at minimum:
|
||||
- `Nickname`
|
||||
- `ContactInfo`
|
||||
- `ContactInfo` ([CIISS v2](https://nusenu.github.io/ContactInfo-Information-Sharing-Specification/) format recommended)
|
||||
- `RelayBandwidthRate`
|
||||
|
||||
### Step 4: Deploy
|
||||
@@ -194,7 +194,7 @@ Paste your relay configuration (see [example config](../examples/relay-guard.con
|
||||
|
||||
**Important**: Edit at minimum:
|
||||
- `Nickname` - Your relay name
|
||||
- `ContactInfo` - Your email
|
||||
- `ContactInfo` - Your contact info ([CIISS v2](https://nusenu.github.io/ContactInfo-Information-Sharing-Specification/) format recommended)
|
||||
- `RelayBandwidthRate` - Your bandwidth limit
|
||||
|
||||
Save and set permissions:
|
||||
@@ -347,7 +347,7 @@ docker run -d \
|
||||
--network host \
|
||||
-e TOR_RELAY_MODE=guard \
|
||||
-e TOR_NICKNAME=MyGuardRelay \
|
||||
-e TOR_CONTACT_INFO=tor@example.com \
|
||||
-e TOR_CONTACT_INFO="email:tor[]example.com ciissversion:2" \
|
||||
-e TOR_ORPORT=9001 \
|
||||
-v tor-data:/var/lib/tor \
|
||||
r3bo0tbx1/onion-relay:latest
|
||||
@@ -370,7 +370,7 @@ docker run -d \
|
||||
--network host \
|
||||
-e TOR_RELAY_MODE=exit \
|
||||
-e TOR_NICKNAME=MyExitRelay \
|
||||
-e TOR_CONTACT_INFO=tor@example.com \
|
||||
-e TOR_CONTACT_INFO="email:tor[]example.com ciissversion:2" \
|
||||
-e TOR_ORPORT=9001 \
|
||||
-e TOR_EXIT_POLICY="accept *:80,accept *:443,reject *:*" \
|
||||
-v tor-data:/var/lib/tor \
|
||||
@@ -394,7 +394,7 @@ docker run -d \
|
||||
--network host \
|
||||
-e TOR_RELAY_MODE=bridge \
|
||||
-e TOR_NICKNAME=MyBridge \
|
||||
-e TOR_CONTACT_INFO=tor@example.com \
|
||||
-e TOR_CONTACT_INFO="email:tor[]example.com ciissversion:2" \
|
||||
-e TOR_ORPORT=9001 \
|
||||
-e TOR_OBFS4_PORT=9002 \
|
||||
-v tor-data:/var/lib/tor \
|
||||
@@ -420,7 +420,7 @@ Full configuration via environment variables is supported (no config file needed
|
||||
#### Core Configuration
|
||||
- `TOR_RELAY_MODE` - guard, exit, or bridge (default: guard)
|
||||
- `TOR_NICKNAME` - Relay nickname (required for ENV config)
|
||||
- `TOR_CONTACT_INFO` - Contact email (required for ENV config)
|
||||
- `TOR_CONTACT_INFO` - Contact info ([CIISS v2](https://nusenu.github.io/ContactInfo-Information-Sharing-Specification/) format recommended, required for ENV config)
|
||||
- `TOR_ORPORT` - ORPort (default: 9001)
|
||||
- `TOR_DIRPORT` - DirPort for guard/exit (default: 0 - disabled)
|
||||
- `TOR_OBFS4_PORT` - obfs4 port for bridge mode (default: 9002)
|
||||
@@ -453,7 +453,7 @@ services:
|
||||
environment:
|
||||
TOR_RELAY_MODE: guard
|
||||
TOR_NICKNAME: MyRelay
|
||||
TOR_CONTACT_INFO: tor@example.com
|
||||
TOR_CONTACT_INFO: "email:tor[]example.com ciissversion:2"
|
||||
TOR_ORPORT: 9001
|
||||
TOR_BANDWIDTH_RATE: 50 MBytes
|
||||
TOR_BANDWIDTH_BURST: 100 MBytes
|
||||
@@ -510,7 +510,7 @@ abc123def456 r3bo0tbx1/onion-relay:latest Up 5 minutes (healthy)
|
||||
|
||||
### 2. Run Diagnostics
|
||||
|
||||
The image provides **5 diagnostic tools**:
|
||||
The image provides **6 diagnostic tools**:
|
||||
|
||||
```bash
|
||||
# Full health report with emojis
|
||||
@@ -562,6 +562,8 @@ docker exec tor-relay health
|
||||
- **24-48 hours**: Full statistics available
|
||||
- **8+ days**: Eligible for Guard flag (guard relays only)
|
||||
|
||||
> 🗳️ **How flags are assigned:** Tor's **9 Directory Authorities** vote every hour on relay flags (Guard, Stable, Fast, HSDir, etc.). Your relay only receives a flag when **at least 5 of 9** authorities reach consensus. New relays start as unmeasured middle relays and earn flags over time as authorities observe stable uptime and sufficient bandwidth.
|
||||
|
||||
Search for your relay:
|
||||
- **Clearnet**: https://metrics.torproject.org/rs.html
|
||||
- **Tor Browser**: http://hctxrvjzfpvmzh2jllqhgvvkoepxb4kfzdjm6h7egcwlumggtktiftid.onion/rs.html
|
||||
@@ -964,7 +966,7 @@ After successful deployment:
|
||||
## Support
|
||||
|
||||
- 📖 [Main README](../README.md)
|
||||
- 🔧 [Tools Documentation](TOOLS.md) - Complete guide to the 5 diagnostic tools
|
||||
- 🔧 [Tools Documentation](TOOLS.md) - Complete guide to the 6 diagnostic tools
|
||||
- 📊 [Monitoring Guide](MONITORING.md) - External monitoring integration
|
||||
- 🐛 [Report Issues](https://github.com/r3bo0tbx1/tor-guard-relay/issues)
|
||||
- 💬 [Tor Project Forum](https://forum.torproject.net/)
|
||||
|
||||
45
docs/FAQ.md
45
docs/FAQ.md
@@ -32,7 +32,7 @@ Built on Alpine Linux 3.23.0 with a minimal 20MB image size, busybox-only tools,
|
||||
|---------|--------------|-----------------|
|
||||
| **Image size** | ~16.8 MB | ~100+ MB |
|
||||
| **Base** | Alpine 3.23.0 | Debian |
|
||||
| **Diagnostics** | 5 busybox tools + JSON API | None |
|
||||
| **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 |
|
||||
@@ -72,7 +72,7 @@ docker run -d \
|
||||
--network host \
|
||||
-e TOR_RELAY_MODE=guard \
|
||||
-e TOR_NICKNAME=MyGuardRelay \
|
||||
-e TOR_CONTACT_INFO="admin@example.com" \
|
||||
-e TOR_CONTACT_INFO="email:admin[]example.com ciissversion:2" \
|
||||
-e TOR_ORPORT=9001 \
|
||||
-e TOR_DIRPORT=9030 \
|
||||
-v tor-data:/var/lib/tor \
|
||||
@@ -89,6 +89,37 @@ docker run -d \
|
||||
ghcr.io/r3bo0tbx1/onion-relay:latest
|
||||
```
|
||||
|
||||
### What is the ContactInfo Information Sharing Specification (CIISS)?
|
||||
|
||||
The [CIISS v2](https://nusenu.github.io/ContactInfo-Information-Sharing-Specification/) 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](https://metrics.torproject.org/) 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](https://torcontactinfogenerator.netlify.app/) - 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](https://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:
|
||||
@@ -97,7 +128,7 @@ Both work identically - we support two naming conventions for compatibility:
|
||||
```bash
|
||||
TOR_RELAY_MODE=bridge
|
||||
TOR_NICKNAME=MyBridge
|
||||
TOR_CONTACT_INFO=admin@example.com
|
||||
TOR_CONTACT_INFO=email:admin[]example.com ciissversion:2
|
||||
TOR_ORPORT=9001
|
||||
TOR_OBFS4_PORT=9002
|
||||
```
|
||||
@@ -195,6 +226,8 @@ sudo ufw allow 9002/tcp
|
||||
| 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%"
|
||||
@@ -247,7 +280,7 @@ docker logs tor-bridge | grep "bridge line"
|
||||
**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
|
||||
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
|
||||
|
||||
@@ -426,7 +459,7 @@ docker run -d --name tor-relay ... # Same config
|
||||
**Verify upgrade:**
|
||||
```bash
|
||||
docker exec tor-relay cat /build-info.txt
|
||||
# Should show: Version: 1.1.6
|
||||
# Should show: Version: 1.1.7
|
||||
|
||||
docker exec tor-relay fingerprint
|
||||
# Verify fingerprint unchanged
|
||||
@@ -537,5 +570,5 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md) for guidelines.
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** Feburary 2026 (v1.1.6)
|
||||
**Last Updated:** March 2026 (v1.1.7)
|
||||
**Maintained by:** [@r3bo0tbx1](https://github.com/r3bo0tbx1)
|
||||
|
||||
@@ -436,7 +436,7 @@ docker rm obfs4-bridge
|
||||
- [ ] Fingerprint matches backup
|
||||
- [ ] Container starts without errors
|
||||
- [ ] Bootstrap reaches 100%
|
||||
- [ ] Diagnostic tools work (status, health, fingerprint)
|
||||
- [ ] Diagnostic tools work (status, health, fingerprint, gen-family)
|
||||
- [ ] Monitoring updated (if applicable)
|
||||
|
||||
---
|
||||
|
||||
@@ -178,6 +178,7 @@ After any migration:
|
||||
- `docker exec <container> status`
|
||||
- `docker exec <container> health`
|
||||
- `docker exec <container> fingerprint`
|
||||
- `docker exec <container> gen-family --show` (if using Happy Family)
|
||||
- [ ] Tor Metrics shows relay (after 1-2 hours)
|
||||
|
||||
---
|
||||
|
||||
@@ -49,7 +49,7 @@ The Tor Guard Relay container now supports **three relay modes**:
|
||||
**Best for:**
|
||||
- Operators who want to contribute without legal complexity
|
||||
- Stable, high-bandwidth connections
|
||||
- Long-term operation (8+ days to earn Guard flag)
|
||||
- Long-term operation (8+ days to earn Guard flag - requires at least 5 of 9 directory authorities to vote in consensus)
|
||||
|
||||
**Requirements:**
|
||||
- Public IP with ports 9001, 9030 accessible
|
||||
@@ -491,7 +491,7 @@ nc -zv <your-ip> 9001
|
||||
**Normal for:**
|
||||
- New relays (2-8 weeks to build reputation)
|
||||
- Bridges (intentionally low visibility)
|
||||
- Guards without Guard flag (need 8+ days uptime)
|
||||
- Guards without Guard flag (need 8+ days uptime - at least 5 of 9 directory authorities must agree in consensus)
|
||||
|
||||
**Check:**
|
||||
1. Verify relay is reachable: `docker exec <container> status`
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 🛠️ Tools Reference Guide
|
||||
|
||||
**Tor Guard Relay 1.1.3** includes 5 essential diagnostic tools built directly into the ultra-optimized ~20 MB container. All tools are busybox-compatible, executable without file extensions, and designed for production use.
|
||||
**Tor Guard Relay 1.1.3** includes 6 essential diagnostic tools built directly into the ultra-optimized ~20 MB container. All tools are busybox-compatible, executable without file extensions, and designed for production use.
|
||||
|
||||
---
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
| **fingerprint** | Display relay fingerprint | Text | With Tor Metrics link |
|
||||
| **bridge-line** | Get obfs4 bridge line | Text | Bridge mode only |
|
||||
| gen-auth | Generate Control Port auth | Text | Password + Hash |
|
||||
| gen-family | Generate/view Happy Family key | Text | Tor 0.4.9+ only |
|
||||
|
||||
---
|
||||
|
||||
@@ -224,6 +225,53 @@ When to use:
|
||||
|
||||
---
|
||||
|
||||
### `gen-family`
|
||||
|
||||
**Purpose:** Generate or view a Tor Happy Family key (Tor 0.4.9+). This replaces the old `MyFamily` fingerprint-exchange workflow with a single shared `FamilyId`.
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
# Generate a new family key
|
||||
docker exec tor-relay gen-family MyRelays
|
||||
|
||||
# View existing family key and FamilyId
|
||||
docker exec tor-relay gen-family --show
|
||||
|
||||
# Show help
|
||||
docker exec tor-relay gen-family --help
|
||||
```
|
||||
|
||||
**Output Example (generate):**
|
||||
```
|
||||
════════════════════════════════════════════════════════════
|
||||
Tor Happy Family Key Generator (Tor 0.4.9+)
|
||||
════════════════════════════════════════════════════════════
|
||||
|
||||
✓ Generated family key: MyRelays
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
Your FamilyId (add to torrc or TOR_FAMILY_ID env var):
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
FamilyId wweKJrJxUDs1EdtFFHCDtvVgTKftOC/crUl1mYJv830
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
💡 Copy the secret key file to all relays in this family.
|
||||
Then set TOR_FAMILY_ID in each relay's environment.
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
**Exit Codes:**
|
||||
- `0` - Key generated or displayed successfully
|
||||
- `1` - Error (key already exists, Tor not found, etc.)
|
||||
|
||||
**When to use:**
|
||||
- When linking multiple relays (guard, exit, middle) into a family
|
||||
- Run once to generate, then copy the key file to all family members
|
||||
- Replaces the old manual fingerprint exchange (`MyFamily`)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Common Workflows
|
||||
|
||||
### 1. Quick Health Check
|
||||
@@ -270,7 +318,21 @@ docker exec tor-bridge bridge-line
|
||||
# Share ONLY with trusted users, NOT publicly
|
||||
```
|
||||
|
||||
### 5. Automated Monitoring
|
||||
### 5. Set Up Happy Family (Tor 0.4.9+)
|
||||
```bash
|
||||
# Generate a family key on one relay
|
||||
docker exec tor-relay gen-family MyRelays
|
||||
|
||||
# Copy the key file to all other family members
|
||||
docker cp tor-relay:/var/lib/tor/keys/MyRelays.secret_family_key ./
|
||||
docker cp ./MyRelays.secret_family_key tor-relay-2:/var/lib/tor/keys/
|
||||
docker exec -u 0 tor-relay-2 chown 100:101 /var/lib/tor/keys/MyRelays.secret_family_key
|
||||
|
||||
# Set TOR_FAMILY_ID on each relay and restart
|
||||
# (use the FamilyId from gen-family --show output)
|
||||
```
|
||||
|
||||
### 6. Automated Monitoring
|
||||
```bash
|
||||
# Simple monitoring script
|
||||
while true; do
|
||||
@@ -288,7 +350,7 @@ while true; do
|
||||
done
|
||||
```
|
||||
|
||||
### 6. Check Logs
|
||||
### 7. Check Logs
|
||||
```bash
|
||||
# View recent logs
|
||||
docker logs --tail 100 tor-relay
|
||||
@@ -322,7 +384,7 @@ docker logs tor-relay 2>&1 | grep -i warn
|
||||
# Verify tools exist
|
||||
docker exec tor-relay ls -la /usr/local/bin/
|
||||
|
||||
# Should show: status, health, fingerprint, bridge-line, gen-auth
|
||||
# Should show: status, health, fingerprint, bridge-line, gen-auth, gen-family
|
||||
|
||||
# Check PATH
|
||||
docker exec tor-relay echo $PATH
|
||||
@@ -401,18 +463,22 @@ docker logs tor-relay | grep -i obfs4
|
||||
|
||||
## ❓ FAQ
|
||||
|
||||
**Q: Why only 5 tools instead of 9?**
|
||||
A: The v1.1.3 build remains ultra-light (~16.8 MB). These 5 tools cover all essential operations including health checks, identity, and authentication setup.
|
||||
**Q: Why only 6 tools instead of 9?**
|
||||
|
||||
A: The v1.1.3 build remains ultra-light (~16.8 MB). These 6 tools cover all essential operations including health checks, identity, authentication setup, and Happy Family key management.
|
||||
|
||||
**Q: Where are metrics/monitoring endpoints?**
|
||||
|
||||
A: Removed to achieve ultra-small image size. Use `health` tool with external monitoring systems or check `/var/log/tor/notices.log` directly.
|
||||
|
||||
**Q: Can I still use Prometheus?**
|
||||
|
||||
A: Yes! Use `gen-auth` to configure the Control Port, then run a separate `prometheus-tor-exporter` container alongside this one.
|
||||
|
||||
**Q: What happened to the dashboard?**
|
||||
|
||||
A: Removed (required Python/Flask). Use `status` tool for visual output or build your own dashboard using `health` JSON.
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** December 2025 | **Version:** 1.1.3
|
||||
**Last Updated:** March 2026 | **Version:** 1.1.7
|
||||
@@ -501,7 +501,7 @@ After migration:
|
||||
- ✨ Official Tor Project ENV variable compatibility
|
||||
- ✨ Bootstrap progress logs in terminal
|
||||
- ✨ Enhanced emoji logging (v1.1.0 style)
|
||||
- ✨ 5 diagnostic tools (status, health, fingerprint, bridge-line, gen-auth)
|
||||
- ✨ 6 diagnostic tools (status, health, fingerprint, bridge-line, gen-auth, gen-family)
|
||||
- ✨ Auto-detection of bridge mode from PT_PORT
|
||||
- ✨ OBFS4V_* variable processing
|
||||
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
Nickname ShinobiKage
|
||||
Nickname MyTorBridge
|
||||
ContactInfo email:your-email[]example.com pgp:YOUR_PGP_FINGERPRINT ciissversion:2
|
||||
|
||||
# Happy Family (Tor 0.4.9+) - replaces MyFamily
|
||||
# Generate with: docker exec tor-bridge gen-family MyRelays
|
||||
#FamilyId YOUR_FAMILY_ID_HERE
|
||||
|
||||
# MyFamily (legacy - keep BOTH during transition period)
|
||||
#MyFamily FINGERPRINT_OF_OTHER_RELAY_1
|
||||
#MyFamily FINGERPRINT_OF_OTHER_RELAY_2
|
||||
|
||||
Address YOUR.IPV4.IP.ADDRESS
|
||||
ORPort 24819 IPv4Only
|
||||
ORPort [YOUR:IPV6:IP:ADDRESS::]:24819
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
Nickname MyTorExitRelay
|
||||
ContactInfo email:your-email[]example.com pgp:YOUR_PGP_FINGERPRINT ciissversion:2
|
||||
|
||||
# Happy Family (Tor 0.4.9+) - replaces MyFamily
|
||||
# Generate with: docker exec tor-relay gen-family MyRelays
|
||||
#FamilyId YOUR_FAMILY_ID_HERE
|
||||
|
||||
# MyFamily (legacy - keep BOTH during transition period)
|
||||
# Once Tor Project announces MyFamily removal, you can drop these lines
|
||||
#MyFamily FINGERPRINT_OF_OTHER_RELAY_1
|
||||
#MyFamily FINGERPRINT_OF_OTHER_RELAY_2
|
||||
|
||||
Address YOUR.IPV4.IP.ADDRESS
|
||||
ORPort 9001 IPv4Only
|
||||
ORPort [YOUR:IPV6:IP:ADDRESS::]:9001
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
Nickname MyTorGuardRelay
|
||||
ContactInfo email:your-email[]example.com pgp:YOUR_PGP_FINGERPRINT ciissversion:2
|
||||
|
||||
# Happy Family (Tor 0.4.9+) - replaces MyFamily
|
||||
# Generate with: docker exec tor-relay gen-family MyRelays
|
||||
#FamilyId YOUR_FAMILY_ID_HERE
|
||||
|
||||
# MyFamily (legacy - keep BOTH during transition period)
|
||||
# Once Tor Project announces MyFamily removal, you can drop these lines
|
||||
#MyFamily FINGERPRINT_OF_OTHER_RELAY_1
|
||||
#MyFamily FINGERPRINT_OF_OTHER_RELAY_2
|
||||
|
||||
Address YOUR.IPV4.IP.ADDRESS
|
||||
ORPort 9001 IPv4Only
|
||||
ORPort [YOUR:IPV6:IP:ADDRESS::]:9001
|
||||
|
||||
@@ -620,7 +620,7 @@ main() {
|
||||
|
||||
log ""
|
||||
log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
log "🧅 Tor Relay Migration Validator v1.1.6"
|
||||
log "🧅 Tor Relay Migration Validator v1.1.7"
|
||||
log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
log ""
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ Auto-update version numbers across all documentation, templates, and configurati
|
||||
- Format: `## [v1.1.2] - 2025-01-14`
|
||||
|
||||
3. **templates/*.yml** (Docker Compose)
|
||||
- `image:` tags from `onion-relay:1.1.5` → `onion-relay:1.1.6`
|
||||
- `image:` tags from `onion-relay:1.1.6` → `onion-relay:1.1.7`
|
||||
|
||||
4. **templates/*.json** (Cosmos Cloud)
|
||||
- `"image":` fields in JSON templates
|
||||
@@ -515,13 +515,13 @@ sed -i 's/1.1.1/1.1.2/g' path/to/file
|
||||
**Solution:**
|
||||
```bash
|
||||
# Ensure image exists locally or in registry
|
||||
docker pull ghcr.io/r3bo0tbx1/onion-relay:1.1.6
|
||||
docker pull ghcr.io/r3bo0tbx1/onion-relay:1.1.7
|
||||
|
||||
# Generate SBOM locally for testing
|
||||
docker run --rm \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
anchore/syft:latest \
|
||||
ghcr.io/r3bo0tbx1/onion-relay:1.1.6 \
|
||||
ghcr.io/r3bo0tbx1/onion-relay:1.1.7 \
|
||||
-o cyclonedx-json
|
||||
```
|
||||
|
||||
|
||||
@@ -231,6 +231,13 @@ else
|
||||
warn "bridge-line tool not ready yet (needs full bootstrap - 10-30 minutes)"
|
||||
fi
|
||||
|
||||
# Test 4.5: gen-family tool (help flag)
|
||||
if docker exec test-tools gen-family --help >/dev/null 2>&1; then
|
||||
success "gen-family tool works"
|
||||
else
|
||||
warn "gen-family tool not available (requires Tor 0.4.9+)"
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
docker stop test-tools >/dev/null 2>&1
|
||||
docker rm test-tools >/dev/null 2>&1
|
||||
@@ -306,7 +313,7 @@ echo "✅ OBFS4V_* variables are processed correctly"
|
||||
echo "✅ Bridge mode auto-detected from PT_PORT"
|
||||
echo "✅ TOR_* ENV naming works (TOR_ORPORT, TOR_CONTACT_INFO, etc.)"
|
||||
echo "✅ Guard/Exit/Bridge modes configured correctly"
|
||||
echo "✅ Diagnostic tools work (status, health, fingerprint, bridge-line)"
|
||||
echo "✅ Diagnostic tools work (status, health, fingerprint, bridge-line, gen-family)"
|
||||
echo "✅ Mixed ENV naming works (can combine official + TOR_* prefix)"
|
||||
echo ""
|
||||
echo "🎯 Your image is fully compatible with thetorproject/obfs4-bridge!"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# relay-status.sh — Tor relay/bridge status checker with security validation
|
||||
# Version: 1.1.6
|
||||
# relay-status.sh - Tor relay/bridge status checker with security validation
|
||||
# Version: 1.1.7
|
||||
# Automatically detects Tor containers or uses specified container name
|
||||
#
|
||||
|
||||
@@ -11,7 +11,7 @@ set -euo pipefail
|
||||
CONTAINER="${1:-}" # Accept container name as first argument
|
||||
readonly FINGERPRINT_PATH="/var/lib/tor/fingerprint"
|
||||
readonly TORRC_PATH="/etc/tor/torrc"
|
||||
readonly VERSION="1.1.6"
|
||||
readonly VERSION="1.1.7"
|
||||
|
||||
# Colors for output
|
||||
readonly RED='\033[0;31m'
|
||||
@@ -359,7 +359,7 @@ EOF
|
||||
# Show version
|
||||
show_version() {
|
||||
echo "relay-status.sh version ${VERSION}"
|
||||
echo "Part of Tor Guard Relay v1.1.6"
|
||||
echo "Part of Tor Guard Relay v1.1.7"
|
||||
}
|
||||
|
||||
# Main execution
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔐 Security Validation Tests - Tor Guard Relay v1.1.6"
|
||||
echo "🔐 Security Validation Tests - Tor Guard Relay v1.1.7"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
@@ -126,7 +126,7 @@ echo "Test 3: Tool Scripts Security"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
# Check for 4 essential tools
|
||||
for tool in status health fingerprint bridge-line; do
|
||||
for tool in status health fingerprint bridge-line gen-family; do
|
||||
if [ -f "tools/$tool" ]; then
|
||||
if head -1 "tools/$tool" | grep -q "^#!/bin/sh"; then
|
||||
test_pass "tools/$tool uses busybox sh"
|
||||
@@ -303,7 +303,7 @@ echo ""
|
||||
echo "Test 8: Shell Script Syntax"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
for script in docker-entrypoint.sh tools/status tools/health tools/fingerprint tools/bridge-line; do
|
||||
for script in docker-entrypoint.sh tools/status tools/health tools/fingerprint tools/bridge-line tools/gen-family; do
|
||||
if [ -f "$script" ]; then
|
||||
if sh -n "$script" 2>/dev/null; then
|
||||
test_pass "$script has valid POSIX sh syntax"
|
||||
|
||||
@@ -49,7 +49,7 @@ docker run -d \
|
||||
--security-opt no-new-privileges:true \
|
||||
-e TOR_RELAY_MODE=bridge \
|
||||
-e TOR_NICKNAME=MyBridge \
|
||||
-e TOR_CONTACT_INFO=admin@example.com \
|
||||
-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 \
|
||||
@@ -61,7 +61,7 @@ docker run -d \
|
||||
# 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=admin@example.com # Contact email
|
||||
TOR_CONTACT_INFO="email:admin[]example.com ciissversion:2" # Contact info (CIISS v2)
|
||||
|
||||
# Ports (configurable)
|
||||
TOR_ORPORT=9001 # ORPort for relay traffic (default: 9001)
|
||||
@@ -127,7 +127,7 @@ We support **BOTH** naming conventions for maximum compatibility:
|
||||
```bash
|
||||
TOR_RELAY_MODE=bridge
|
||||
TOR_NICKNAME=MyBridge
|
||||
TOR_CONTACT_INFO=admin@example.com
|
||||
TOR_CONTACT_INFO="email:admin[]example.com ciissversion:2"
|
||||
TOR_ORPORT=9001
|
||||
TOR_OBFS4_PORT=9002
|
||||
```
|
||||
@@ -296,6 +296,6 @@ If you still see this error after updating to the latest version:
|
||||
|
||||
---
|
||||
|
||||
**Version:** 1.1.6
|
||||
**Last Updated:** 2026-02-08
|
||||
**Version:** 1.1.7
|
||||
**Last Updated:** 2026-03-02
|
||||
**Maintainer:** rE-Bo0t.bx1 <r3bo0tbx1@brokenbotnet.com>
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"cosmos-icon": "https://raw.githubusercontent.com/r3bo0tbx1/tor-guard-relay/refs/heads/main/src/onion.png",
|
||||
"cosmos-stack": "TorGuardRelay",
|
||||
"cosmos-stack-main": "TorGuardRelay",
|
||||
"cosmos-version": "1.1.6",
|
||||
"cosmos-version": "1.1.7",
|
||||
"maintainer": "rE-Bo0t.bx1 <r3bo0tbx1@brokenbotnet.com>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"cosmos-icon": "https://raw.githubusercontent.com/r3bo0tbx1/tor-guard-relay/refs/heads/main/src/obfs4.png",
|
||||
"cosmos-stack": "OBFS4-Bridge",
|
||||
"cosmos-stack-main": "OBFS4-Bridge",
|
||||
"cosmos-version": "1.1.6",
|
||||
"cosmos-version": "1.1.7",
|
||||
"maintainer": "rE-Bo0t.bx1 <r3bo0tbx1@brokenbotnet.com>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
"cosmos-stack-main": "OBFS4-Bridge",
|
||||
"cosmos-description": "🌉 Tor obfs4 Bridge - Drop-in replacement for thetorproject/obfs4-bridge",
|
||||
"cosmos-icon": "https://raw.githubusercontent.com/r3bo0tbx1/tor-guard-relay/refs/heads/main/src/obfs4.png",
|
||||
"cosmos-version": "1.1.6",
|
||||
"cosmos-version": "1.1.7",
|
||||
"maintainer": "rE-Bo0t.bx1 <r3bo0tbx1@brokenbotnet.com>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"environment": [
|
||||
"TOR_RELAY_MODE=bridge",
|
||||
"TOR_NICKNAME=MyTorBridge",
|
||||
"TOR_CONTACT_INFO=admin@example.com",
|
||||
"TOR_CONTACT_INFO=email:admin[]example.com ciissversion:2",
|
||||
"TOR_ORPORT=9001",
|
||||
"TOR_OBFS4_PORT=9002"
|
||||
],
|
||||
@@ -54,7 +54,7 @@
|
||||
"cosmos-description": "🧅 Tor obfs4 Bridge - ENV-based config",
|
||||
"cosmos-icon": "https://raw.githubusercontent.com/r3bo0tbx1/tor-guard-relay/refs/heads/main/src/obfs4.png",
|
||||
"cosmos-force-network-secured": "false",
|
||||
"cosmos-version": "1.1.6"
|
||||
"cosmos-version": "1.1.7"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"environment": [
|
||||
"TOR_RELAY_MODE=exit",
|
||||
"TOR_NICKNAME=MyExitRelay",
|
||||
"TOR_CONTACT_INFO=admin@example.com",
|
||||
"TOR_CONTACT_INFO=email:admin[]example.com ciissversion:2",
|
||||
"TOR_ORPORT=9001",
|
||||
"TOR_DIRPORT=0",
|
||||
"TOR_BANDWIDTH_RATE=50 MBytes",
|
||||
@@ -58,7 +58,7 @@
|
||||
"cosmos-icon": "https://raw.githubusercontent.com/r3bo0tbx1/tor-guard-relay/refs/heads/main/src/exit.png",
|
||||
"cosmos-auto-update": "true",
|
||||
"cosmos-force-network-secured": "false",
|
||||
"cosmos-version": "1.1.6"
|
||||
"cosmos-version": "1.1.7"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"environment": [
|
||||
"TOR_RELAY_MODE=guard",
|
||||
"TOR_NICKNAME=MyGuardRelay",
|
||||
"TOR_CONTACT_INFO=admin@example.com",
|
||||
"TOR_CONTACT_INFO=email:admin[]example.com ciissversion:2",
|
||||
"TOR_ORPORT=9001",
|
||||
"TOR_DIRPORT=0",
|
||||
"TOR_BANDWIDTH_RATE=50 MBytes",
|
||||
@@ -56,7 +56,7 @@
|
||||
"cosmos-description": "🛡️ Tor Guard Relay | ENV-based config",
|
||||
"cosmos-icon": "https://raw.githubusercontent.com/r3bo0tbx1/tor-guard-relay/refs/heads/main/src/onion.png",
|
||||
"cosmos-force-network-secured": "false",
|
||||
"cosmos-version": "1.1.6"
|
||||
"cosmos-version": "1.1.7"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
"cosmos-description": "🛡️ Multi Tor Guard Relay - 1",
|
||||
"cosmos-icon": "https://raw.githubusercontent.com/r3bo0tbx1/tor-guard-relay/main/src/onion.png",
|
||||
"cosmos-force-network-secured": "false",
|
||||
"cosmos-version": "1.1.6",
|
||||
"cosmos-version": "1.1.7",
|
||||
"maintainer": "rE-Bo0t.bx1 <r3bo0tbx1@brokenbotnet.com>"
|
||||
}
|
||||
},
|
||||
@@ -114,7 +114,7 @@
|
||||
"cosmos-description": "🛡️ Multi Tor Guard Relay - 2",
|
||||
"cosmos-icon": "https://raw.githubusercontent.com/r3bo0tbx1/tor-guard-relay/main/src/onion.png",
|
||||
"cosmos-force-network-secured": "false",
|
||||
"cosmos-version": "1.1.6",
|
||||
"cosmos-version": "1.1.7",
|
||||
"maintainer": "rE-Bo0t.bx1 <r3bo0tbx1@brokenbotnet.com>"
|
||||
}
|
||||
},
|
||||
@@ -172,7 +172,7 @@
|
||||
"cosmos-description": "🛡️ Multi Tor Guard Relay - 3",
|
||||
"cosmos-icon": "https://raw.githubusercontent.com/r3bo0tbx1/tor-guard-relay/main/src/onion.png",
|
||||
"cosmos-force-network-secured": "false",
|
||||
"cosmos-version": "1.1.6",
|
||||
"cosmos-version": "1.1.7",
|
||||
"maintainer": "rE-Bo0t.bx1 <r3bo0tbx1@brokenbotnet.com>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ services:
|
||||
labels:
|
||||
com.centurylinklabs.watchtower.enable: "true"
|
||||
description: "Tor obfs4 Bridge - Drop-in replacement for thetorproject/obfs4-bridge"
|
||||
version: "1.1.6"
|
||||
version: "1.1.7"
|
||||
maintainer: "rE-Bo0t.bx1 <r3bo0tbx1@brokenbotnet.com>"
|
||||
|
||||
volumes:
|
||||
|
||||
@@ -9,7 +9,7 @@ services:
|
||||
environment:
|
||||
TOR_RELAY_MODE: bridge
|
||||
TOR_NICKNAME: MyTorBridge
|
||||
TOR_CONTACT_INFO: "your-email@example.com"
|
||||
TOR_CONTACT_INFO: "email:your-email[]example.com ciissversion:2"
|
||||
TOR_ORPORT: 9001
|
||||
TOR_OBFS4_PORT: 9002
|
||||
TOR_BANDWIDTH_RATE: "10 MBytes"
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
labels:
|
||||
com.centurylinklabs.watchtower.enable: "true"
|
||||
description: "Tor obfs4 Bridge"
|
||||
version: "1.1.6"
|
||||
version: "1.1.7"
|
||||
maintainer: "rE-Bo0t.bx1 <r3bo0tbx1@brokenbotnet.com>"
|
||||
|
||||
volumes:
|
||||
|
||||
@@ -9,11 +9,15 @@ services:
|
||||
environment:
|
||||
TOR_RELAY_MODE: exit
|
||||
TOR_NICKNAME: MyExitRelay
|
||||
TOR_CONTACT_INFO: "your-email@example.com <0xYOUR_PGP_KEY>"
|
||||
TOR_CONTACT_INFO: "email:your-email[]example.com url:https://example.com proof:uri-rsa ciissversion:2"
|
||||
TOR_ORPORT: 9001
|
||||
TOR_DIRPORT: 0
|
||||
TOR_BANDWIDTH_RATE: "50 MBytes"
|
||||
TOR_BANDWIDTH_BURST: "100 MBytes"
|
||||
# Happy Family (Tor 0.4.9+) - generate with: docker exec tor-exit-relay gen-family MyRelays
|
||||
# TOR_FAMILY_ID: "YOUR_FAMILY_ID_HERE"
|
||||
# MyFamily (legacy, comma-separated fingerprints - keep during transition)
|
||||
# TOR_MY_FAMILY: "FINGERPRINT1,FINGERPRINT2"
|
||||
TOR_EXIT_POLICY: "accept *:20-23,accept *:43,accept *:53,accept *:79-81,accept *:88,accept *:110,accept *:143,accept *:194,accept *:220,accept *:389,accept *:443,accept *:464,accept *:465,accept *:531,accept *:543-544,accept *:554,accept *:563,accept *:636,accept *:706,accept *:749,accept *:873,accept *:902-904,accept *:981,accept *:989-995,accept *:1194,accept *:1220,accept *:1293,accept *:1500,accept *:1533,accept *:1677,accept *:1723,accept *:1755,accept *:1863,accept *:2082,accept *:2083,accept *:2086-2087,accept *:2095-2096,accept *:2102-2104,accept *:3128,accept *:3389,accept *:3690,accept *:4321,accept *:4643,accept *:5050,accept *:5190,accept *:5222-5223,accept *:5228,accept *:5900,accept *:6660-6669,accept *:6679,accept *:6697,accept *:8000,accept *:8008,accept *:8074,accept *:8080,accept *:8082,accept *:8087-8088,accept *:8232-8233,accept *:8332-8333,accept *:8443,accept *:8888,accept *:9418,accept *:9999,accept *:10000,accept *:11371,accept *:19294,accept *:19638,accept *:50002,accept *:64738,reject *:*"
|
||||
volumes:
|
||||
- tor-exit-data:/var/lib/tor
|
||||
@@ -37,7 +41,7 @@ services:
|
||||
labels:
|
||||
com.centurylinklabs.watchtower.enable: "true"
|
||||
description: "Tor Exit Relay"
|
||||
version: "1.1.6"
|
||||
version: "1.1.7"
|
||||
maintainer: "rE-Bo0t.bx1 <r3bo0tbx1@brokenbotnet.com>"
|
||||
|
||||
volumes:
|
||||
|
||||
@@ -9,11 +9,15 @@ services:
|
||||
environment:
|
||||
TOR_RELAY_MODE: guard
|
||||
TOR_NICKNAME: MyGuardRelay
|
||||
TOR_CONTACT_INFO: "your-email@example.com <0xYOUR_PGP_KEY>"
|
||||
TOR_CONTACT_INFO: "email:your-email[]example.com url:https://example.com proof:uri-rsa ciissversion:2"
|
||||
TOR_ORPORT: 9001
|
||||
TOR_DIRPORT: 0
|
||||
TOR_BANDWIDTH_RATE: "50 MBytes"
|
||||
TOR_BANDWIDTH_BURST: "100 MBytes"
|
||||
# Happy Family (Tor 0.4.9+) - generate with: docker exec tor-guard-relay gen-family MyRelays
|
||||
# TOR_FAMILY_ID: "YOUR_FAMILY_ID_HERE"
|
||||
# MyFamily (legacy, comma-separated fingerprints - keep during transition)
|
||||
# TOR_MY_FAMILY: "FINGERPRINT1,FINGERPRINT2"
|
||||
volumes:
|
||||
- tor-guard-data:/var/lib/tor
|
||||
- tor-guard-logs:/var/log/tor
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
version: '3.8'
|
||||
|
||||
# Happy Family Setup (Tor 0.4.9+):
|
||||
#
|
||||
# Option A - Generate a new key:
|
||||
# 1. Start relay-1, then run: docker exec guard-relay-1 gen-family MyRelays
|
||||
# 2. Copy the .secret_family_key to all relay volumes:
|
||||
# docker cp guard-relay-1:/var/lib/tor/keys/MyRelays.secret_family_key .
|
||||
# docker cp MyRelays.secret_family_key guard-relay-2:/var/lib/tor/keys/
|
||||
# docker cp MyRelays.secret_family_key guard-relay-3:/var/lib/tor/keys/
|
||||
# 3. Fix ownership: docker exec -u 0 <container> chown 100:101 /var/lib/tor/keys/MyRelays.secret_family_key
|
||||
# 4. Add 'FamilyId <value>' to each relay's torrc
|
||||
# 5. Keep MyFamily lines during the transition period
|
||||
# 6. Restart all relays
|
||||
#
|
||||
# Option B - Import an existing key from a non-Docker setup:
|
||||
# 1. Copy your .secret_family_key to the Docker host
|
||||
# 2. docker cp MyRelays.secret_family_key guard-relay-1:/var/lib/tor/keys/
|
||||
# (repeat for each relay container)
|
||||
# 3. Fix ownership: docker exec -u 0 <container> chown 100:101 /var/lib/tor/keys/MyRelays.secret_family_key
|
||||
# 4. Add 'FamilyId <value>' to each relay's torrc
|
||||
# 5. Restart all relays
|
||||
|
||||
services:
|
||||
tor-relay-1:
|
||||
image: r3bo0tbx1/onion-relay:latest
|
||||
|
||||
@@ -703,7 +703,7 @@
|
||||
<p>
|
||||
<strong>Important:</strong> The traffic you observed <strong>did not originate from this machine</strong>. It originated from an anonymous user somewhere in the world who routed their traffic through the Tor network. This server merely forwarded that traffic to your destination.
|
||||
</p>
|
||||
<p>Think of this server like a postal service that delivers letters—the postal worker doesn't write the letters, they just deliver them. Similarly, this exit node doesn't create traffic, it only forwards it.</p>
|
||||
<p>Think of this server like a postal service that delivers letters - the postal worker doesn't write the letters, they just deliver them. Similarly, this exit node doesn't create traffic, it only forwards it.</p>
|
||||
</section>
|
||||
<section class="card">
|
||||
<h2>
|
||||
|
||||
249
tools/gen-family
Normal file
249
tools/gen-family
Normal file
@@ -0,0 +1,249 @@
|
||||
#!/bin/sh
|
||||
# Generate or display Tor Happy Family key and FamilyId
|
||||
# Requires Tor >= 0.4.9.x with --keygen-family support
|
||||
|
||||
set -e
|
||||
|
||||
GREEN=$(printf '\033[0;32m')
|
||||
BLUE=$(printf '\033[0;34m')
|
||||
YELLOW=$(printf '\033[1;33m')
|
||||
CYAN=$(printf '\033[0;36m')
|
||||
RED=$(printf '\033[0;31m')
|
||||
BOLD=$(printf '\033[1m')
|
||||
NC=$(printf '\033[0m')
|
||||
|
||||
TOR_DATA_DIR="${TOR_DATA_DIR:-/var/lib/tor}"
|
||||
KEYS_DIR="${TOR_DATA_DIR}/keys"
|
||||
FORCE=0
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--force|-f) FORCE=1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
FAMILY_NAME=""
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--force|-f|--help|-h|--show|-s) ;;
|
||||
*) FAMILY_NAME="$arg"; break ;;
|
||||
esac
|
||||
done
|
||||
FAMILY_NAME="${FAMILY_NAME:-TorFamily}"
|
||||
|
||||
show_usage() {
|
||||
echo ""
|
||||
echo "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo "${CYAN}║${NC} ${BOLD}Tor Happy Family Key Generator${NC} ${CYAN}║${NC}"
|
||||
echo "${CYAN}╚════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo "${BOLD}Usage:${NC}"
|
||||
echo " gen-family [name] Generate a new family key"
|
||||
echo " gen-family [name] --force Overwrite existing key (no backup prompt)"
|
||||
echo " gen-family --show Show existing FamilyId"
|
||||
echo " gen-family --help Show this help"
|
||||
echo ""
|
||||
echo "${BOLD}Examples:${NC}"
|
||||
echo " docker exec tor-relay gen-family MyRelays"
|
||||
echo " docker exec tor-relay gen-family --show"
|
||||
echo ""
|
||||
echo "${BOLD}What is Happy Family?${NC}"
|
||||
echo " Tor 0.4.9+ replaces MyFamily with a cryptographic key-based"
|
||||
echo " system. All relays in a family share one secret key file."
|
||||
echo " See: https://community.torproject.org/relay/setup/post-install/family-ids/"
|
||||
echo ""
|
||||
}
|
||||
|
||||
show_existing() {
|
||||
echo ""
|
||||
echo "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo "${CYAN}║${NC} ${BOLD}Tor Happy Family - Current Status${NC} ${CYAN}║${NC}"
|
||||
echo "${CYAN}╚════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
|
||||
FOUND=0
|
||||
for keyfile in "$KEYS_DIR"/*.secret_family_key; do
|
||||
[ -f "$keyfile" ] || continue
|
||||
FOUND=1
|
||||
BASENAME=$(basename "$keyfile" .secret_family_key)
|
||||
echo "${GREEN}✓${NC} Found family key: ${BOLD}${BASENAME}${NC}"
|
||||
echo " File: ${BLUE}${keyfile}${NC}"
|
||||
done
|
||||
|
||||
if [ "$FOUND" -eq 0 ]; then
|
||||
echo "${YELLOW}⚠${NC} No family keys found in ${KEYS_DIR}"
|
||||
echo ""
|
||||
echo " Generate one with: ${BOLD}gen-family MyRelays${NC}"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TORRC="${TOR_CONFIG:-/etc/tor/torrc}"
|
||||
if [ -f "$TORRC" ]; then
|
||||
echo ""
|
||||
FAMILY_IDS=$(grep -i "^FamilyId " "$TORRC" 2>/dev/null || true)
|
||||
if [ -n "$FAMILY_IDS" ]; then
|
||||
echo "${GREEN}✓${NC} FamilyId in torrc:"
|
||||
echo "$FAMILY_IDS" | while read -r line; do
|
||||
echo " ${BLUE}${line}${NC}"
|
||||
done
|
||||
else
|
||||
echo "${YELLOW}⚠${NC} No FamilyId line found in torrc"
|
||||
echo " Add the FamilyId line to your torrc to activate Happy Family"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f "$TORRC" ]; then
|
||||
MY_FAMILY=$(grep -i "^MyFamily " "$TORRC" 2>/dev/null || true)
|
||||
if [ -n "$MY_FAMILY" ]; then
|
||||
echo ""
|
||||
echo "${YELLOW}ℹ${NC} MyFamily lines also present (transition period - this is expected)"
|
||||
MY_FAMILY_COUNT=$(echo "$MY_FAMILY" | wc -l)
|
||||
echo " ${MY_FAMILY_COUNT} MyFamily entries configured"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
generate_key() {
|
||||
echo ""
|
||||
echo "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo "${CYAN}║${NC} ${BOLD}Tor Happy Family Key Generator${NC} ${CYAN}║${NC}"
|
||||
echo "${CYAN}╚════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
|
||||
TOR_VERSION=$(tor --version 2>/dev/null | head -n1 || echo "unknown")
|
||||
echo "${BOLD}Tor version:${NC} ${TOR_VERSION}"
|
||||
echo ""
|
||||
|
||||
if [ -f "${KEYS_DIR}/${FAMILY_NAME}.secret_family_key" ]; then
|
||||
if [ "$FORCE" -eq 1 ]; then
|
||||
echo "${YELLOW}⚠${NC} Removing existing family key: ${BOLD}${FAMILY_NAME}${NC}"
|
||||
rm -f "${KEYS_DIR}/${FAMILY_NAME}.secret_family_key"
|
||||
echo "${GREEN}✓${NC} Old key removed"
|
||||
echo ""
|
||||
else
|
||||
echo "${YELLOW}⚠${NC} Family key '${FAMILY_NAME}' already exists!"
|
||||
echo " File: ${BLUE}${KEYS_DIR}/${FAMILY_NAME}.secret_family_key${NC}"
|
||||
echo ""
|
||||
echo " ${BOLD}To replace without backup:${NC}"
|
||||
echo " ${BOLD}gen-family ${FAMILY_NAME} --force${NC}"
|
||||
echo ""
|
||||
echo " ${BOLD}To replace safely:${NC}"
|
||||
echo " 1. Back it up first:"
|
||||
echo " ${BOLD}docker cp <container>:${KEYS_DIR}/${FAMILY_NAME}.secret_family_key ./${FAMILY_NAME}.secret_family_key.bak${NC}"
|
||||
echo " 2. Remove the old key:"
|
||||
echo " ${BOLD}docker exec -u 0 <container> rm ${KEYS_DIR}/${FAMILY_NAME}.secret_family_key${NC}"
|
||||
echo " 3. Run gen-family again:"
|
||||
echo " ${BOLD}gen-family ${FAMILY_NAME}${NC}"
|
||||
echo ""
|
||||
echo " ${RED}⚠️ WARNING:${NC} Replacing a family key means ALL relays using it"
|
||||
echo " must be updated with the new key and FamilyId. Back up first!"
|
||||
echo ""
|
||||
echo " ${BOLD}Or use a different name:${NC} gen-family NewFamilyName"
|
||||
echo " ${BOLD}View existing keys:${NC} gen-family --show"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p "$KEYS_DIR" 2>/dev/null || true
|
||||
|
||||
echo "${BOLD}Generating family key: ${CYAN}${FAMILY_NAME}${NC}"
|
||||
echo ""
|
||||
|
||||
KEYGEN_OUTPUT=$(cd "$KEYS_DIR" && tor --keygen-family "$FAMILY_NAME" 2>&1) || {
|
||||
echo "${RED}✗${NC} Failed to generate family key!"
|
||||
echo ""
|
||||
echo " Output: ${KEYGEN_OUTPUT}"
|
||||
echo ""
|
||||
echo " This requires Tor >= 0.4.9.2-alpha"
|
||||
echo " Your version: ${TOR_VERSION}"
|
||||
echo ""
|
||||
exit 1
|
||||
}
|
||||
|
||||
FAMILY_ID=$(echo "$KEYGEN_OUTPUT" | grep "^FamilyId " | head -1)
|
||||
|
||||
if [ -z "$FAMILY_ID" ]; then
|
||||
FAMILY_ID=$(echo "$KEYGEN_OUTPUT" | grep "FamilyId" | head -1 | sed 's/.*\(FamilyId .*\)/\1/')
|
||||
fi
|
||||
|
||||
echo "${GREEN}✓${NC} Family key generated successfully!"
|
||||
echo ""
|
||||
|
||||
if [ -n "$FAMILY_ID" ]; then
|
||||
echo "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo "${BOLD}1. Add this line to your torrc:${NC}"
|
||||
echo "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo ""
|
||||
echo " ${GREEN}${FAMILY_ID}${NC}"
|
||||
echo ""
|
||||
else
|
||||
echo "${YELLOW}⚠${NC} Could not extract FamilyId from output."
|
||||
echo " Full output:"
|
||||
echo " ${KEYGEN_OUTPUT}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo "${BOLD}2. Key file location:${NC}"
|
||||
echo "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo ""
|
||||
echo " ${BLUE}${KEYS_DIR}/${FAMILY_NAME}.secret_family_key${NC}"
|
||||
echo ""
|
||||
echo "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo "${BOLD}3. For multi-relay setups:${NC}"
|
||||
echo "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo ""
|
||||
echo " Copy this key to ALL your relays. Each relay needs:"
|
||||
echo " • The ${BOLD}.secret_family_key${NC} file in its keys directory"
|
||||
echo " • The ${BOLD}FamilyId${NC} line in its torrc"
|
||||
echo ""
|
||||
echo " Extract from this container:"
|
||||
echo " ${BOLD}docker cp <container>:${KEYS_DIR}/${FAMILY_NAME}.secret_family_key .${NC}"
|
||||
echo ""
|
||||
echo " Copy to another container's volume:"
|
||||
echo " ${BOLD}docker cp ${FAMILY_NAME}.secret_family_key <other>:${KEYS_DIR}/${NC}"
|
||||
echo ""
|
||||
echo "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo ""
|
||||
echo "${CYAN}📝 Next steps:${NC}"
|
||||
echo " 1. Add the FamilyId line to your torrc (all relays)"
|
||||
echo " 2. Copy the .secret_family_key to all relay keys directories"
|
||||
echo " 3. Restart your relays: ${BOLD}docker restart tor-relay${NC}"
|
||||
echo " 4. Keep MyFamily lines during the transition period"
|
||||
echo ""
|
||||
echo "${CYAN}⚠️ Important:${NC}"
|
||||
echo " • Keep your .secret_family_key ${RED}SECRET${NC} - treat it like a private key"
|
||||
echo " • Back up the key file - losing it means regenerating for all relays"
|
||||
echo " • The key persists in your Docker volume (${BOLD}/var/lib/tor${NC})"
|
||||
echo " • During transition, keep BOTH MyFamily AND FamilyId configured"
|
||||
echo ""
|
||||
echo "${CYAN}📖 Documentation:${NC}"
|
||||
echo " https://community.torproject.org/relay/setup/post-install/family-ids/"
|
||||
echo ""
|
||||
}
|
||||
|
||||
ACTION=""
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--help|-h) ACTION="help"; break ;;
|
||||
--show|-s) ACTION="show"; break ;;
|
||||
--force|-f) ;;
|
||||
*) ACTION="generate"; break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "${ACTION:-help}" in
|
||||
help)
|
||||
show_usage
|
||||
;;
|
||||
show)
|
||||
show_existing
|
||||
;;
|
||||
generate)
|
||||
generate_key
|
||||
;;
|
||||
esac
|
||||
18
tools/status
18
tools/status
@@ -57,6 +57,24 @@ if [ -f "$TOR_DATA/fingerprint" ] && [ -r "$TOR_DATA/fingerprint" ]; then
|
||||
echo "🔑 Fingerprint: ${FP_START}...${FP_END}"
|
||||
fi
|
||||
|
||||
# Happy Family status
|
||||
FAMILY_KEY_COUNT=0
|
||||
if [ -d "$TOR_DATA/keys" ]; then
|
||||
for fk in "$TOR_DATA/keys"/*.secret_family_key; do
|
||||
[ -f "$fk" ] || continue
|
||||
FAMILY_KEY_COUNT=$((FAMILY_KEY_COUNT + 1))
|
||||
done
|
||||
fi
|
||||
TORRC="${TOR_CONFIG:-/etc/tor/torrc}"
|
||||
if [ "$FAMILY_KEY_COUNT" -gt 0 ]; then
|
||||
echo "👨👩👧 Family Key: $FAMILY_KEY_COUNT key(s) present"
|
||||
fi
|
||||
if [ -f "$TORRC" ] && grep -qi "^FamilyId " "$TORRC" 2>/dev/null; then
|
||||
echo "✅ Happy Family: CONFIGURED"
|
||||
elif [ "$FAMILY_KEY_COUNT" -gt 0 ]; then
|
||||
echo "⚠️ Happy Family: key present but FamilyId not in torrc"
|
||||
fi
|
||||
|
||||
ERRORS=$(grep -c "\[err\]" "$TOR_LOG" 2>/dev/null || echo "0")
|
||||
ERRORS=$(sanitize_num "$ERRORS")
|
||||
WARNINGS=$(grep -c "\[warn\]" "$TOR_LOG" 2>/dev/null || echo "0")
|
||||
|
||||
Reference in New Issue
Block a user