Setting up your WordPress blog as a Tor Hidden Service

This blog is now also available at http://bgaxaar7xx6dpptt.onion/, in other words, as a Tor Hidden Service (or location-hidden service, as the Tor Project itself calls it). It was surprisingly easy to set it up like this, and I thought I’d explain what I did.
First, however, let me make it clear that the location of this blog isn’t hidden. The Tor and non-Tor version run on the same server, which is hosted on a VPS at Bitfolk. There are a number of reasons why I decided to set it up like this as well, one of which is that it’s fun to do so. However, I believe it also helps support Tor in general and hidden services in particular — just like Facebook setting up a hidden service at their not-too-hidden servers did. Anonymity needs friends and by accessing this blog through Tor, you can be such a friend.
In what follows, I will assume that you are interested in setting things up for the same reasons. If you actually have something you really want hide from a powerful adversary, you should do some proper research and not just copy and paste things from a blog like mine. And at the very least, you shouldn’t run a non-Tor version of the blog on the same server.
I will also assume that you are running your WordPress site on a Linux server that you fully control, that the server runs Apache and that you aren’t afraid of the Linux command line. And I will assume that you have already installed Tor, which on most Linux distributions is trivial.

  1. Configure your hidden service
    (See here for a slightly more detailed version of the first two points.)
    Tor comes with a configuration file, which is probably called /etc/tor/torrc. Open this file in a text editor and look for the bit that says
    ############### This section is just for location-hidden services ###
    a few lines below, you should see see lines like
    # HiddenServiceDir /var/lib/tor/hidden_service/
    # HiddenServicePort 80

    Uncomment these two lines, by removing the # in front of them.
  2. Restart Tor
    You do this by running something like
    service tor restart
    You can now access your site as a Tor Hidden service. To find its .onion address, go to the directory /var/lib/tor/hidden_service/ configured above and look for the file hostname inside it.
    (If you don’t like the hostname, remove the whole directory, restart Tor and repeat until you’ve got one you like. The hostname some kind of hash of the randomly generated private key, so you can’t control it and you’re unlikely going to have the resources to repeat this until you’ve got something you really like.)
  3. Configure Apache
    Depending on how you have configured Apache, accessing your blog using the .onion address may redirect you to the default web server, outside of Tor. That’s not what you want, so you need to add a virtual server to your Apache settings.
    Apache changes its structure every few years, but in my case (I’m running Apache 2.4.10 on Debian Linux) I had to edit /etc/apache2/sites-enabled/000-default.conf. In this file, look for a block starting with <VirtualHost that defines your current WordPress site. Just copy this block, paste it into the same file and substitute your .onion domain for the one of your blog.
    In my case, the new block looked like this:

    <VirtualHost *:80>
    ServerName bgaxaar7xx6dpptt.onion
    ServerAdmin youremail@address
    DocumentRoot /var/www/lapsedordinary
    <Directory />
    Options FollowSymLinks
    AllowOverride None
    <Directory /var/www/lapsedordinary>
    Options FollowSymLinks
    # Options -Indexes FollowSymLinks
    AllowOverride All
    Order allow,deny
    allow from all
    ErrorLog ${APACHE_LOG_DIR}/tor_lapsedordinary_error.log
    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn
    CustomLog ${APACHE_LOG_DIR}/tor_lapsedordinary_access.log combined

    (Note that I created separate log files for people accessing my blog via the .onion domain. If you do so, you can see how many people access your blog this way and what pages they access. You don’t have to though.)
    Finally, restart Apache (service apache2 restart in my case).
  4. Set up the Domain Mirror plugin
    Now your blog should be accessible using the .onion domain. However, internal links will probably go to the domain you’ve set up in the WordPress settings. To let it work with both domains, you’ll need a plugin, of which there are a few. For me, the Domain Mirror plugin worked well (though I had to rename the installation directory). Once installed, it’s really easy to set up. Now internal links for those accessing your blog as a Tor hidden service should point to the .onion domain as well.

That’s all.
You will notice that, while I run HTTPS by default on the non-Tor version of the blog, the Tor version uses plain HTTP. That’s not a problem though: connections to hidden services are encrypted by design. One can get a certificate for a .onion domain (Facebook has one) but that’s just to get the Green lock in your browser’s address bar, which is something for people to look for before they enter their credentials.