If you are running servers in your private network that need SSL, you can use LetsEncrypt and Certbot to automatically obtain and renew certificates for free. Even if your machines are not accessible from the internet.
What you need:
- A static IP in your internal network for the server, like 192.168.1.2
- Own a domain like “example.com” In this post I assume the server is accessed using server.example.com
- Certbot’s support for the nameserver of the domain. Even if you purchased your domain at some unupported provider, its usually no cost to change to a supported nameserver. In this post I am using Cloudflare
How to set it all up:
- Log in to your Cloudflare account and create an A record for ‘myserver’ with address 192.168.1.2
- Get a global API key from Cloudflare and remember it.
- Login to the private server.
- Create
/root/.secrets/cloudflare.ini
and put the following content into it:dns_cloudflare_email = "<mailadres of your cloudflare account>" dns_cloudflare_api_key = "<the api key you remembered earlier>"
- Ensure only root can read the directory and file
sudo sudo chmod 0700 /root/.secrets/ sudo chmod 0400 /root/.secrets/cloudflare.ini
- Install Certbot and the plugins it needs to talk to Cloudflare. For my environment this boiled down to:
sudo apt-get install certbot -t stretch-backports sudo apt-get install python3-certbot-dns-cloudflare -t stretch-backports
- Tell Certbot to obtain a free certificate for server.example.com
sudo /usr/bin/certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials /root/.secrets/cloudflare.ini \ -d server.example.com \ --preferCed-challenges dns-01
- Voila! You now have a certificate stored in
/etc/letsencrypt/live/server.example.com/fullchain.pem
Dealing with renewals:
- Certificates from LetsEncrypt have a short expiry time, so we need to renew it before it expires. We don’t want to have to think about doing this, we want this to be automatic. A simple crontab entry solves that.
14 5 * * * root /usr/bin/certbot renew --quiet > /dev/null 2>&1
Doing something with the SSL Certificate:
- After Certbot has obtained or renewed a certificate it executes scripts located in
/etc/letsencrypt/renewal-hooks/post/
In my case I am running Ubiquity’s Unifi controller software and use this script to deal with the renewal:#!/bin/sh DOMAIN=unifi.example.com # Backup previous keystore cp /var/lib/unifi/keystore /var/lib/unifi/keystore.backup.$(date +%F_%R) # Convert to PKCS12 format openssl pkcs12 -export \ -inkey /etc/letsencrypt/live/${DOMAIN}/privkey.pem \ -in /etc/letsencrypt/live/${DOMAIN}/fullchain.pem \ -out /etc/letsencrypt/live/${DOMAIN}/fullchain.p12 \ -name unifi \ -password pass:unifi # Install certificate keytool -importkeystore \ -deststorepass aircontrolenterprise \ -destkeypass aircontrolenterprise \ -destkeystore /var/lib/unifi/keystore \ -srckeystore /etc/letsencrypt/live/${DOMAIN}/fullchain.p12 \ -srcstoretype PKCS12 \ -srcstorepass unifi \ -alias unifi \ -noprompt #Restart UniFi controller service unifi restart