SOCKS5 Proxy
Run a local SOCKS5 proxy server that routes any SOCKS5-compatible application through the Tor network.
Overview
The Socks5Proxy component provides a standard SOCKS5 proxy interface, allowing you to:
- Universal Tor Access — Route any SOCKS5-compatible application through Tor
- Zero Configuration — Default binds to
127.0.0.1:9050(Tor standard) - Circuit Isolation — Separate Tor circuits per connection or user
- Multi-Identity — Run multiple proxies with different isolation tokens
Basic Usage
Rust
use hypertor::{Socks5Proxy, Result};
#[tokio::main]
async fn main() -> Result<()> {
// Start SOCKS5 proxy on default address (127.0.0.1:9050)
let proxy = Socks5Proxy::with_defaults();
println!("SOCKS5 proxy running on 127.0.0.1:9050");
println!("Press Ctrl+C to stop");
proxy.run().await?;
Ok(())
}
Custom Configuration
use hypertor::{Socks5Proxy, ProxyConfig};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
let config = ProxyConfig {
bind_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 1080),
isolation_by_auth: true, // Different Tor identity per SOCKS auth
timeout_secs: 120,
};
let proxy = Socks5Proxy::with_config(config);
proxy.run().await?;
Using the Proxy
Once the SOCKS5 proxy is running, you can route any SOCKS5-compatible application through Tor:
curl
curl --socks5-hostname 127.0.0.1:9050 https://check.torproject.org/api/ip
Note: Use
--socks5-hostname(not--socks5) to resolve DNS through Tor. This prevents DNS leaks.
wget
wget -e use_proxy=yes -e http_proxy=socks5://127.0.0.1:9050 https://example.com
Python (requests)
import requests
proxies = {
'http': 'socks5h://127.0.0.1:9050',
'https': 'socks5h://127.0.0.1:9050'
}
resp = requests.get('https://check.torproject.org/api/ip', proxies=proxies)
print(f"Tor IP: {resp.json()['IP']}")
Note: Use
socks5h://(with ‘h’) to resolve DNS through the proxy (Tor). Plainsocks5://leaks DNS.
Python (aiohttp)
import aiohttp
import aiohttp_socks
async def fetch_via_tor():
connector = aiohttp_socks.ProxyConnector.from_url('socks5://127.0.0.1:9050')
async with aiohttp.ClientSession(connector=connector) as session:
async with session.get('https://check.torproject.org/api/ip') as resp:
data = await resp.json()
print(f"Tor IP: {data['IP']}")
Git
git config --global http.proxy socks5h://127.0.0.1:9050
git clone https://github.com/example/repo.git
SSH
ssh -o ProxyCommand='nc -x 127.0.0.1:9050 %h %p' user@host
Firefox/Browsers
- Settings → Network Settings
- Manual proxy configuration
- SOCKS Host:
127.0.0.1, Port:9050 - SOCKS v5
- ✅ “Proxy DNS when using SOCKS v5”
Circuit Isolation
Control how Tor circuits are assigned to connections:
Per-Connection Isolation
use hypertor::{Socks5Proxy, ProxyConfig};
// Each connection gets its own Tor circuit (different exit IP)
let proxy = Socks5Proxy::builder()
.isolation_per_connection(true)
.build();
Authentication-Based Isolation
// Different SOCKS auth credentials = different Tor identity
let proxy = Socks5Proxy::builder()
.isolation_by_auth(true)
.build();
// Client A: socks5://user1:pass1@127.0.0.1:9050 → Circuit A
// Client B: socks5://user2:pass2@127.0.0.1:9050 → Circuit B
Custom Isolation Tokens
use hypertor::{Socks5Proxy, IsolationToken};
// Create proxy with custom isolation token
let token = IsolationToken::new();
let proxy = Socks5Proxy::builder()
.isolation_token(token.clone())
.build();
// All connections through this proxy share the same Tor circuit
Multi-Identity Proxies
Run multiple SOCKS5 proxies with different identities:
use hypertor::{Socks5Proxy, IsolationToken};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
// Proxy 1: Identity for browsing
let proxy1 = Socks5Proxy::builder()
.bind(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 9051))
.isolation_token(IsolationToken::new())
.build();
// Proxy 2: Identity for API access
let proxy2 = Socks5Proxy::builder()
.bind(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 9052))
.isolation_token(IsolationToken::new())
.build();
// Run both
tokio::join!(proxy1.run(), proxy2.run());
Security Considerations
DNS Leaks
Always use socks5h:// (with ‘h’) in clients that support it, or --socks5-hostname for curl. This ensures DNS resolution happens through Tor, not locally.
Local Binding
By default, the proxy binds to 127.0.0.1 (localhost only). If you need to expose it on a network:
// ⚠️ Exposes Tor proxy to network - use with caution!
let proxy = Socks5Proxy::builder()
.bind("0.0.0.0:9050".parse()?)
.build();
Authentication
For network-exposed proxies, enable authentication:
let proxy = Socks5Proxy::builder()
.auth("username", "password")
.build();
Example: Full Application
use hypertor::{Socks5Proxy, ProxyConfig, Result};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
#[tokio::main]
async fn main() -> Result<()> {
// Configure proxy
let proxy = Socks5Proxy::builder()
.bind(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 9050))
.isolation_by_auth(true)
.build();
println!("╔════════════════════════════════════════╗");
println!("║ hypertor SOCKS5 Proxy ║");
println!("╠════════════════════════════════════════╣");
println!("║ Address: 127.0.0.1:9050 ║");
println!("║ Isolation: Per-authentication ║");
println!("╚════════════════════════════════════════╝");
println!();
println!("Test with:");
println!(" curl --socks5-hostname 127.0.0.1:9050 https://check.torproject.org/api/ip");
proxy.run().await?;
Ok(())
}
Next Steps
- TorClient Documentation — Direct HTTP client API
- OnionApp Documentation — Host your own .onion service
- Security Features — PoW, Vanguards, Leak Detection