This repository has no description
2.3 kB
89 lines
1#!/usr/bin/env bash
2set -euo pipefail
3
4# Create temporary directory for this tor instance
5TOR_DIR=$(mktemp -d -t tornade.XXXXXX)
6trap 'rm -rf "$TOR_DIR"' EXIT
7
8# Generate random ports
9SOCKS_PORT=$((9050 + RANDOM % 1000))
10CONTROL_PORT=$((SOCKS_PORT + 1))
11
12# Create tor configuration
13cat > "$TOR_DIR/torrc" <<EOF
14DataDirectory $TOR_DIR/data
15SocksPort 127.0.0.1:$SOCKS_PORT
16ControlPort 127.0.0.1:$CONTROL_PORT
17Log notice file $TOR_DIR/tor.log
18RunAsDaemon 0
19
20# Performance and reliability optimizations
21CircuitBuildTimeout 15
22LearnCircuitBuildTimeout 0
23NumEntryGuards 8
24KeepalivePeriod 60
25SocksTimeout 120
26
27# Reliability settings
28MaxCircuitDirtiness 600
29NewCircuitPeriod 30
30UseEntryGuards 1
31EOF
32
33# Start tor in background - suppress output to avoid protocol interference
34tor -f "$TOR_DIR/torrc" >/dev/null 2>&1 &
35TOR_PID=$!
36
37# Function to cleanup tor process
38cleanup() {
39 if kill -0 "$TOR_PID" 2>/dev/null; then
40 kill "$TOR_PID" 2>/dev/null || true
41 wait "$TOR_PID" 2>/dev/null || true
42 fi
43 rm -rf "$TOR_DIR"
44}
45trap cleanup EXIT INT TERM
46
47# Retry up to 5 times to establish circuits
48for attempt in 1 2 3 4 5; do
49
50 if [ $attempt -gt 1 ]; then
51 # Kill previous tor instance and restart
52 kill "$TOR_PID" 2>/dev/null || true
53 wait "$TOR_PID" 2>/dev/null || true
54 tor -f "$TOR_DIR/torrc" >/dev/null 2>&1 &
55 TOR_PID=$!
56 fi
57
58 # Check frequently at first, then slow down - longer timeout per attempt
59 for i in {1..120}; do
60 if grep -q "Bootstrapped 100%" "$TOR_DIR/tor.log" 2>/dev/null; then
61 # Success - exit both loops
62 break 2
63 fi
64 # Check every 0.1s for first 2 seconds, then every 0.5s
65 if [ "$i" -le 20 ]; then
66 sleep 0.1
67 else
68 sleep 0.5
69 fi
70 done
71
72 # This attempt failed, continue to next attempt
73done
74
75# Final check - if still not ready after all attempts, exit
76if ! grep -q "Bootstrapped 100%" "$TOR_DIR/tor.log" 2>/dev/null; then
77 exit 1
78fi
79
80# Check if we're trying to run SSH on macOS
81if [[ "$1" == "ssh" ]] && [[ "$(uname)" == "Darwin" ]]; then
82 # On macOS, use ProxyCommand instead of torsocks due to SIP
83 shift # remove 'ssh' from arguments
84 exec ssh -o ProxyCommand="nc -x 127.0.0.1:$SOCKS_PORT %h %p" "$@"
85else
86 # For other commands or non-macOS systems, use torsocks
87 export TORSOCKS_TOR_PORT=$SOCKS_PORT
88 exec torsocks "$@"
89fi