Enable Letsencrypt and Joomla behind proxy

// posted here so I remember it //

LetsEncrypt offers owners of domains the option to create free-of-charge SSL certificates. Having a blog's login form sending passwords via encrypted channels is a Good Idea, but so far I put it off because previously it was costly and a hassle to get this done.

When the initiative to have SSL everywhere started, the tools were not so great and not all browsers recognized LetsEncrypt. Often they would show warnings about an unknown certificate authority, but by now it looks those things have been solved. There are even a lot of tools and package to get you started quickly for your given web server and host operating system.

sudo apt-get install letsencrypt

will get you started on Ubuntu.

sudo letsencrypt --apache

will give a list of your enabled domains on the Apache web server and ask which ones to SSLify. 

Caveat 1: if you are using vhosts, each must be in its own configuration file. This was some work.

Caveat 2: if you are using Joomla, you need to configure it to use SSL - I did simply turn on "force SSL for entire site" and whoops, endless redirect loop.

Since my Joomla instances live inside a virtual machine (KVM), the proxy Apache on the host would serve as a termination to the SSL connection and then send the unencrypted request to the virtualized Joomla. But since Joomla would try to force a redirect to SSL, it would always answer with "hey, you need to encrypt this request" - and the browser would follow the redirect, only to end up in another iteration of the host de-crypting and Joomla complaining.

You need to add a request header to the host Apache:

<VirtualHost *:80>
    RequestHeader set X-Forwarded-Proto "http"
    …
</VirtualHost>
<VirtualHost *:443>
    RequestHeader set X-Forwarded-Proto "https"
    …
</VirtualHost>

and add

SetEnvIfNoCase X-Forwarded-Proto https HTTPS=on

to the Apache server's config file inside the VM.

Only that did not work for me, I kept getting either redirect loops or mixed content problem (when some links point to non-encrypted URLs). So my hack is to use 

    RequestHeader set X-Forwarded-Proto "http"

and a second SetEnvIf for: SetEnvIfNoCase X-Forwarded-Proto http HTTPS=on

on the guest system.

This makes all traffic coming to Joomla look like it's encrypted via https. 

Note: this is only secure against MITM because the Joomla VM is on the same machine as the proxy server and does not listen to the internet (all traffic to the VM must originate on the host, in this case the Apache proxy server).

Renewing certificates:

Add a cron file "letsencrypt" to /etc/conf.d folder with:

 17 1,13 * * * root letsencrypt renew && /usr/sbin/service apache2 reload17 1,13 * * * root letsencrypt renew && /usr/sbin/service apache2 reload

so it tries two times a day to renew any certificates in danger of expiration. (Tool to create cron expressions: the beautiful Crontab.Guru)