Skip to content

CBTOR - Tor Management API

Anonymous web fetching through a load-balanced Tor worker pool with self-healing recovery.

Overview

CBTOR provides a REST API for routing web requests through the Tor network using 4 dedicated OpenWRT workers. Each worker runs Tor connected via WireGuard tunnels, with automatic health monitoring, circuit rotation, and self-healing recovery.

Live API: https://tor.nominate.ai

Feature Description
Anonymous Fetch Route any URL through Tor (clearnet or .onion)
Load Balancing Round-robin, sticky, random, least-connections
Self-Healing Automatic recovery with exponential backoff
Circuit Rotation NEWNYM signals for fresh exit IPs

API Endpoints

Core Operations

Endpoint Method Description
/api/v1/fetch POST Fetch URL anonymously via Tor
/api/v1/health GET Worker pool health status
/api/v1/mode POST Set load balancing mode
/api/v1/endpoints GET Tor check endpoint statistics

Worker Management

Endpoint Method Description
/api/v1/tor/workers GET List all Tor workers
/api/v1/tor/workers/{n} GET Get specific worker status
/api/v1/tor/workers/{n}/tor/start POST Start Tor service
/api/v1/tor/workers/{n}/tor/stop POST Stop Tor service
/api/v1/tor/workers/{n}/tor/restart POST Restart Tor service
/api/v1/tor/status GET Cluster status summary
/api/v1/workers/drain POST Remove worker from pool
/api/v1/workers/enable POST Force-enable worker

Architecture

                    ┌─────────────────────────────────────┐
                    │  CBTOR API (tor.nominate.ai:32211)  │
                    │  - Load Balancer                    │
                    │  - Health Manager                   │
                    │  - Recovery Logic                   │
                    └───────────────┬─────────────────────┘
        ┌───────────────┬───────────┼───────────┬───────────────┐
        │               │           │           │               │
   wg-tor01        wg-tor02    wg-tor03    wg-tor04        WireGuard
   10.201.1.x      10.201.2.x  10.201.3.x  10.201.4.x      Tunnels
        │               │           │           │
        ▼               ▼           ▼           ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Worker 01   │ │ Worker 02   │ │ Worker 03   │ │ Worker 04   │
│ 17.0.0.134  │ │ 17.0.0.202  │ │ 17.0.0.201  │ │ 17.0.0.120  │
│             │ │             │ │             │ │             │
│ Tor SOCKS   │ │ Tor SOCKS   │ │ Tor SOCKS   │ │ Tor SOCKS   │
│ :9050       │ │ :9050       │ │ :9050       │ │ :9050       │
│             │ │             │ │             │ │             │
│ TransPort   │ │ TransPort   │ │ TransPort   │ │ TransPort   │
│ :9040       │ │ :9040       │ :9040       │ │ :9040       │
│             │ │             │ │             │ │             │
│ Control     │ │ Control     │ │ Control     │ │ Control     │
│ :9051       │ │ :9051       │ │ :9051       │ │ :9051       │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘
       │               │               │               │
       └───────────────┴───────────────┴───────────────┘
                    ┌─────────────────────────────────────┐
                    │          Tor Network                │
                    │   (Entry → Middle → Exit nodes)     │
                    └─────────────────────────────────────┘

Request Routing

URL Type Routing Method Port Typical Latency
Clearnet (http/https) TransPort via WireGuard 9040 1-5 seconds
.onion hidden service SOCKS5 proxy 9050 10-30 seconds

Worker Health States

HEALTHY ──(3 failures)──▶ SUSPECT ──(3 more failures)──▶ DEAD
    ▲                                                       │
    │                                                       ▼
    └─────────────────────────────────────────────────── RECOVERY
                       (success)
State Description Receives Traffic
healthy All checks passing Yes
suspect 3+ consecutive failures Yes (degraded)
dead 6+ failures, entering recovery No
recovery Active recovery in progress No

Timeout & Recovery Cycles

Host-Side Health Manager (API Server)

The API server runs continuous health monitoring every 10 seconds:

Parameter Value Description
health_check_interval 10 sec Check all workers
failure_threshold 3 Failures before SUSPECT
recovery_backoff 1, 2, 4, 8, 16, 32 sec Exponential retry delays
reboot_after_attempts 6 Attempts before forcing reboot

Recovery Sequence: 1. Check SSH reachable 2. Check SOCKS port (9050) responding 3. Restart Tor if needed (/etc/init.d/tor restart) 4. Reconnect WireGuard tunnel 5. Verify Tor circuit via check endpoints

Node-Side Self-Healing (Each Worker)

Each Tor worker runs its own health check every minute via cron:

Parameter Value Description
TEST_TIMEOUT 30 sec .onion page load timeout
NEWNYM_WAIT 5 sec Wait after circuit rotation
RESTART_WAIT 30 sec Wait after Tor restart
RECOVERY_WAIT 15 min Stay offline before retry

Node Recovery Sequence:

1. Test random .onion site via SOCKS
2. If fail → NEWNYM (new circuit), retry
3. If still fail → Restart Tor, retry
4. If still fail → Mark OFFLINE, stop Tor
5. After 15 min → Attempt recovery

Test Endpoints (.onion sites):

Site URL
DuckDuckGo duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion
ProPublica p53lf57qovyuvwsc6xnrppyply3vtqm7l6pcobkmyqsiofyeznfu5uqd.onion
BBC News bbcnewsd73hkzno2ini43t4gblxvycyac5aw4gnv7t2rccijh7745uqd.onion
ProtonMail protonmailrmez3lotccipshtkleegetolb73fuirgj7r4o4vfu7ozyd.onion
Riseup vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd.onion
Archive.org archiveiya74codqgiixo33q62qlrqtkgmcitqx5u2oeqnmn5bpcbiyd.onion

Combined Recovery Timeline

0s      Host detects failure
10s     Host retries (failure_threshold not reached)
20s     Host retries
30s     Worker marked SUSPECT
40s     Host retries
50s     Host retries
60s     Worker marked DEAD, recovery starts
        Meanwhile: Node cron runs, detects issue
        Node tries NEWNYM (5s wait)
        Node tries Tor restart (30s wait)
        If both fail: Node goes OFFLINE for 15 min

61s     Host recovery: SSH check, SOCKS check
62s     Host: Restart Tor via SSH
92s     Host: Verify Tor circuit
        If success → HEALTHY
        If fail → Wait 1s (backoff[0])

93s     Host retry
        If fail → Wait 2s (backoff[1])
...
        After 6 failed attempts → Host reboots worker
        Wait 90s for reboot → Try again

Load Balancing Modes

Mode Algorithm Use Case
round_robin Rotate through workers Even distribution (default)
sticky Hash-based consistent routing Session affinity
random Random selection Simple distribution
least_connections Pick least busy High throughput
failover Always use first healthy Primary/backup pattern

Quick Start

Basic Fetch

import requests

response = requests.post("https://tor.nominate.ai/api/v1/fetch", json={
    "url": "https://check.torproject.org/api/ip"
})
data = response.json()
print(f"Routed via {data['worker']}, exit IP in body")

Sticky Session (Same Exit IP)

response = requests.post("https://tor.nominate.ai/api/v1/fetch", json={
    "url": "https://example.com/login",
    "mode": "sticky",
    "sticky_key": "my-session-123"
})

Check Health

curl https://tor.nominate.ai/api/v1/health
Resource URL
Swagger UI https://tor.nominate.ai/docs
ReDoc https://tor.nominate.ai/redoc
OpenAPI Spec https://tor.nominate.ai/openapi.json
Document Description
Deployment Plan Initial installation guide
Load Balancer Load balancer design
DNSCrypt Setup DNS encryption
Next Steps Roadmap

Key Files

API Server (Host)

File Purpose
api/main.py FastAPI application
api/routers/fetch.py Fetch and health endpoints
api/routers/tor.py Worker management endpoints
api/load_balancer/health.py Health manager with recovery
api/load_balancer/pool.py Worker pool and load balancing
scripts/cron/tor-warmup.sh Circuit warmup script

Worker Nodes (OpenWRT)

File Purpose
/etc/tor/torrc Tor daemon configuration
/etc/tor/onion-test-sites.txt Health check test URLs
/usr/local/bin/tor-health-check.sh Self-healing script
/var/run/tor/health-status Current state (online/offline)
/var/log/tor-health.log Health check logs