Tor is a powerful anonymity tool that lets people communicate and share ideas without disclosing who they are or what they’re viewing to prying eyes.

One cool thing that the network lets you do is create a site as a hidden service, which is a service accessible only from within the tor network, is end to end encrypted and can be viewed entirely anonymously via a .onion domain.

I thought it could be cool to be able to run Known as a hidden service, and potentially build an entirely distributed social network, one that resists metadata surveillance as well as content surveillance. Anyway, baby steps…

Install Tor

The first thing you need to do is install tor. I don’t mean the tor browser, although you’ll need that to visit your hidden service, I mean the underlying tor program itself. On a debian based network this is really easy:

apt-get install tor

Next, you need to configure your hidden service(s) by editing the configuration in /etc/tor/torrc:

HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80 127.0.0.1:80
HiddenServicePort 443 127.0.0.1:443

Restart tor and you will find a file containing your .onion domain name in /var/lib/tor/hidden_service/hostname. More details on configuring tor hidden services can be found on the tor project website.

Install Known

Download and install Known in the usual way.

My setup for my test onion site is Apache2 + modules + MariaDB (because I wanted to try Maria out). You of course can run nginx with mysql or mongodb, it won’t matter too much for tor.

To run through the Known installation procedure, you’ll need to visit your site via the tor browser. Find the name of your hidden service in /var/lib/tor/hidden_service/hostname (which will look something like xa7txi2q5okg36f6.onion), fire up your tor browser and visit that URL. All being well, you should see the Known installation.

Configuring Known to use tor

By default, Known will attempt to connect to web services and send webmentions directly. This will usually work if the machine you’re running your hidden service on is also directly connected to the internet, however you should consider routing this through tor since this communication could unmask your service.

So, you need to configure tor as a proxy, and then configure Known to use it.

First, edit torrc and add/uncomment the line:

SocksPort 9050

Next, configure Known’s web services to use it. Add the following to your Known config.ini file:

proxy_string = 'localhost:9050'
proxy_type = 'socks5-hostname'
disable_ssl_verify = 'yes'

These commands tell Known’s webservice calls to use the tor proxy to connect to the internet, and to use tor for DNS resolution in order to get access to .onion domains. This is important so that you are able to, among other things, send webmentions to other .onion sites from within the tor network. The last line disables ssl verification for HTTPS certificates (see the note below).

Note, for these settings to work you need to be running a version of Known that includes my curl settings patch.

Restart tor, and now all web service calls (which use Known’s web service library) should be sent via your tor proxy.

Known issues

There are some things you will need to consider when running Known as a hidden service:

  • The default PuSH hub is the public one at https://withknown.superfeedr.com/. This may cause unacceptable leakage of activity, so you may want to consider leaving this blank or using the Known native PuSH hub.
  • For the same reason, you may want to consider turning off emails, or sending emails through something like Mixmaster.
  • Only things that use Known’s web services libraries will use the proxy. Third party plugins (especially syndication plugins which use third party libraries, e.g. Facebook) will still try to connect directly. You may consider not using these plugins.
  • Currently there are no valid TLS certificates available for .onion domains, so you have to self sign if you want HTTPS. However, a .onion address is end to end encrypted in any case and there is some lively discussion about whether certificate authority based HTTPS is necessary or even desirable for hidden services. That you can’t get valid SSL certs for hidden services is a known problem (as opposed to a Known problem), so it’ll be resolved eventually one way or another.

Anyway, happy hacking!

Based on prompting from a point made in this great article, I extended the System logging Known plugin that I wrote previously, to include a visual security log.

This log shows a user by user security log, showing login/logout and login failure attempts for each user’s account, plus a global log visible to the administrator. This provides a visual way for you to keep track of when, and from where, your account has been accessed, and hopefully give you tools to spot erroneous access attempts (for additional security you should totally check out my two factor authentication plugin as well).

» Visit the project on Github...

So, let us talk plainly. You absolutely, definitely, positively should be using TLS / HTTPS encryption on the sites that you run.

HTTPS provides encryption, meaning that anyone watching the connection (and yes, people do care, and are absolutely watching), will have a harder time trying to extract content information about the connection. This is important, because it stops your credit card being read as it makes its way to Amazon’s servers, or your password being read when you log into your email.

When I advise my clients on infrastructure, these days I recommend that all pages on a website, regardless of that page’s contents, should be served over HTTPS. The primary reason being a feature of an encrypted connection which I don’t think gets underlined enough. I also advise them to invest in colocation to protect their business data. You can visit this page to know more.

Tamper resistant web

When you serve content over HTTPS, it is significantly harder to modify. Or, to put it another way, when you serve pages unencrypted, you have absolutely no guarantee that the page your server sends is going to be the page that your visitor receives!

If an attacker controls a link in the chain of computers between you and the site you’re visiting it is trivial to modify requests to and from a visitor and the server. A slightly more sophisticated attacker can perform these attacks without the need to control a link in the chain, a so called “Man on the side” attack – more technically complex, but still relatively trivial with sufficient budget, and has been widely automated by state actors and criminal gangs.

The capabilities these sorts of attacks give someone are limited only by budget and imagination. On a sliding scale of evil, possibly the least evil use we’ve seen in the wild is probably the advertising injection attack used by certain ISPs and Airplane/hotel wifi providers, but could easily extend to attacks designed to actively compromise your security.

Consider this example of an attack exploiting a common configuration:

  • A web application is installed on a server, and the site is available by visiting both HTTP and HTTPS endpoints. That is to say, if you visited both http://foo.com and https://foo.com, you’d get the same page being served.
  • Login details are sent using a POST form, but because the developers aren’t complete idiots they send these over HTTPS.

Seems reasonable, and I used to do this myself without seeing anything wrong with it.

However, consider what an attacker could do in this situation if the page serving the form is unencrypted. It would, for example, be a relatively trivial matter, once the infrastructure is in place, to simply rewrite “https://” to “http://”, meaning your login details would be sent unencrypted. Even if the server was configured to only accept login details on a secure connection (another fairly common practice), this attack would still work since the POST will still go ahead. A really sophisticated attacker could intercept the returning error page, and replace it with something innocuous, meaning your visitor would be non the wiser.

It gets worse of course, since as we have learnt from the Snowden disclosures, security agencies around the world will often illegally conscript unencrypted web pages to perform automated attacks on anyone they view as a target (which, as we’ve also learnt from the Snowden disclosures, includes just about everybody, including system administrators, software developers and even people who have visited CNN.com).

Lets Encrypt!

Encrypting your website is fairly straightforward, certainly when compared to the amount of work it took to deploy your web app in the first place. Plus, with the new Lets Encrypt project launching soon, it’s about to get a whole lot easier.

You’ll need to make sure you test those configurations regularly, since configuration recommendations change from time to time, and most shared hosts & default server configurations often leave a lot to be desired.

However, I assert that it is worth the extra effort.

By enabling HTTPS on the entire site, you’ll make it much much harder for an attacker to compromise your visitor’s privacy and security (I say harder, not impossible. There are still attacks that can be performed, especially if the attacker has root certificate access for certificates trusted by the computer you’re using… so be careful doing internet banking on a corporate network, or in China).

You also add to the herd immunity to your fellow internet users, normalising encrypted traffic and limiting the attack surface for mass surveillance and mass packet injection.

Finally, you’ll get a SEO advantage, since Google is now giving a ranking boost to secure pages.

So, why wait?