Apr 2, 2023

Double TuTORial: Setting Up a Non-Exit Relay and Adding an Onion Address to Your Website

How does onion routing work? What's the point of an onion address for a clearnet website? How do I run a non-exit node? Why shouldn't I run an exit note? These questions and more, answered.

The Onion Network - aka Tor - is a great tool for privacy and security. And the more people who use it and participate in it, the better it is at providing those things.

In this post I will teach you how you can do that while at the same time providing extra privacy for visitors to your website by providing an onion URL for it.

You might be asking what the point is if you run your site through a regular domain already. After all, people can put a normal clearnet URL into the Tor Browser already, right?

Yes, they can, but visiting a Tor hidden service is still a lot more secure than using Tor to access "clearnet" URLs. This is true even if you are running a normal website accessible over the regular internet.

I'll explain why, along with how to set your site to redirect to the onion service if someone using Tor visits the normal URL, and how you can help out the decentralised Tor network stay decentralised and secure by running a "middle relay."

As luck would have it, the explanation for why the onion URL increases privacy for your users and what a middle relay is are connected, so I'll start off there.

Only as strong as your weakest point: the problem with exit nodes

When you access Tor, your traffic is bounced around between at least three nodes. Each performs a different function and, vitally, exit nodes present the greatest risks to both those who run them and those who use them. If you cut out exit nodes entirely, you are increasing your OPSEC on Tor significantly.

But why? It's actually pretty simple.

When you fire up the Tor Browser it makes the first connection through a guard relay, also known as an entry node. This is your first "hop" on the circuit. Whenever you connect to Tor, the first relay you connect to is always a guard relay, which is why I prefer the entry node terminology.

A guard/entry relay is not actually a separate type of node, but rather just a middle relay that's been around long enough to have built up a good reputation as being fast and reliable for a reasonable amount of time as measured by the consensus protocol. The longer your relay has been active and stable, the more likely it is to get chosen by clients as an entry node.

A middle relay is one that routes traffic between the entry and the next hop, which could be another middle relay, an exit node, or an onion service. Because all traffic inside Tor is end-to-end encrypted, neither the entry or middle relays can see the contents of your traffic.

Finally there are exit nodes. There are separate from entry and middle relays, as most Tor relays are not exit nodes. This is because while the main risks of running an entry/middle node are mere inconveniences, opting to act as an exit node comes with serious legal risk.

The importance of hidden services even for clearnet sites, and the importance of not running an exit node

If you typed a normal URL like, say, stacker.news, your traffic must be routed through an exit node. Because the traffic is now exiting Tor and being routed to the clearnet, it is decrypted by the exit node. This means the exit node is able to view all that decrypted traffic and monitor it. Of course, as its aim is providing as close to anonymity as is possible, Tor doesn't exactly include logging software on exit nodes, but the Tor Project also can't really do much to stop malicious exit node operators using third party tools to sniff traffic passing through their own machines.

At the same time, honest exit node operators are taking a big risk. The Tor Project itself warns of these risks and advises against individuals running exit nodes without first forming an organisation such as a limited liability company and hiring a lawyer, and even then, they explicitly warn against running exit nodes from personal internet connections. This is because if a Tor user was routed through a certain exit node while engaging in illicit activity, for example hacking, guess which IP address is going to be found in the logs? Yes, the exit node. And even though there is a public directory of all Tor relays that includes whether or not one hosted at any given IP address is an exit node, the feds are still gonna bust down your door before anyone else's.

The use of exit nodes, then, is not ideal for either party and is more of a necessary evil than an ideal solution.

Enter hidden services

The above is what happens if you enter a regular clearnet domain. What happens if you instead type an onion address?

Continuing the previous example, here's the onion address for stacker.news:

snsnsnya6h3ot563f3p566wuhfoklkg5f62hokdlaqzcaub3gf4xlxyd.onion

Paste that into the Tor Browser and the first steps are the same - your traffic is still routed through entry and middle relays - but this time instead of being decrypted by an exit node, the traffic is fully end-to-end encrypted as it is all routed through Tor. This means it is only decrypted once it reaches the server of the site you are visiting. Naturally, because this connection happens inside Tor, the server doesn't know your IP address and you don't know theirs.

As for the Tor relays, as I have mentioned, the entry and middle routes only pass through encrypted traffic. They do not need to decrypt the traffic and therefore don't have any access to the keys required to do so. This is the magic of end-to-end encryption. A connection is established between two parties (in this case, yourself and the server) and only those two parties have the keys to decrypt the data. The route responsible for transmissing the data can't see it. This includes your own ISP - all they can see is you are connected to Tor, not what you are doing within it.

As you can see, when visiting an onion address, the circuit pings through multiple relays but doesn't require an exit node as the circuit ends at the destination within the Tor network.

At no point is an exit node required to be part of the circuit between the client (your computer) and a hidden service (the server of the onion URL you're accessing). This is not the case if you enter a regular domain name.

TL;DR! What does this mean for me?

As the owner of a website, you provide your visitors with much more private access through Tor if you provide both a clearnet domain and a Tor hidden service onion URL.

As the runner of a Tor relay, you can run a non-exit node with very low risk. If you have a lot of unused bandwidth on an existing VPS, you can even put it to use by running one on your existing server. It's easy and quick to do.

I won't focus on running a non-exit Tor relay from your local network here because, although you can do it, dynamic IP addresses can cause issues with reliability, you may notice your bandwidth getting bogged down especially during peak times, your ISP might throttle you, and various websites will likely start blocking your IP address. If you know what you are doing and can mitigate these risks, you probably don't need this tutorial anyway. For everyone else, I'll leave complex home networking setups for another day.

Bonus: Tor hidden services allow you to easily and privately host a website, Bitcoin node, or other publicly accessible service without exposing your IP address or opening ports

While I recommend against running a relay from your home network, a cool thing you can do with Tor hidden services is use them to host something you can access remotely from a physical computer within your home network without exposing your IP address, forwarding any ports, or messing with your firewall. Tor is able to traverse NAT, provide a persistant domain without setting up reverse DNS, and provide anonymity all at the same time, making it much easier and safer to run a website, Bitcoin node, or whatever else directly from your home network.

Note that in order for this to stay private, you need to ensure the your machine is exposed to the outside world only through Tor, i.e. it has to act as a "darknet" website. Don't let the negative connotations put you off - this simply means something is only accessible via Tor rather than the regular internet.

You can even use a reverse proxy or a Cloudflare tunnel to make your home server accessible on the clearnet while still keeping your home network private, but that's a topic that deserves its own post. If you run a Bitcoin node through Umbrel or something similar, you are likely already using an Onion address to access your node remotely without opening your home network.

First step for both: installing Tor on the VPS

This is really quite simple. I am assuming you have a VPS running and are familiar with SSH and Linux. That's all that is required.

So, first we SSH into your VPS and install the Tor packages.

Firstly you make sure you have the package required to use repos that use HTTPS:

sudo apt install apt-transport-https

Now just check the codename for the Linux OS running on your system:

lsb_release -c

Keep a mental note of it for the next bit.

Here we create the repo on the VPS:

sudo nano /etc/apt/sources.list.d/tor.list

Now you just paste the repo details in, making sure to substitute jammy (the latest Ubuntu LTS at the time of writing) with the version running on your own VPS. Unless it's actually jammy in which case you can just copy and paste the below exactly as they are:

deb     [signed-by=/usr/share/keyrings/tor-archive-keyring.gpg] https://deb.torproject.org/torproject.org jammy main
deb-src [signed-by=/usr/share/keyrings/tor-archive-keyring.gpg] https://deb.torproject.org/torproject.org jammy main

Save and exit then add the PGP key to your keyring by running this:

wget -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --dearmor | sudo tee /usr/share/keyrings/tor-archive-keyring.gpg >/dev/null

Now we just install the Tor packages:

sudo apt update
sudo apt install tor deb.torproject.org-keyring

In the next portion we move on to running a non-exit Tor relay, then we go through setting up an onion service. You can do just one of these or you can do both. Up to you!

How to set up a non-exit Tor relay

Fire up the Tor config file:

sudo nano /etc/tor/torrc

Now either uncomment or paste in the following lines:

SocksPort   0
ORPort 443
RunAsDaemon 1
Nickname lettersandd1g1ts0nly
ExitPolicy reject *:*
ExitRelay   0

These six short lines are all that is required to configure Tor as a non-exit relay.

By default, your host's reverse DNS will show up under the public Tor relay directory. If you wish to display a domain there instead, you can make a subdomain of one you own and point the A and AAAA records at your VPS. Or you can just register one cheaply. If you do register a domain, uncomment or paste this in the torrc file too:

Address adomain.thatyouown.tld

You don't need to configure a reverse proxy here unless you wish to serve a website through that same domain or subdomain. Even if you already run a website from that VPS, there won't be any clashes as Tor itself uses SOCKS natively, not HTTP, so it won't "fight" with your existing server for the port.

If you have limited bandwidth on your VPS, you can throttle the connection by speed:

RelayBandwidthRate 100 KB  # Throttle traffic to 100KB/s (800Kbps)
RelayBandwidthBurst 200 KB # But allow bursts up to 200KB/s (1600Kbps)

And/or by amount of data used during the day:

AccountingMax 4 GB
AccountingStart day 00:00

Or per month:

AccountingStart month 3 15:00

If you're happy with how it's all set up, you can get it going by restarting the systemd service:

sudo systemctl restart tor

Verify it's working by checking the logs:

sudo journalctl -xeu tor

Finally, if you want to add some extra protections against potential DDoS attacks on the Tor network affecting your VPS, you can install this set of scripts and configure them to your liking by following the directions in the repo.

Keep in mind, there is a basic level of DDoS protection built into Tor already, but it is based on simple methods like rate limiting. The scripts are dynamically updated with a list of specific IP addresses to block if a DDoS attack has actually been been detected.

How to add an onion service to your existing website

Fire up the Tor config file:

sudo nano /etc/tor/torrc

To start off with, I'm going to run through the standard instructions which assume you do not care about having a vanity onion URL. DuckDuckGo has a perfect example of a vanity onion address:

duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion

Notice how the the address begins neatly with duckduckgo.

I'll explain how these work in a minute, but first let's go through the normal process where your onion is randomly generated.

Now either uncomment or paste in the following lines:

RunAsDaemon 1
DataDirectory /var/lib/tor
HiddenServiceDir /var/lib/tor/onion_service/
HiddenServicePort 80 127.0.0.1:80
HiddenServicePort 80 unix:/var/run/tor-my-website.sock

Restart Tor:

sudo systemctl restart tor

If it all worked, you should see a randomly generated onion address when you run this:

cat /var/lib/tor/onion_service/hostname

Copy the output then we just need to add it to your webserver config. For the sake of this tutorial I'll assume you're using Nginx, so just open up your vhost:

cd /etc/nginx/sites-enabled
sudo nano [your vhost]

Now copy the main server block only, ignoring any that exist only to redirect to HTTPS etc, go right down to the bottom of the vhost and paste it.

Remove anything to do with SSL/TLS/HTTPS as it's not needed for Tor. Change to port 80 or use the unix sock we created in the Tor config. Make sure you change the server name to the onion address.

The end result should be something like this:

server {
	# Listen on port 80 over 1pv4
	listen 80;
	# Listen on port 80 over ipv6
	listen [::]:80;
	# Or listen for the SOCKS proxy
	listen unix:/var/run/tor-my-website.sock;
	# Stick your onion address here
	server_name yourlongonionaddresshere.onion;

	# Blah blah blah your config
	# Remember to remove any SSL/TLS/HTTPS lines	
}

If you wish to make the regular site redirect to the onion address when some visits through Tor, go to the main server block (not the Tor one) and add this new header:

add_header Onion-Location yourlongonionaddresshere.onion;

One more step to make sure we don't get any errors because the onion address is an unusually long hostname. Save and exit the vhost config then open up nginx.conf:

sudo nano /etc/nginx/nginx.conf

Go to the top of the http block and add this inside:

server_names_hash_bucket_size 128;

Save, close, then restart Nginx:

sudo systemctl restart nginx

Now you can open up Tor Browser and paste your onion address in there. Keep in mind it can take a few minutes for a new onion address to propegate across Tor, so if it doesn't work straight away don't worry just yet!

How to add a vanity onion address

That's all well and good, you might be saying, but I want a custom onion address like the cool kids. Where do I get one of those?

As you can probably tell already, an onion address is not a domain name in the traditional sense. There's nowhere to go and register and buy them.

Instead, a v3 onion address is actually an Ed25519 keypair. The address is a base32 encoded version of the public key.

So in order to get a custom one you use this tool to bruteforce a load of keypairs and filter for the ones that match the pattern you enter in their base32 encoded form. The only restriction is the names cannot include the digits 0, 1, 8, or 9 as these are not valid in base32.

Since this is bruteforce work, shorter filters are faster. There is a page on optimising the performance which is worth reading, because some non-default settings can greatly increase speed. But I have found pretty consistently that anything five characters or less will be virtually instant, whereas anything over will likely be significantly slower.

To state the obvious, unless you have a really good VPS, you should do this on your local machine else it could take ages on an average $5 VPS.

Compiling on a Linux system is easy:

sudo apt install gcc libc6-dev libsodium-dev make autoconf
./autogen.sh
./configure
make

Once you compile the program you can run it like this:

mkdir output
./mkp224o test -d output

Where test is the string you want your onion to start off with and output is the directory the successfully generated addresses along with their keypairs will be stored.

Once you have found one you like, you can stop the program, go to the folder for the one you like, upload the three files via sftp, make sure they're in the same directory, then move that directory to the folder Tor expects:

sudo mv -r output /var/lib/tor/myonion

The myonion folder can be called whatever, but make sure it contains the three files from the generated keypair you liked and it's in /var/lib/tor.

You will find Tor will fail to load unless you set the correct permissions, so make sure you do that once they're in the right place on your VPS:

sudo chmod -R u+rwX,og-rwx /var/lib/tor/myonion
sudo chown -R debian-tor /var/lib/tor/myonion

Now just open up the Tor config again:

sudo nano /etc/tor/torrc

And change the onion_service directory to the new one:

HiddenServiceDir /var/lib/tor/myonion/

Reatart Tor:

sudo systemctl restart tor

Again you may have to wait a few minutes for the new onion to propegate, then it should work in the Tor Browser.

That's all folks!

In this tuTORial you've learned:

  • The basic structure of onion routing
  • Why an onion address is useful even for a clearnet site
  • The difference between an exit and non-exit relay
  • How to set up a non-exit relay
  • How to set up a hidden service
  • How to create a custom onion address
  • How to redirect a clearnet site to an onion site

Future posts will go over further topics such as using Tor to self-host everything from websites to Bitcoin and Lightning nodes from your own machine and internet connection without opening ports and exposing your IP address. If you are intimidated by the terminal you need not worry as multiple automated user interfaces exist to sort all the details out for you.

If you liked this post and want more you can follow me on Nostr.

My NIP-05 is xanny@nostr.xanny.family.

Here is a link via Snort.social and here is my npub:

npub17rlc0emedw5xljztfqrmykjaacsx6ujvdas64zznjadrnhhwlavq4jjtgg

If you're feeling generous enough to zap some sats you can do so via Nostr or by using this link or the lightning address xanny@xanny.family - thank you for reading this far! PV!