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:

  1. Launch Tor Browser
  2. Type the .onion address directly into the address bar
  3. The browser will connect through the Tor network

Tor Browser includes several privacy features:

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.

Built by theluckystrike — More at zovo.one