Writing mostly about computers and math.


Some onions.

Original image from Thad Zajdowicz on Flickr. Some rights reserved: cc by.

Tor hidden services are useful for protecting privacy, but Tor users still have to rely on exit node operators to pass traffic from the Tor network to the web. Tor hidden services are designed to allow people to share websites with each other without either party revealing too much information about themselves. Another benefit of hidden services is that users can access them without going through an exit node, a weak point in the network's privacy protection and a resource with limited bandwidth.

Obviously setting up a hidden service to allow access to an existing public website doesn't do much to protect your privacy, but it does make it safer and easier for Tor users to access your site and it takes relatively little effort to set up. I'll show you how to do this on Debian, but the steps should be similar for other Unix-like operating systems.

Installing Tor

The Tor Project recommends that you not use the Tor package in the Debian/Ubuntu repos since they're not reliably updated. They maintain a repo with .deb packages you can use instead; instructions for setting it up on Debian unstable are adapted from their website below:

$ echo "deb http://deb.torproject.org/torproject.org stretch main" | sudo tee -a /etc/apt/sources.list.d/tor
$ echo "deb-src http://deb.torproject.org/torproject.org stretch main" | sudo tee -a /etc/apt/sources.list.d/tor
$ gpg --keyserver keys.gnupg.net --recv A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89
$ gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | sudo apt-key add -
$ sudo apt update
$ sudo apt install tor deb.torproject.org-keyring

Configuring the Hidden Service

Once the install finishes, we need to edit the torrc file to enable the hidden service. On Linux, this file is located at /etc/tor/torrc. Around line 70 in this file you should find two lines like this:

HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80

The HiddenServiceDir is where the private key for the hidden service will be stored, so make sure it's somewhere safe. /var/lib/tor/hidden_service is good enough for me, but you can set it to whatever you want. The HiddenServicePort is the port Tor users will use to access your hidden service followed by the actual location of your hidden service. Since we're connecting to an existing web server, we want to use so the web server will accept the connection. If your web server is on a different IP or port then use those values instead but keep the initial 80 the same.

Make sure those lines are uncommented and restart Tor -- it should generate your private key and you'll see your new .onion address in <HiddenServiceDir>/hostname. This address is random but there are ways to get a less random one.

Configuring the Web Server

If your web server just serves all connections on port 80, then great; you're already done. You should be able to access your website using the .onion address shown in your HiddenServiceDir.

If, however, you use something like Apache virtual hosts then you have a little more configuring to do.


Find the config file for your site (/etc/apache2/sites-available/*.conf) and add a new ServerAlias somewhere in the VirtualHost you want to service your .onion address. For example:

<VirtualHost *:80>
    ServerName www.peterbeard.co
    ServerAlias duskgytldkxiuqc6.onion

    DirectoryIndex index.html
    DocumentRoot /var/www/peterbeard.co


You'll need to edit the config file for your site (/etc/nginx/sites-available/*) to add the new hostname to the server block:

server {
    listen 80;
    server_name www.peterbeard.co

    index index.html;
    root /var/www/peterbeard.co;

Anyway, hopefully this helps you set up a .onion address your users can use to find your site. If you want a particular address, check out this other article I wrote about generating a specific .onion address for your hidden service.