How to migrate a Tor Onion Service

How to migrate a Tor Onion Service from one service to another. There are a few unique pitfalls beyond a normal server migration for "clearnet" sites.

A few weeks ago, I created my first Onion Service (previously called a Hidden Service). I spun up a Google Cloud instance and got one running in just under an hour. Now, in the spirit of privacy, I want to transfer my Onion Service off big tech servers and onto a computer running on my home network.

Today, I will walk through how to migrate a Tor Onion Service from one server to another.

Migrating sites in general is an annoying task, and my example will work with a simple static file-only website. If you have to move a production application, including dynamic content, databases, and uptime SLAs... I hope you have some infrastructure engineers to help.

For Tor Onion Services, the swap isn't as easy as migrating servers for clear net sites. Without a load balancer or proxy, which is unrealistic for most dark net use cases, there needs to be downtime. Ownership over an Onion URL is not managed via a DNS server; you need to transfer the cryptographic keys from one server to the other to maintain ownership over your dark net domain name.

My setup

My Google Cloud and home server are running Debian 11 and serving a static website with Nginx.

Backup your existing server

Tor

Depending on your configuration, you may have your Tor configuration files and website data files in various locations. For a default installation of an Onion Service on Debian 11, the following directories are the ones of interest:

  • Tor configuration file: /etc/tor/torrc (file)
  • Tor data files: /var/lib/tor/ (directory)

You'll need to backup these files to use on your new server.

Nginx

Nginx configurations are much more standard, so you can reliably look in /etc/nginx/sites-available/ for your site's configuration. In my case, I am saving /etc/nginx/sites-available/mikeross.onion.

In my case, I have a very simple configuration that would be easy enough to retype if it weren't for the crazy long onion URL.

server {
    listen 8080;
    server_name 5lbxsec563zko6qtco5tez2ow7vchzhktjtuzmkrrf46vn767x4jj4id.onion;
    root /home/mike/www;
    index index.html;
}

Website data

I'm hosting an Onion Service with static file content, sitting in my home directory (probably not best practice) at /home/mike/www. Check your web server configuration file if you are unsure where your website data is stored.

Setup your new server

While the ordering is not strictly necessary, you can safely follow the process in reverse to restore your website.

Transfer your website data

Copy your static website files into the same directory or a different location on the new server.

In my case, I moved my static content into a more widely-used directory and put it under /srv/mikeross.onion.

Install & configure Nginx

As one of the world's most used web servers, Nginx gets us up and running quickly once installed.

1. Install nginx

Run sudo apt install nginx

2. Copy your saved site configuration

Copy your saved configuration file to /etc/nginx/sites-available/. For example, /etc/nginx/sites-available/yoursite.onion.

3. Create a symbolic link to enable the service

Run sudo ln -s /etc/nginx/sites-available/yoursite.onion /etc/nginx/sites-enabled/yoursite.onion

4. (Optional) Update your website data directory

You need to tell Nginx about the updated directory if you copied your website data files to a different location on the new server.

Since I copied my website data into a better location this time, I'll update the root line.

server {
    listen 8080;
    server_name 5lbxsec563zko6qtco5tez2ow7vchzhktjtuzmkrrf46vn767x4jj4id.onion;
    root /srv/mikeross.onion;
    index index.html;
}

5. Restart Nginx for changes to take effect

Run sudo systemctl restart nginx

Install & configure Tor

Up to now, the rest of the tutorial was basically "how to migrate between web servers". The critical steps are ensuring that your Tor Onion Service is configured to serve your site at the same Onion URL.

1. Install Tor

Following the steps from the Tor Project itself, install and configure Tor on your new machine: https://community.torproject.org/onion-services/setup/install/.

2. Stop the Tor service on the new server

We want to update the configuration files on the new server. We must stop the service, make the changes, and re-start for them to take effect.

sudo systemctl stop tor

3. Overwrite the Tor configuration files

Using your saved Tor configuration files, copy:

  • The saved torrc to /etc/tor/torrc
  • The saved site configuration directory (e.g. mike_ross_onion) from /var/lib/tor to the same location on the new server. In my case,  the folder contained files hostname, hs_ed25519_public_key, and hs_ed25519_secret_key.

4. Stop the Tor service on the old server

You can't serve the same Tor Onion Service from two servers at once. We are about to switch over to the new server, so we deactivate the first server's Tor service right before the switch to minimize downtime.

sudo systemctl stop tor

5. Start Tor service on the new server

On the new server, we should start our Tor Onion Service and the configuration should serve the site at the same Onion Service URL.

sudo systemctl start tor

Voila! That's it! For proof that this tutorial works, check out my migrated site at http://5lbxsec563zko6qtco5tez2ow7vchzhktjtuzmkrrf46vn767x4jj4id.onion/ (use Tor Browser). Proudly hosted... somewhere 🧅

Troubleshooting

Sometimes all you need to do is wait...

After completing the guide and trying to test in Tor Browser, I received the following error:

After doing a hard refresh of the server a few times, about 30 seconds later, the Onion Service appeared and was served from my new server! I made a small change to the index.html file on the new server to make sure the switchover actually happened.

File permissions matter!

One other pitfall that I ran into was that I didn't check the file permissions of the Tor configuration files that I copied to my new server. I was using root user when transfering files, so the owner was root.

Once you transfer your configuration files, verify that your /var/lib/tor folder has all files owned by debian-tor user.

If you don't do this (like me), then you'll receive the same "Onionsite has disconnected" error and nothing else, which is a really confusing thing to resolve!