Let's encrypt: Get certifiactes for reverse proxied services

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 config of your application to allow the lets encrypt challenge.

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

<VirtualHost *:80>  
    ServerName www.shivering-isles.com
    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
    #...
</VirtualHost>  
<IfModule mod_ssl.c>  
<VirtualHost *:443>  
    ServerName www.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 config should looks like this:

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

<IfModule mod_ssl.c>  
<VirtualHost *:443>  
    ServerName www.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 statments are processed from top to down and first match wins.

Reload your apache config 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.

×

Stay in touch

By follow me on Twitter, follow RSS or sign up for my newsletter.