Okay, so we're ready to generate an SSL certificate for our web application. There are a few prerequisites for this:
- A fully registered domain name, i.e. example.com.
- A DNS A record with example.com pointing to your VPS's public IP address.
- A DNS A record with www.example.com pointing to your VPS's public IP address.
So, firstly, we need to install a tool called Certbot. To do this, you need to SSH into your VPS and run the following commands:
sudo add-apt-repository ppa:certbot/certbot sudo apt update sudo apt install certbot
Certbot has to answer a cryptographic challenge provided by the Let's Encrypt API. It uses port 80 or 443 to accomplish this, so you need to allow this port in your firewall. If you're on a Digital Ocean Ubuntu 18.0.4 machine, then you need these commands:
sudo ufw allow 80 sudo ufw allow 443
Be sure now to kill any processes that are currently using these ports. For example, if you have your web application running. If you do not then Certbot will fail to bind to the appropriate port and the request for certification will fail. To generate a certificate we are going to use Certbot's standalone mode:
sudo certbot certonly --standalone --preferred-challenges http -d example.com
After being prompted to enter your email address and accept terms and conditions you should receive a message similar to the following:
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/example.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/example.com/privkey.pem Your cert will expire on 2019-03-19. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew all* of your certificates, run "certbot renew"
You'll notice that the directories where the private key and certificate file have been stored are the same as the ones that we have already specified in our configuration files. Each certificate is valid for 90 days. Renewal can be handled automatically using cron. To start, open the cron file using
crontab -e. In the cron file we can add a new line, replacing the filepaths with the filepath of your
@weekly certbot renew --pre-hook "docker-compose -f path/to/docker-compose.yml down" --post-hook "docker-compose -f path/to/docker-compose.yml up -d"
After saving the cron file we now have a renewal check scheduled weekly. To do this check, we need access to ports 80 and 443; this means that we need to kill our application before the check and start it after the check. This is handled by the
-–post-hook arguments. If Certbot detects that an SSL certificate will expire within 30 days then it will be renewed.
Lastly, you can check to see if the renewal command will work correctly by using the following command:
sudo certbot renew –dry-run
Feel free to add the
-–post-hook arguments to the dry run of the renewal, however only do this if you already have your application on your VPS, otherwise you'll attempt to reference files that do not yet exist.