Tor hidden services (also called onion services) allow you to host and access services without revealing your IP address. These services use the .onion top-level domain and route all traffic through the Tor network, providing end-to-end encryption and anonymity for both the server and the client.
This guide covers practical methods for accessing hidden services safely, with configuration examples and security considerations for developers building privacy-focused applications.
Understanding Tor Hidden Services
A hidden service is a service accessible only through the Tor network. Instead of using a traditional IP address, hidden services use a unique onion address—a 56-character base32 string ending in .onion (for version 3) or a 16-character base32 string ending in .onion (for version 2, which is deprecated).
When you access a hidden service, your traffic takes a path through at least three Tor relays, and the service itself is also accessed through Tor relays. Neither party learns the other’s IP address. The connection uses TLS with ephemeral keys, providing forward secrecy.
Installing and Configuring Tor
First, install the Tor daemon. On macOS, use Homebrew:
brew install tor
On Debian-based Linux distributions:
sudo apt install tor
The Tor configuration file is typically located at /etc/tor/torrc on Linux or /usr/local/etc/tor/torrc on macOS. For accessing hidden services as a client, the default configuration usually works. However, for better security, consider these settings:
# Force using bridges if you're in a restrictive environment
UseBridges 1
Bridge obfs4 <bridge-address>
# Exclude known bad exits (optional, for advanced users)
ExcludeNodes {ru},{ua},{by}
# Use only secure protocols
SafeSocks 1
Start the Tor service:
# macOS
brew services start tor
# Linux
sudo systemctl start tor
Accessing Hidden Services with Tor Browser
The simplest method to access hidden services is using Tor Browser, available at torproject.org. Tor Browser is a modified Firefox that routes all traffic through the Tor network automatically.
To access a hidden service:
- Launch Tor Browser
- Type the
.onionaddress directly into the address bar - The browser will connect through the Tor network
Tor Browser includes several privacy features:
- NoScript for JavaScript control
- HTTPS Everywhere for encrypted connections
- New identity feature to clear cookies and tabs
Programmatic Access Using Stem
For developers building applications that interact with hidden services, the Stem library provides Python bindings for Tor control. Install it with:
pip install stem
Here’s a basic example of connecting to a hidden service:
from stem import Circuit
from stem.control import Controller
def access_hidden_service(onion_address, controller_port=9051):
"""
Access a hidden service through Tor.
Args:
onion_address: The .onion address to connect to
controller_port: The Tor control port (default 9051 for Tor daemon)
"""
with Controller.from_port(port=controller_port) as controller:
controller.authenticate()
# Create a new circuit to the hidden service
circuit = controller.new_circuit(
purpose=Circuit.PURPOSE_SERVICE,
build_flags=[Circuit.BUILD_FLAG_ONEHOP_TUNNEL]
)
# Get the descriptor for the hidden service
try:
descriptor = controller.get_hidden_service_descriptor(onion_address)
print(f"Found hidden service: {descriptor}")
return descriptor
except Exception as e:
print(f"Error accessing service: {e}")
return None
# Example usage
if __name__ == "__main__":
# Use the DuckDuckGo hidden service as an example
result = access_hidden_service("3g2upl4pq6kufc4m.onion")
Using curl with Tor
For command-line access, you can use curl with the Tor SOCKS proxy. This is useful for scripting and automation:
# Using SOCKS5 proxy (port 9050 for Tor daemon)
curl --socks5 localhost:9050 https://3g2upl4pq6kufc4m.onion
# Or use torsocks for transparent proxying
torsocks curl https://3g2upl4pnhvihwli.onion
For HTTPS enforcement (recommended):
curl --socks5 localhost:9050 -H "Host: 3g2upl4pq6kufc4m.onion" https://3g2upl4pq6kufc4m.onion
Verifying Connection Security
Before accessing any hidden service, verify that your Tor circuit is working correctly. Check your IP address through the Tor network:
curl --socks5 localhost:9050 https://check.torproject.org/api/ip
You should receive a response indicating you’re using Tor. The response should include "IsTor":true.
For hidden services that support it, verify the onion service’s authentication key. Version 3 onion services use a public key that can be verified:
# The descriptor contains the service's public key
tor --list-descriptors --hidden-service <onion-address>
Security Best Practices
When accessing hidden services, follow these security guidelines:
Always use HTTPS when available
Many hidden services support HTTPS. This provides an additional layer of encryption beyond Tor’s circuit encryption. Check for the HTTPS lock icon in Tor Browser or use -k sparingly in curl to allow invalid certificates only when necessary.
Verify onion addresses Hidden service addresses are cryptographically derived. Don’t trust addresses shared through unsecured channels. When possible, verify the address through multiple independent sources.
Disable JavaScript for unknown services Tor Browser’s NoScript default settings block JavaScript on untrusted sites. Only enable JavaScript for services you trust and understand.
Use dedicated Tor instances For development work, consider running a separate Tor daemon instance rather than using the same Tor connection for sensitive browsing and development. Configure a different SOCKS port:
SOCKSPort 9052
ControlPort 9053
DataDirectory /var/lib/tor-dev
Monitor for IP leaks Ensure your application doesn’t make DNS queries or direct connections outside the Tor network. Use Wireshark or tcpdump to verify all traffic goes through the Tor proxy:
# Monitor connections on the Tor SOCKS port
sudo tcpdump -i lo0 -n 'tcp port 9050'
Troubleshooting Common Issues
If you cannot connect to a hidden service, consider these common problems:
The service may be offline or overloaded. Try again later or check if the address is correct. Some networks block Tor connections—consider using Tor bridges configured in your torrc file.
Connection timeouts can occur if the hidden service has limited capacity or network issues. Increase your connection timeout in applications:
import requests
session = requests.Session()
session.proxies = {
'http': 'socks5h://localhost:9050',
'https': 'socks5h://localhost:9050'
}
session.timeout = 30 # Increase timeout
response = session.get('https://exampleonion.onion')
Conclusion
Accessing Tor hidden services safely requires understanding the Tor network’s architecture, using appropriate tools, and following security best practices. Whether you’re using Tor Browser for casual access or building applications with Stem and curl, always verify your connection, use HTTPS when available, and be mindful of potential IP leaks.
For developers, the Tor network provides a unique platform for building privacy-preserving applications. The SOCKS5 interface makes it straightforward to integrate Tor into existing applications, and libraries like Stem offer fine-grained control for more complex use cases.
Related Reading
Built by theluckystrike — More at zovo.one