Hosting TOR Hidden Services (.onions)
The level of effort required to set up a TOR Hidden Service (known as a .onion) largely relates to the amount of paranoia you need to exercise regarding your anonymity.
Whilst the ins and outs of Operational Security (Op-Sec) are a little too intricate for a single post, this documentation will take you through the steps required to configure a Debian server to host a .onion site with reasonable protections in place.
Pre-Requisites
A Linux server (this documentation is Debian specific)
Aim
Once this tutorial is complete, we'll have configured our server to host a .onion, with minimal logging at the OS level. If you're serious about Op-Sec, you should not be connecting to the server from a location that might identify you.
Our server won't appear to be a web-server to the outside world, with HTTP access only available to Tor users.
Installing The Software
Let's begin by installing the software we'll be using
apt-get install nginx
apt-get install ntpdate tor
service tor stop
Note: We install ntpdate because TOR requires an accurate clock
Configuring Hosting
The example below is for a simple static HTML site. If you're planning on using CGI, then it's an exercise left to the reader. Essentially, aside from a few modifications this step isn't that different to configuring standard clearnet hosting (although there are additional things you can do in the name of Op-Sec).
Create the hosting area for our .onion
mkdir -p /usr/share/nginx/onions/myonion
echo "Hello World" > /usr/share/nginx/onions/myonion/index.html
chown -R debian-tor:debian-tor /usr/share/nginx/onions/myonion
We need to adjust the port that NGinx listens on, and configure it with the correct document root
nano /etc/nginx/sites-available/default
# Remove the existing config and replace with server{ listen 127.0.0.1:9070; root /usr/share/nginx/onions/myonion; index index.html index.html; server_name foo.bar; # We'll amend this later location / { autoindex on; } } # Save and exit (Ctrl-X, Y) nano /etc/nginx/nginx.conf # Locate the http block and add server_tokens off; # Save and exit
Once NGinx has been started, you should be able to test the site using wget
service nginx start
wget --header="Host: foo.bar" http://127.0.0.1:9070/
Configure TOR
The next step is to configure the TOR client and tell it to provide a hidden service
cd /etc/tor
mv torrc torrc-default
nano torrc
# Insert the following
SocksPort 0 # what port to open for local application connections
SocksListenAddress 127.0.0.1 # accept connections only from localhost
RunAsDaemon 1
DataDirectory /var/lib/tor
HiddenServiceDir /var/lib/tor/myonion/
HiddenServicePort 80 127.0.0.1:9070
If we now start TOR, the directory /var/lib/tor/myonion should be created, and two files created within it (including one defining the hostname)
service tor start
cat /var/lib/tor/myonion/hostname
The hostname of your new .onion should be output, so go back and amend the server name directive in the NGinx config file and then reload NGinx
Note: The second file within that directory is private_key. Keep it very, very safe!
Making it all start at boot
Making the services start at boot is as simple as
update-rc.d nginx defaults
update-rc.d tor defaults
Basic Op-Sec Precautions
Obviously, the appropriate Op-Sec precautions will vary by use-case, but at the very least we want to be ensuring the security of the server and reducing the availability of things like bash history.
First lets configure fail2ban.
apt-get install fail2ban
cat << EOM > /etc/fail2ban/jail.local
[ssh]
enabled = true
maxretry = 3
banaction = iptables-allports
[ssh-ddos]
enabled = true
maxretry = 3
EOM
service fail2ban restart
update-rc.d fail2ban defaults
Disable BASH History
echo 'alias exit="kill -9 $$"' >> /etc/profile
source /etc/profile
You should also consider disabling firewall rules, and it would also be wise to consider ensuring that all egress occurs via TOR to reduce the potential effectiveness of side-channel attacks
Conclusion
Hopefully this documentation has served as a useful introduction to setting up a basic .onion, though the level of op-sec used is very basic so it should be considered nothing more than a primer!
There are a couple of extra points which should also be considered
- Never configure Tor to both host .onions and be a TOR relay - it allows for easy downtime comparison between your .onion and the publicly available relay information
- Avoid running multiple .onions on the same server - if downtime occurs (especially if regularly), it may be possible to ascertain that those onions are run (or at least hosted) by the same person
If you're planning on hosting something more complex than a static HTML site, pay close attention to the error messages and headers that it generates - anything containing your IP needs to be removed/disabled/changed.
It's also worth noting that NGinx includes a Client-Peer response header, which appears to contain the IP of the server. However, when the request arrives over TOR, the value of that header will be whatever IP TOR DNS mapped the hidden service to. You can verify this by requesting via TOR with GET:
GET -Sse http://alfk3ti4ld3fq4hj.onion
GET http://alfk3ti4ld3fq4hj.onion --> 200 OK
Connection: close
Date: Sat, 18 Oct 2014 16:05:13 GMT
Accept-Ranges: bytes
Server: nginx
Content-Length: 12
Content-Type: text/html
Last-Modified: Sat, 18 Oct 2014 15:53:54 GMT
Client-Date: Sat, 18 Oct 2014 16:05:41 GMT
Client-Peer: 10.228.101.53:80
Client-Response-Num: 1
From the beginning though, your primary concern should always be Op-Sec. TOR is a useful tool for anonymity, but it's not a panacea, high-profile takedowns (and arrests) do happen in relation to Hidden Services. For examples, see the take down of Silk Road, Silk Road 2.0, DoxBin and various other examples. If the .onion you're planning to run is anything more than a small personal site, give it serious thought before setting anything live!
Related Reading: