I remember a time when acquiring SSL certificates to enable HTTPS on a web server was a tedious process ... not only did you have to subscribe but you would need to verify your identity by submitting all kinds of paperwork to prove your existence.

These days you can get SSL Certificates sign-by browser recognized certificate authorities for FREE. The catch with most of them is that they are only valid for short periods such as 30 or 90 days, and you have to update your certs to a renewed version before they expire.

letsencrypt.org, one of the providers of free SSL certs makes this easier by automating the process of requesting and renewing a certificate, using a protocol named ACME. By using tools that support ACME you can maintain your SSL certificates easily.

There are a number of tools that support ACME -- the list can be found here. Most can be run in a Linux-based web server, and regularly renew your SSL certificate and update your web server automatically. I tried a few of them, and while many would work on a full blown Linux server such as CentOS or Ubuntu, very few would run on an OpenWRT router.

In the end I managed to get the dehydrated ACME client to work. Here are my notes.

  • Login to your OpenWRT router, and execute the following:
    • Install dependencies needed by dehydrated:
      • opkg install openssl-util
      • opkg install curl
      • opkg install diffutils
      • opkg install ca-certificates
      • opkg install bash
    • This is where we want the dehydrated executable to go:
    • This is for the dehydrated config file:
      • mkdir -p /etc/dehydrated/www
      • wget "https://github.com/lukas2511/dehydrated/raw/master/docs/examples/config" -O /etc/dehydrated/config
    • Edit /etc/dehydrated/domaints.txt and insert your list of domains you wish SSL keys for. If you have multiple virtualhost on port 443, you should list all of their domain names on the same line, separated by space:
      • home.abubakar.net
    • As part of the ACME protocol, letsencrypt.org checks to see if your server is really the one requesting the cert. It does this by checking your webserver for a token that is placed there by the dehydrated client. So you need to make a well known directory for dehydrated to save the token into, which must also be accessible from the internet.
    • Edit /etc/dehydrated/config and uncomment and set the following:
      • WELLKNOWN="/etc/dehydrated/www"
    • Append the italic section below to your domain name's http server section in /etc/nginx/nginx.conf. This is to allow the token written by dehydrated during its config process to be accessible over the internet by letsencrypt.org.
      • server {
        • listen 80;
        • server_name home.abubakar.net;
        • location /.well-known/acme-challenge {
          • alias /etc/dehydrated/www;
        • }
        • [...]
      • }
    • Execute the following:
      • cd /usr/local/bin
      • ./dehydrated --register --accept-terms
      • ./dehydrated -c
    • Your certs should be available as:
      • /etc/dehydrated/certs/home.abubakar.net/cert.pem
      • /etc/dehydrated/certs/home.abubakar.net/privkey.pem
      • /etc/dehydrated/certs/home.abubakar.net/fullchain.pem
    • You can now create a server section in nginx.conf with SSL turned on, i.e.:
    • # Reverse Proxy for HTTPS
    • server {
    • listen 443;
    • server_name home.abubakar.net;
    • ssl on;
    • ssl_certificate /etc/dehydrated/certs/home.abubakar.net/cert.pem;
    • ssl_certificate_key /etc/dehydrated/certs/home.abubakar.net/privkey.pem;
    • ssl_session_timeout 5m;
    • ssl_protocols SSLv2 SSLv3 TLSv1;
    • ssl_ciphers HIGH:!aNULL:!MD5;
    • ssl_prefer_server_ciphers on;
    • location / {
    • proxy_pass http://home.abubakar.net.internal/;
    • }
    • }

Renewing your SSL certificates

  • You can manually check for the need to renew a certificate by running:
    • /usr/local/bin/dehydrated --cron
  • But it works best when put into openwrt as a scheduled task, that also restarts the nginx server:
    • Login to LUCI as root, System -> Scheduled Tasks
    • Append the following into the text box:
      • * 3 * * * /bin/sh -c "/usr/local/bin/dehydrated --cron; /etc/init.d/nginx reload"