My Profile Photo

Sheogorath's Blog

Let's encrypt: Get certifiactes for reverse proxied services

on

Let’s encrypt is a lovely solution for the big problem of expensive certificates. It allows you to get free certificates by running their clients. To prove that you are the owner of the domain they just use a challenge which is placed on your webserver.

So what do you need? Right, a webserver as reverse proxy. I’ll use apache in this tutorial. What else? Yes, the “Let’s encrypt”-client and at least any service which need a SSL certificate.

The most annoying part of let’s encrypt is that their certificates have a really short lifetime. Currently 90 days in future may less. So you need to renew it periodically. How to do that is another article.

So let’s start. First you download the “Lets encrypt”-client from Github

I’ll install it to /opt/letsencrypt. You can use any other location too. You may use the package management of your system.

cd /opt
git clone https://github.com/letsencrypt/letsencrypt.git letsencrypt

Next step you had to edit the virtual host configuration of your application to allow the lets encrypt challenge.

Let’s say this is the virtual host configuration before you want to use a Let’s encrypt certificate:

<VirtualHost *:80>
    ServerName shivering-isles.com
    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
    #...
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName shivering-isles.com
    ProxyPreserveHost On
    ProxyRequests off
    ProxyPass / http://127.0.0.1:12345/
    ProxyPassReverse / http://127.0.0.1:12345
    SSLCertificateFile    /path/to/certificate/ourold.crt
    SSLCertificateKeyFile /path/to/key/ourold.key
    #...
</VirtualHost>
</IfModule>

You add the following two lines:

  • DocumentRoot /var/www/
  • ProxyPass /.wellknown !

DocumentRoot will be the place where lets encrypt will store the challenge stuff. The new ProxyPass statement will allow you to enter the DocumentRoot just for the challenge and still have everything else passed to your application.

Now your configuration should looks like this:

<VirtualHost *:80>
    ServerName shivering-isles.com
    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
    #...
</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName shivering-isles.com
    DocumentRoot /var/www/
    ProxyPreserveHost On
    ProxyRequests off
    ProxyPass /.wellknown !
    ProxyPass / http://127.0.0.1:12345/
    ProxyPassReverse / http://127.0.0.1:12345
    SSLCertificateFile    /path/to/certificate/ourold.crt
    SSLCertificateKeyFile /path/to/key/ourold.key
    #...
</VirtualHost>
</IfModule>

Please notice the position of the ProxyPass statement is important because those statements are processed from top to down and first match wins.

Reload your apache configuration and change to /opt/letsencrypt.

You run ./letsencrypt-auto and let’s encrypt will work as expected.

EDIT 16.05.2016: Had to add the <IfModule mod_ssl.c>-tag else the official Let’s encrypt client doesn’t detect the vhost.