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