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!

I recently wrote a hook for Known (subsequently merged into the core) that converts twitter links to an embedded representation.

This was handy for a few folk, so I figured it’d be sensible to add similar functionality to my OEmbed Enabled embedded posts plugin for Known. The plugin will now attempt to use OEmbed to extract a representation of any Known post you link to into a rendered version.

Because allowing connections to just any OEmbed endpoint is a security risk, I’ve configured the plugin so that the Admin needs to whitelist domains/urls first (your current domain is automatically whitelisted).

Theoretically this could be used to whitelist non-Known sites that support oEmbed, although I’ve not extensively tested this so YMMV. Have fun!

» Visit the project on Github...

We all know how important it is to secure web servers with encryption. As I’ve mentioned before, port 80 HTTP should be considered deprecated at this point!

Just as important (potentially more so), but often overlooked, is to ensure that your email server is also secure.

STARTTLS is a technology that lets you start an encrypted session during a standard SMTP connection. In the same way as HTTPS secures web, STARTTLS will secure email in transit from your mail client to the server, and from server to server. This makes it much harder to passively read the traffic, and having more encrypted traffic on the internet is only ever a good thing.

This only protects email in transit from server to server of course, so this is not a replacement for end to end encryption methods like PGP, but it does complement it… and since most email is still sent insecurely, this adds extra security without requiring your users do any extra work.

It’s easy to set up (for Exim at least), and it transparently runs on port 25, so there’s no reason not to!

Generate your keys

As with web, you’ll need a server key and certificate file.

For my public mail and MX relay servers, I decided to use valid certificate authority certificates. Clients, and some relaying servers, will throw a certificate error for self signed certificates, but others will not. Better safe than sorry, and since I already had a valid certificate on my site for the server in question, I simply recycled the certificate.

If this is your internal server, you can use a certificate signed by your own certificate authority, supported by the machines in your organisation.

The default exim configuration expects to find certificates in /etc/exim4/exim.key and /etc/exim4/exim.crt.

Enable TLS

The basic STARTTLS configuration by simply editing exim4.conf.template and setting MAIN_TLS_ENABLE = yes in the tlsoptions section. Restart exim and you should have STARTTLS support enabled.

As with a web server, you can configure ciphers etc at this stage. On my server at least, the defaults seemed reasonably strong, but as we learn which ciphers have been compromised by GCHQ and the NSA, we might need to tweak these.

Test your configuration

Next, you should test your configuration.

To do this, the simplest way is to use a program called swaks, which you should find in your distro’s package library.

swaks -a -tls -q HELO -s mail.example.com -au test -ap '<>'

Should produce a result something like…

=== Trying mail.example.com:25...
=== Connected to mail.example.com.
.
.
.
 -> STARTTLS
<-  220 TLS go ahead
=== TLS started w/ cipher ECDHE-RSA-AES256-GCM-SHA384
=== TLS peer subject DN="/OU=Domain Control Validated/OU=PositiveSSL/CN=mail.example.com"
.
.
.
 ~> QUIT
<~  221 mail.example.com closing connection
=== Connection closed with remote host.

If you get an error when starting TLS examine your exim log for the cause.