The following is the GNU All-permissive License as recommended in

Copyright (C) 2024 Free Software Foundation

Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty.

Contributions are welcome. See

Installing a Tor Service on a Trisquel Virtual Machine

[problem] - potential duplicate page

How Onion Services works

Below here is a schema of Onion Services working.

Onion Services overview schema


  1. You want to create an Onion Service. You connect your Onion Service to the Tor network. Your Onion Service establishes a connection through an anonymized circuit (Tor relays) to three introduction points to be reachable. Your Onion Service is hidden and protected itself behind the Tor network.

  2. For a client access to your Onion Service, your Onion Service creates an Onion Service descriptor. This descriptor contains a list of introduction points, next It's signed this with the Onion Service's identity private key. The identity private key used here is the private part of the public key that is encoded in the Onion Service address. Then the Onion Service publishes the descriptor to a distributed hash table (also called Directory) with still an anonymized circuit.

  3. Let's say that the client knows your Onion address. To visit your Onion Service, the client connects to the Tor network with Tor Browser. After the client contact the distributed hash table to get the signed descriptor of your Onion Service to know the three introduction points.

  4. When the client receives the signed descriptor, thanks to the public key embedded in the onion address of your Onion Service, It can verify the signature of the descriptor. It permits to be sure you connect to the real Onion Service and trust the introduction points.

  5. Now the client knows the introduction points to contact your Onion Service, it before determines a Tor relay which becomes a rendez-vous point. Next it sends to the rendez-vous point a secret string called "one-time secret". This secret string will be used later during the meeting between the client and your Onion Service. Then the client sends the rendez-vous point address as well as the secret to your Onion Service through the Tor network and one of three introduction points to ask the Onion Service about this meeting and establish a connection.

  6. When the introduction points receives the rendez-vous point as well the secret string from the client, It passes to your Onion Service and the latter does an all of verifications process to decide if it can trust the client or not.

  7. If your Onion Service trusts the client, It connects to the rendez-vous point via the Tor network and finally It sends the secret string's client to the rendez-vous point. To conclude the rendez-vous point compares the secret string between the client and the Onion Service. If it matches, it creates a connection between the client and your Onion Service and works as a relay. The connection is composed of six relays, three from the Onion Service to the rendez-vous point and three relays where the third is the rendez-vous point for the client.

Install a webserver

Here I outline the steps for setting up Nginx and Apache2. Either is fine.


sudo apt-get install nginx

Nginx stores the website root directory location in /etc/nginx/sites-available/default so change the line

root /var/www/html;

to the path to your website


service nginx start


sudo apt-get install apache2

Apache2 stores the website root directory location in 2 places. In /etc/apache2/sites-available/000-default on line

DocumentRoot /var/www/html

and in /etc/apache2/apache2.conf on line

<Directory /var/www/html>

Change both to the appropriate path, then

service apache2 start

Install Tor

With apt

sudo apt-get install tor

With Ansible

Create a tor group in your inventory file. The default location is /etc/ansible/hosts


Add these lines to your playbook, /etc/ansible/playbook.yml

- hosts: tor
  become: true
  - tor

Put this role in /etc/ansible/roles/tor/tasks/main.yml

- name: "Installing Tor"
  apt: pkg=tor state=installed

Then run

ansible-playbook /etc/ansible/playbook.yml

Configuring Tor

Uncomment these lines in your /etc/tor/torrc:

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

Change the HiddenServiceDir line to a location that is readable/writable by the user.

i.e. /home/username/hidden_service/

tor -f /etc/tor/torrc

Tor will create a private_key and hostname file in the hidden_service director, that's the .onion URL.

Both a clearnet and a onion service of the same site should now be running. If your site has all relative links then your onion service should work as expected.

Converting absolute links to relative links

If your site has absolute links then they will bring you out of tor and into the clearnet. You will have to convert them to relative links.

To convert a single file, run:

sed -i -E -e 's,(http://|https://|http://www.|https://www.|www.),,g' index.html

To convert the files in your entire directory tree, carefully run:

find ./ -type f -exec sed -i -E -e 's,(http://|https://|http://www.|https://www.|www.),,g' {} \;

Secure an Onion Service

To secure your Onion Service as well as your server, you must follow this guide from Tor website. - Basic recommendations, click here. - To secure your server, click here. - To improve the security of your Onion Service with Vanguards, click here. - To scan your Onion Service to find any vulnerabilities, click here.

Moving an Onion Service

To move an Onion Service towards on another machine, just copy the /var/lib/tor/my_website/ directory of the target machine in /var/lib/tor/.

On the old one machine, stop and disable the Tor service.

Make sure the torrc (/etc/tor/torrc) on the new system has the same configuration as the old one.

Ensure that /var/lib/tor/my_website/ directory on the new machine have the right owner (debian-tor).

Then restart the Tor service on the new machine.