Freedombone Blog

Freedom in the Cloud

The rush to TLS

Issues which I've been encountering recently with XMPP are all about TLS and differing threat models. It seems as if LetsEncrypt has been around for ever, but really it has only been usable in the last two or three years. During that time an increasing number of internet applications just assume that TLS authentication is in place.

Before LetsEncrypt XMPP servers typically allowed self-signed TLS certificates or no certificates. Recognition by Certificate Authorities (CAs) wasn't mandatory. But increasingly now it is. This is all fine except in cases where you don't need TLS or where Certificate Authorities are untrusted and belong in the threat model. That's usually the case if you're running XMPP on onion addresses. After all, CAs include numerous dodgy companies and entities like the Chinese government.

So if you're setting up an XMPP server with the intention of using both clearnet and onion addresses then there's a conflict of interests between the two routing worlds. The clearnet would like CA-recognized TLS certificates to always be used. The onionspace would prefer that to be optional or not present.

In the rush to implement TLS everywhere, and thereby secure the internet from the evildoers, minority use cases like onion routing have been forgotten about and there isn't a clear solution if you want to inhabit both worlds.

As a workaround I've added a settings screen for the XMPP app within Freedombone which allows TLS authentication to be strictly enforced or not.

Matrix addendum

There has been a recent talk about Matrix at FOSDEM 2019 in which it's said:

As of Matrix 1.0, we require homeservers to present a CA-signed TLS certificate

So very much the same problems are going to apply to Matrix on onion addresses quite soon. Probably the version of Matrix on onion-only versions of Freedombone will need to be modified in order to federate, and will be non-compliant with the spec. If that's infeasible then it might be that Matrix on onion will only be non-federating, which would be disappointing.

Addendum addendum

It looks like Matrix will be ok after all. In the recently published federation API it says:

The TLS certificate provided by the target server must be signed by a known Certificate Authority. Servers are ultimately responsible for determining the trusted Certificate Authorities, however are strongly encouraged to rely on the operating system's judgement. Servers can offer administrators a means to override the trusted authorities list. Servers can additionally skip the certificate validation for a given whitelist of domains or netmasks for the purposes of testing or in networks where verification is done elsewhere, such as with .onion addresses.

Making email easier

Mailpile has existed as an app within Freedombone for a couple of years, and it's a nice webmail client, but for a more mass market type of approach it's not ideal. The reason is that the setup is quite non-intuitive and assumes that you know what acronyms like SMTP, IMAP and GPG mean. It's highly doubtful that the average shopper knows about any of that, and chances are they just use Gmail because that's what they were instructed to do by the initial setup process when they first got an Android phone. Gmail didn't ask them for an IMAP domain.

On Freedombone an email server is part of the base install and it has the capability to send and receive messages using onion addresses. I thought it would be nice to have a webmail client which doesn't need any post-installation configuration and which can be used with noscript or with javascript turned off. At first I thought I might need to write something like that because every modern webmail client appears to make extensive use of javascript, but the prospect of writing a usable email system is definitely a non-trivial undertaking so I wanted to avoid doing that if possible.

The only non-javascript solution I found was Squirrelmail. Squirrelmail is an old system by technology standards, although not as old as the kernel. It pre-dates smartphones, and it's certainly not the most glamorous web software you've ever seen but it's functional and customizable to some extent.

So I added a customized version of squirrelmail to the web interface of Freedombone.

The login has been changed to a new logo, and it's linked up to themes and languages such that if you change that on the settings screen the webmail system also changes accordingly. Testing it on mobile in the vertical orientation it looks odd but in horizontal orientation its ok and quite usable. I made a couple of themes called freedom_light and freedom_dark using the same colors as the main web interface so that it looks somewhat consistent. And you can use it to send between onion or clearnet email addresses without much hassle.

So despite its age and smartphone agnosticism Squirrelmail still appears to be quite a good addition.

Apart from the usual advantages of onion addresses the biggest one here is that you don't need to be using GPG to still have fairly good communications security. It's not end-to-end in the strictest sense, but a lot more secure than email usually is. You can also use it via a Tor browser with the security level cranked up to the max if you want to.

End-to-End Policy

Another thing changed recently on the XMPP configuration within Freedombone is the end-to-end security policy. Previously if you posted anything without encryption there would be a big scary and usually also noisy warning notification telling you to do better. This is ok for private one-to-one chats, but not for public multi-user chats such as channels used for open source projects.

So I did a little tweaking and now either OpenPGP or OMEMO are required for one-to-one chat (if you try anything else it will just fail) and there is no encryption requirement for multi-user chat. So you won't get any annoying alarms when posting to multi-user chats. You can of course still do encrypted multi-user chat if you want to, it's just not a strict requirement enforced by the server.

I now find that using XMPP with Conversations on Android is actually a nice experience with very little friction. The cryptostuff all seems to "just work", and there is no possibility of accidentally sending an unencrypted private message as there was before. As of Conversations 2.1 OMEMO encryption is now the default, so you don't need to be concerned about turning it on.

Also in cryptostuff-related news I noticed recently that the Tor daemon on my server was struggling and that apps were not accessible via their onion addresses. This happens occasionally, because Tor is not a perfect system. Relays appear or disappear. Guards change. Systems are attacked and defended. It would be nice to know when these outages are occurring though, so I've added a watchdog to monitor the health of the Tor daemon and report any changes in status via email. So now just by reading your email you can know whether there are any Tor problems happening. In future I'd like to integrate this with XMPP, because that might be more useful. I don't read emails all that often.

Federating the Onions

Within Freedombone it has long been possible to view fediverse instances via an onion address. That has applied to GNU Social, postActiv and more recently Pleroma. But this is really just the client to server part of the communications pipeline and federation between instances (server to server) remained exclusively via the clearnet.

A couple of years ago I did do some investigation of whether I could get GNU Social to federate via onion addresses, which would have the advantage of being independent of the DNS and certificate authority systems. There are a few php Tor proxying examples out there on Github, but none of my experients with federating GNU Social via onion addresses worked out the way I had hoped and I expect that fixing this would require a more involved level of php hacking than I'm currently familiar with.

Recently it has become possible to proxy Pleroma through Tor so that the servers can federate using Tor's DNS resolver, so I've added this as the default behavior both for the ordinary version of Freedombone and also the "onion only" version which, as the name implies, only uses onion addresses to access apps. If you're using Freedombone then this is all automatic, but if you're not the changes needed are quite simple.

If you're using Debian 9.x (the current stable) then you may want to install the tor daemon from backports. This will give you access to the shiny new version 3 onion addresses which have better performance and security properties.

apt-get -yq -t stretch-backports install tor

Create an onion address for your Pleroma instance. Within /etc/tor/torrc:

HiddenServiceDir /var/lib/tor/hidden_service_pleroma/
HiddenServiceVersion 3
HiddenServicePort 80 127.0.0.1:8011

And restart tor to generate the address:

systemctl restart tor

To find out what the onion address is:

cat /var/lib/tor/hidden_service_pleroma/hostname

Create an nginx configuration for your site. Something like:

proxy_cache_path /tmp/pleroma-media-cache levels=1:2 keys_zone=pleroma_media_cache:10m max_size=100m inactive=80m use_temp_path=off;

server {
    listen 127.0.0.1:8011 default_server;
    server_name yoursiteonionaddress;

    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;

   access_log /dev/null;
   error_log /dev/null;

   root /etc/pleroma;
   index index.html;

   gzip_vary on;
   gzip_proxied any;
   gzip_comp_level 6;
   gzip_buffers 16 8k;
   gzip_http_version 1.1;
   gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/activity+json application/atom+xml;

   location / {
       client_max_body_size 15m;
       client_body_buffer_size 15m;

       limit_conn conn_limit_per_ip 50;
       limit_req zone=req_limit_per_ip burst=50 nodelay;

       add_header 'Access-Control-Allow-Origin' '*' always;
       add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS' always;
       add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;
       if ($request_method = OPTIONS) {
           return 204;
       }

       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "upgrade";
       proxy_set_header Host $http_host;
       #proxy_set_header X-Forwarded-Proto $scheme;
       proxy_pass http://localhost:4000;
  }

  location /proxy {
      client_max_body_size 15m;
      client_body_buffer_size 128k;

      limit_conn conn_limit_per_ip 10;
      limit_req zone=req_limit_per_ip burst=10 nodelay;

      proxy_cache pleroma_media_cache;
          proxy_cache_lock on;
          proxy_pass http://localhost:4000;
  }
}

Where in the above case the Pleroma daemon is running on port 4000.

Now edit your secret.exs Pleroma configuration file and add the following line:

config :pleroma, :http, proxy_url: {:socks5, :localhost, 9050}

You will then need to recompile Pleroma.

cd where_you_installed_pleroma
sudo -u pleroma mix clean
sudo -u pleroma mix deps.compile
sudo -u pleroma mix compile

And restart the pleroma daemon.

systemctl restart pleroma

You should now be able to access Pleroma from the onion address and also federate with other instances which also support server to server onion addresses via a tor proxy.