Adding a Tor Hidden Service

Tor (if you're unfamiliar) is a privacy focused network that enables anonymous communication over the Internet.

While it's perfectly possible to browse regular websites over Tor, there are also "hidden services" which are, effectively, websites that remain within the Tor network and so have (arguably) enhanced privacy and security for both visitors and site owners alike.

I've never seriously looked into this, because I assumed it would be far too complicated to work out but it turns out that you can do it pretty easily, albeit with a few caveats.

Note that in all this, I've talked about a "hidden service"; it's also known as an "onion service", and the terms seem to be switched freely!

Grab a VPS

While I'm sure I could have installed this on any existing server, it feels more proper to have a dedicated machine to providing the Tor-Open Web gateway; the processing power required is close to zero, and storage requirements are similarly lilliputian - and you can pick up really cheap small VPSes these days.

A lot of VPS providers have rules against running Tor (especially exits, but often even relays) - we won't be doing either, but if you're the overly-cautious type you might want to use a Tor-friendly provider.

Initial Install

A minimal Linux install will be more than enough; I tend to use Debian because... well, because that's what I always use. If you have a passion for a different distro feel free.

Install Nginx; this is what we will use to handle requests sent to the hidden services, and forward them on to our Open Web websites.

And lastly, install Tor according to whatever distro you've gone for.

Create A Hidden Service

This is as simple as adding two lines to your Tor configuration file (/etc/tor/torrc) and restarting Tor:

HiddenServiceDir /var/lib/tor/my_website/
HiddenServicePort 80 127.0.0.1:80

After Tor is restarted, you'll find /var/lib/tor/my_website/ has been created and populated. Take a backup of the entire directory - if you ever need to relocate this setup to another server, just restore the whole directory and restart Tor, and it will restore everything.

Your new hidden service name is contained in /var/lib/tor/my_website/hostname - take a note of this, because we'll use it to configure Nginx next.

Configure Your Nginx Proxy

Next up, create a new site definition within Nginx - /etc/nginx/sites-available/my_website_proxy.conf; link or copy it into /etc/nginx/sites-enabled/ once you're done, whichever way you usually do it:

server {
  listen 127.0.0.1:80;
  server_name <hidden service name from above>;
  location / {
    proxy_pass https://www.my_website.com;
    proxt_ssl_server_name on;
  }
}

(obviously replace my_website as required).

Restart Nginx, and your hidden service should now be accessible.

Add An Onion Location

The last (optional, but desirable) step is to configure your existing website to inform visitors that there is a hidden service option and there are two ways of doing this.

Ideally, you want to use HTTP headers and most web hosting providers make this possible. In your website's .htaccess file, add:

<IfModule mod_headers.c>
  Header set Onion-Location "http://<hidden service name from above>"
</IfModule mod_headers.c>

This will mean that Tor-capable broswers (the Tor Browser itself, Brave) will let Tor users know, when they visit your site, that there's a hidden service alternative - depending on their setup, it may even automatically direct them to it.

The other option is to add the onion location as a <meta> enty in your websites HTML code, but this isn't always picked up (Brave, for example, seems to ignore it) despite it being in the documentation:

<meta http-equiv="onion-location" content="http://<hidden service name from above" />

Add More Services

You can add as many services as you like; just add new HiddenServiceDir/HiddenServicePort entries, and a new Nginx configuration file, for each new website.

Unless you have particularly high Tor traffic to your sites, even a small VPS can handle a number of hidden services with ease.

Caveats

No HTTPS

The hidden services do not have any HTTPS certificates, not least because so far, free services like Let's Encrypt don't (yet?) support them.

However, Tor traffic is encrypted all the way to the VPS hosting the hidden service, and Nginx proxies out to your HTTPS-supporting Open Web website. The only unencrypted step is between the Tor software and the Nginx proxy, on the same machine. So outside of that gateway, it's still encrypted.

Multiple Services

If you're running multiple hidden services, there is a theoretical risk that users could work out which sites are sharing the same server. It would require a lot of work, and for my use case it's not something that concerns me.

Some sites want to be on Tor to preserve their own anonymity; for me, this is more an exercise is maximising access for users who are keen on anonymity - if they want to know what other websites I run, I make it pretty easy to find out :-)


As proof that all this works, you could be - and indeed may already be - reading this site on s2nj5xro74xv5duyx3fr5vmj4gxruvfizfbziivaffwvyst3tdejvwyd.onion

This page was first published on 12th March, 2024.