There’s a new way to browse our website more securely and anonymously. To do it, you’ll need a bit of software called the Tor Browser. Once you’ve got it installed, copy and paste this URL into the running Tor browser:
This .onion URL is called a “Tor hidden service.” Tor is a network of internet relays (and a web browser that uses the network) that protects your privacy by hiding your browsing habits from your internet service provider, and hiding your IP address from the websites you visit. A Tor hidden service is a special type of website that can only be visited with Tor, masking your digital trail as much as possible (Disclosure: Outside of my work at ProPublica, I’m also the developer of Onion Browser, an unofficial Tor Browser for iOS.)
We launched this in part because we do a lot of reporting, writing, and coding about issues like media censorship, digital privacy and surveillance, and breaches of private medical information. Readers use our interactive databases to see data that reveals a lot about themselves, such as whether their doctor receives payments from drug companies. Our readers should never need to worry that somebody else is watching what they’re doing on our site. So we made our site available as a Tor hidden service to give readers a way to browse our site while leaving behind less of a digital trail.
We actually launched it quietly as an experiment last year, shortly after publishing Inside the Firewall, an interactive news application about online media censorship in China. While we’re not aware of any countries currently blocking access to ProPublica, I was curious to see what we could do to improve access to readers if that ever happens.
About Tor & Hidden Services
A Tor hidden service (sometimes called an “onion site” or an “onion service”) has a special domain name that ends in
.onion – like
p53lf57qovyuvwsc6xnrppyply3vtqm7l6pcobkmyqsiofyeznfu5uqd.onion – that you can only connect to using Tor. These special websites and services use strong encryption (even if the URL doesn’t start with https), mask metadata like the IP address of the user, and even mask the address of the site they’re visiting.
Collectively, sites like these are often referred to as being part of the “dark web” though the term is contentious in the Tor developer community, thanks to its association with sites like Silk Road, an illicit online drug market that was seized by the FBI in 2013. But regardless of how it’s misused, the dark web has legitimate and even critical utility in keeping the Internet safe and private:
ProPublica and several other journalism and human rights organizations use SecureDrop to allow sources and whistleblowers to safely transmit sensitive files.
The email hosting service Riseup uses onion services to allow users to access their email ultra-securely.
The chat program Ricochet uses onion services under the hood to allow users to securely chat with each other without relying on any central servers.
Facebook launched an onion site in 2014 to improve access to Facebook over Tor, with an eye toward privacy-conscious users and those in countries where Facebook is blocked.
How is a Hidden Service Different?
You are probably already used to using a secure browser when browsing many sites, especially when banking or shopping. Your web browser lets you know when a site uses “HTTPS” by displaying a lock in the address bar. How is a Tor hidden service different, and why is it more secure than HTTPS?
When you’re on a site that uses HTTPS encryption, the connection between your web browser and the site is secure, but important metadata is still visible to servers that can observe your connection, like your ISP or the wifi router you use at a coffee shop. Those can know, for instance, what sites you visit, and can see any unencrypted images and scripts that get loaded in your browser.
Browsing Normal Sites Using Tor
Tor provides some anonymity by relaying traffic through different servers as you browse. This makes it seem to a web server that you are coming from somewhere else. Tor picks three random relays and routes your traffic through each. No relay gets the “whole picture” (that you are visiting propublica.org), because Tor encrypts your connection three times before sending it out: the first layer can only be decoded by the first relay, the second layer can only be decoded by the second, and so on.
Think of this way of layering encryption through relays as like the layers of an onion. Hence the name “Tor,” which was originally an acronym for “the onion router.” Though the longer name has fallen out of use, the onion metaphor is still pretty common when discussing Tor and software that uses it.
When you’re browsing using a Tor browser, your ISP only knows you are using Tor, not what sites you’re visiting or what you’re doing, even when you’re connecting to a non-HTTPS site. The first relay knows your actual IP address and ISP, and knows the address of the second relay. The second relay knows about the first relay and third relay but can’t unencrypt your data to see what you’re doing. The third relay (or “exit relay”) knows about the second relay and the site you are going to, and it can see any unencrypted data that you’re browsing. It’s possible for the sites you visit to know that you’re using Tor because the list of exit nodes is openly known, but they have no way of knowing your real IP address.
Although the exit relay that sends your Tor connection to the normal internet does not know your IP address (since your connection was forwarded to it by another relay), it has access to your metadata, like which sites you are visiting, and unencrypted data because it needs to know how to pass your request on to a desired website.
Browsing Onion Sites Using Tor
An onion site uses the encrypted and anonymous Tor connection from your computer all the way to the websites you visit. Just as before, Tor picks three random relays, but in this case, a copy of Tor we’re running also picks three random relays and the relays meet in the middle.
Your ISP knows you are using Tor. As before, the first relay knows that you are a Tor user, knows your IP address and ISP, and knows the address of the second relay. The chain of relays, which know only the connections before and after them, continue as before except now there are six of them.
As in normal Tor use, none of the relays between a user and the website see the “whole picture”. But the onion site connection never has to leave those confines to connect to the normal Internet, which exposes metadata. To a relay, both a user and our website look like normal Tor clients, and no relay knows any more than that.
How to Run Your Own Hidden Service
If you run a website and want to run a Tor hidden service, here’s how. I’ll assume from here on out that you’ve got a fair bit of technical knowledge and understand how to run a web server, use the command line and edit configuration files. The Windows command-line “expert” version of Tor is a bit finicky and I don’t have a lot of experience using it, so for now, these instructions will be Mac OS X and Linux-specific. (Are you a Windows Tor expert and interested in helping me write Windows-specific sections of these docs? Please get in touch!)
The following instructions will help you set up a demonstration onion site on your own computer. For a production site, there are a few other things you’ll want to consider that I’ll discuss toward the end.
Step 1: Install Tor
First, you’ll want to install a command-line version of Tor.
The easiest way to do this is to use your package manager to install Tor — Homebrew on Mac,
yum or whichever manager you use on Linux. The invocation is usually something like
brew install tor or
apt-get install tor.
If you’re on Mac OS X, you will be prompted to optionally run several commands to
have launchd start tor at login, after installing. You can skip this for now.
Step 2: Configure a Tor Hidden Service
Once installed, edit Tor’s configuration file. For OS X Homebrew, you’ll want to create the file at
/usr/local/etc/tor/torrc. For Linux, you’ll generally find that the configuration already exists at
/etc/tor/torrc. Open that in your code editor of choice.
Add two lines like this:
HiddenServiceDir /tmp/test-onion-config HiddenServicePort 80 127.0.0.1:3000
HiddenServiceDir: The directory containing
test-onion-configneeds to exist and needs to be owned by the user running Tor. On Mac OS X, Homebrew will install & launch Tor as your current user, so using
/tmp/is fine (since this is just a test demonstration). If you wish to configure an onion site in OS X that won’t disappear when rebooting, you can use something in your home directory, like
/Users/. On a Linux machine, you can use something like
/var/run/tor/test-onion-config; in Ubuntu,
/var/run/toris already owned by the
debian-toruser that runs the Tor daemon.
HiddenServicePort: This routes the inbound port at the
xxxxxxxxxxxxxxxx.onionto an IP address and port of your choice. (It should be an IP address and it’s recommended that this route to the local machine. It can also be a Unix socket on the local filesystem.) In the
HiddenServicePort 80 127.0.0.1:3000example, a user accessing your http://xxxxxxxxxxxxxxxx.onion/ (implied port 80) would serve the web app running at port 3000 on your computer.
Unless your underlying website uses some authentication, a Tor hidden service configured like this will be readable by anybody who knows the address. So if you don’t want to test this with a web app you already have on your computer, you can create a simple test by doing:
$ mkdir /tmp/test-onion-content $ cd /tmp/test-onion-content $ python -m SimpleHTTPServer 3000
This will serve the contents of
127.0.0.1:3000, and also at the onion site address being configured.
(You can check out the Tor manual for more information about torrc config lines.)
Step 3: Access the Tor hidden service
If you aren’t running your test app on port 3000 (or whichever you chose) yet, do that now. Then start (or restart) Tor:
On Mac OS X, just run tor in a terminal window. If you previously installed Tor with Homebrew and followed the steps to copy plist files to
have launchd start tor at login, you can run the following to restart it:
$ launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.tor.plist $ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.tor.plist
Depending on your flavor of Linux, you’ll need to do one of the following (or something similar):
$ sudo service tor restart # or $ sudo systemctl restart tor.service
If all went well, Tor should be running. (If running on the terminal, you’ll see
Bootstrapped 100%: Done at some point. Otherwise, you can usually see the status by looking at the Tor log file —
/var/log/tor/log, depending on your flavor of Linux.)
Now you’ll find that the
/tmp/test-onion-config) has been created.
Inside that directory, you’ll see two files:
If you open the
hostname file, you will see that it contains an
.onion address. If you open Tor Browser and try to visit it, you should now see your website.
More Tor Hidden Services
torrc file can contain more than one hidden service, and hidden services can also operate on several ports. For example, Facebook’s
facebookcorewwwi.onion listens on both HTTP (port 80) and HTTPS (port 443). In cases like this, a
torrc file will look something like this:
HiddenServiceDir /var/run/tor/main-onion-site HiddenServicePort 80 127.0.0.1:80 HiddenServicePort 3000 127.0.0.1:3000 HiddenServiceDir /var/run/tor/other-onion-site HiddenServicePort 80 127.0.0.1:9000
In this case, the “main” site will serve two ports:
http://xxxxxxxxxxxxxxxx.onion:3000/ (routing to what is running on ports 80 and 3000 locally). The “other” site will be available at
http://yyyyyyyyyyyyyyyy.onion/ (routing to what is being served at port 9000 locally).
A little-known secret is that you can also use subdomains with onion sites: the web server that listens to connections from the
HiddenServicePort just needs to respond to the hostname. This works because recent versions of Tor will handle a connection to
www.xxxxxxxxxxxxxxxx.onion as a connection to
xxxxxxxxxxxxxxxx.onion, and your browser will state the subdomain it wants as part of the request inside that connection. You can see an example onion site subdomain configuration here.
Custom Hidden Service Names
You may have noticed that we didn’t configure the onion name that served our example site. Given a
HiddenServiceDir without a
private_key file inside, Tor will randomly generate a
hostname. The 16 characters of the hostname before
.onion are actually derived from this key, which allows Tor to confirm that it is connected to the right hidden service.
There are a few tools that allow you to generate a private_key in advance to get a predictable name: Shallot and Scallion are two popular options. Given an existing torrc with an already-configured
HiddenServiceDir, you can delete the existing
hostname file, drop in the new
private_key file, and restart Tor to use your new onion domain.
It’s debatable whether this is a good idea, since it may train users to look for the prefix and ignore the rest of the domain name. For example, an evildoer can generate a lot of
propubxxxxxxxxxx.onion domains — how do you know you’re at the right one? Facebook works around this issue by having an SSL certificate for their hidden service to provide a strong signal to users that they’re at the correct onion site. We’re working on adding this to our onion site, too.
When in doubt, a user should try to confirm an onion site’s domain by corroborating it at a variety of sources. (You can find a GPG-signed file confirming our onion addresses, here.)
Running in Production
There are a few extra things to think about when running a Tor hidden service in production:
While you can run your hidden service on your laptop or workstation, you’ll likely want to use an always-on machine to act as a server. Otherwise, the hidden service goes offline when your computer does.
HiddenServiceDirshould be relatively well-protected. If someone else can see your private_key, they can impersonate your hidden service. On a Linux machine, this is done by making sure that only the user running tor (
debian-toron Ubuntu) can access this directory.
The target of your HiddenServicePort should preferably be on the same machine as the web server. While you can map this to any IP address, terminating this connection locally reduces the chances of leaking metadata.
You may want to consider where your hidden service is installed. To avoid leaking traffic metadata as much as possible, you can choose to put the hidden service on the same machine as your website so that no Tor traffic has to leave the machine to access the website. Our hidden service is currently hosted on a machine located at the ProPublica offices (and not at our website hosting provider); this is mostly to help us debug issues, but also has the benefit of keeping full control of the machine hosting the hidden service and related log files. In terms of traffic metadata, this mixes encrypted HTTPS traffic from the hidden service with encrypted HTTPS traffic from our own use of the website. I think that’s an acceptable tradeoff (versus leaving hidden service logs available to our web host), but we may re-examine this in the future.
If you want to mirror an existing website, it‘s worth taking stock of the assets and resources that get loaded on your pages. We’ve made an effort to provide onion services for several subdomains that we use to serve our own assets. But news organizations also publish items that use external media — audio clips, videos, social media posts — to strengthen a story, and we use analytics to measure and understand our audiences. Having these external resources has ramifications (since some of the traffic no longer uses a hidden service and relies on using Tor to access the resource’s normal site) and it’s worth considering this issue on your own site. (As mentioned near the top of this post, there are features in Tor Browser that allow a user to block many of these resources.)
Current versions of Tor don’t provide any way of load-balancing large amounts of traffic. So even if you host your content with a production web server such as Apache or nginx, the hidden service endpoint is a single point of failure that can’t currently be scaled up. But Tor developers are working on a way of fixing this in an upcoming version.
SSL certificates are more difficult to acquire for Tor hidden services than normal domains. They can be issued, but must be extended validation (“EV” or “green bar”) certificates and undergo more thorough verification than proving ownership of a normal domain name. (We plan to go through this process, and we’ll update this post as we do so.)
Our Hidden Service Mirror
Putting together all of the above, you can get something like our current hidden service.
We use local Unix sockets (instead of an
ip:port) for the local connection between Tor and nginx. Other than that, there’s nothing too special about our
torrc, which you can find here.
The hidden service running ProPublica’s site at
p53lf57qovyuvwsc6xnrppyply3vtqm7l6pcobkmyqsiofyeznfu5uqd.onion speaks to an instance of nginx that handles routing our subdomains and some processing — such as rewriting “www.propublica.org” links to instead use the onion domain — before proxying on to our normal web server. (In Ubuntu, you can install a version of nginx that contains the extra rewrite modules by installing the
nginx-extras package.) You can see this configuration here.
You might notice that our hidden service does experimentally listen to HTTPS connections, but we’re currently using a self-signed key for that, which can cause a combination of browser errors and assets not loading if you try to visit our onion site that way. We’re working on getting a valid SSL certificate for our hidden service, and that should hopefully be fixed sometime soon.
If you have any concerns or feedback about this tutorial or the configuration I’ve shared, please get in touch. (My PGP key is 0x6E0E9923 and you can get it here, here, on Keybase and on most keyservers.)
Updated January 15, 2016: The configuration example has been updated; the walkthrough now notes that you can use Unix sockets for
Updated December 15, 2021: The .onion URL has been updated to a v3 onion URL, as the shorter v2 onion URLs are no longer supported in Tor Browser.