/ networking

Setting up TOR and Hosting a Hidden Service

This tutorial will show you how to set up TOR as a daemon and host hidden services. Hidden services are only available on the TOR darknet'and allow you to host services without revealing your IP. TOR hidden services can be accessed via a special .onion domain

Table of contents

  1. Introduction to TOR
  2. Setting up TOR and trying it out
  3. Setting up a Hidden Service
  4. Redirecting all traffic to TOR
  5. Conclusion

Introduction to TOR

Traditionally, TOR is most well known for providing anonymized access to the clear-internet via the TOR-Browser. TOR is also a "darknet" where nodes can communicate anonymously within the TOR network.

TOR to internet communication

TOR connection to clearnet

  • Your traffic is onion-routed to an exit-node/bridge which interfaces with the external internet.
  • The exit-node has no idea of your true source address.
  • Any web sites you visit will see your source-address as that of the exit-node. So it's not truly anonymous in the literal sense, you still have an origin address, it's just not your real address
  • Because these exit-node addresses are well documented, these TOR-to-internet egress points are attractive targets for bulk surveillance. By sniffing the traffic originating from the exit-nodes, you can get some idea of what traffic is coming from TOR users. Through heuristics such as browser-fingerprinting and whatever else the NSA has in its toolkit, you can use what to build a fair idea of who. This is especially true if browsing sites that do not use HTTPS.

TOR Hidden-Services (TOR-to-TOR communication)

A Tor Hidden Service

  • TOR-to-TOR communication is "anonymous per se".
  • Client connections always originate from
  • Server addresses are unique in the range; this is generated (along with the .onion domain) from the private key in the hidden service dir.
  • Warning: TOR hidden services are somewhat infamous for their unlawful use, most notoriously the "Silk Road" marketplace. If using TOR for illegal activity, you can (and most likely will) get tracked down. There are a number ways this can happen, the most common and easiest is sloppy opsec; with harder attacks including exploiting vulnerabilities on the hidden service itself as well as timing analysis,
  • TOR hidden servers have lots of legitimate uses too!
    • Hosting a website involving sensitive but legal content
    • Hosting your SSH server more discretely
    • Hosting services over mobile broadband (or any other situation where you don't have an accessible public ip)

Setting up TOR & Trying It Out

For this tutorial, I'm using a Debian 9 server.

We first install the tor and torsocks packages, and and place the following in /etc/tor/torrc Tor will listen as a SOCKS5 proxy on localhost:9050. We also have a TOR DNS resolver listening on localhost:5353.

To demonstrate TOR connectivity, we do some tests with
curl socks5-hostname

Set up TOR

$ sudo apt-get install -y tor torsocks

$ cat > /etc/tor/torrc
SOCKSPort 9050
TransPort 9040
AutomapHostsOnResolve 1
DNSPort 5353

$ service tor start
$ alias torcurl="curl -s --socks5-hostname"
$ torcurl https://check.torproject.org | grep -A2 "title" | sed -n '3p'
Congratulations. This browser is configured to use Tor.

$ dig propub3r6espa33w.onion @ -p 5353 +short

So TOR appears to be working.

Setting Up a Hidden Service

We have an instance of Nginx listening on, we will publish it as a hidden service on port 80.

First, we create a directory in /var/lib/tor for the hidden service.
When we restart/start tor, two files will be created in this directory:
hostname the TOR .onion domain, based on the public key
private-key the private key (Sensitive!; for production, back this up)

Create & Test Hidden Service

$ cat >> /etc/tor/torrc
HiddenServiceDir /var/lib/tor/nginx
HiddenServicePort 80

$ service tor restart
$ onion_site=$(cat /var/lib/tor/nginx/hostname)

$ torcurl -I http://$onion_site
HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Thu, 01 Feb 2018 14:39:44 GMT
Content-Type: text/html
Content-Length: 1636
Last-Modified: Thu, 01 Feb 2018 14:34:02 GMT
Connection: keep-alive
ETag: "5a73255a-664"
Accept-Ranges: bytes

Websites running as TOR hidden services can also be accessed over the clearnet via the TOR2Web proxy.
Simply substitute .onion with tor2web.io and connect via HTTPS. Warning: This does not provide anonymity for the client.

Redirect all traffic to TOR

Let's look at how to transparently redirect all traffic through TOR on a per-user basis. We create the user tor-test which we will use to test this.

We need two iptables rules. The first redirects any of the users DNS (udp/53) queries to localhost:5353. The second iptables redirects any of the user's outbound tcp traffic that isn't destined to localhost into the TOR transport (localhost:9040)

We can test these are working by comparing the output of running curl https:// check.torproject.org as the user root or tor-test

Force User's Traffic thru TOR

$ redirectusr=tor-test

$ iptables -t nat -A OUTPUT -p udp --dport 53 \
-m owner --uid-owner $redirectusr --jump REDIRECT --to-ports 5353

$ iptables -t nat -A OUTPUT ! --dst -p tcp \
-m owner --uid-owner $redirectusr -m tcp --syn --jump REDIRECT --to-ports 9040

$ curl -s https://check.torproject.org | grep -A2 "title" | sed -n '3p'
Sorry. You are not using Tor.
$ su tor-test -c "curl -s https://check.torproject.org | grep -A2 "title" | sed -n '3p'"
Congratulations. This browser is configured to use Tor


In this tutorial we covered how to the following with the TOR client

  • Access TOR via SOCKS5 Proxy
  • Using the TOR DNS Resolver
  • Host our very first TOR hidden service
  • Transparently Proxy All TCP connections through TOR for a particular user

Hope this was helpful and thank you for reading.