Skip to content

Instantly share code, notes, and snippets.

@anthony-curtis
Last active July 9, 2019 14:32
Show Gist options
  • Save anthony-curtis/a0f27c63b968a9de5cfd5d2d36aa8720 to your computer and use it in GitHub Desktop.
Save anthony-curtis/a0f27c63b968a9de5cfd5d2d36aa8720 to your computer and use it in GitHub Desktop.
AWS Lightsail with Automatically Renewing Let's Encrypt SSL

Automatically Renewing Let's Encrypt SSL on AWS Lightsail

The Amazon Lightsail documentation walks through the creation of a wildcard SSL certificate using Let's Encrypt. Unfortunately, the final step of the tutorial says to manually renew your certificate every 90 days.

What if you want to have it renew automatically?

If you try to run the certbot renew command via a cron job it will fail. The wildcard certificate validation process requires a change to your DNS records and this is not something certbot handles out-of-the-box.

You have a few options to create an automated solution:

  1. Use a certbot plugin as mentioned here to automate the DNS record challenge.
  2. Use a non-wildcard certificate with multiple domains and skip the DNS style challenge altogether.

If you absolutely require a wildcard certificate then you will want to research option 1.

In this short guide, we will go through option 2.

Using the Let's Encrypt "webroot" Authentication Method with Lightsail

  • Complete steps 1 and 2 on the Lightsail documentation
  • Skip steps 3 through 6 and instead issue the following commands: sudo certbot certonly -w /home/bitnami/apps/wordpress/htdocs -d example.com -d www.example.com where -d should precede any domains you want to include on this certificate
  • When certbot asks for an authentication method choose "webroot", then wait for the script to complete
  • Return to the Lightsail SSL tutorial and complete step 7 with DOMAIN set to the first domain you listed when generating the certificate
  • Complete Step 8 in Lightsail SSL tutorial if using Wordpress

Automating Renewal

At this point you will have the certificates in place and your site should be serving over SSL.

Time to create a script to automate this so you can "set it and forget it."

  • Open the cron job table via sudo crontab -e

  • Add the following to the top of the cron table:

    # SSL Renewal
    0 0 * * 0 env HOME=/home/bitnami /usr/bin/certbot renew && /opt/bitnami/ctlscript.sh restart
    
    # Testing version - uncomment the line below to test renew command and view output via log file
    #* * * * * env HOME=/home/bitnami /usr/bin/certbot renew --dry-run > /tmp/cron-log.txt 2>&1 && /opt/bitnami/ctlscript.sh restart > /tmp/cron-log.txt 2>&1
    

    This will run the check every week (Sunday at 00:00) and if you are within the renewal period it will update the certificates. If you would like to check at different intervals be sure to use a tool like crontab.guru.

    This also adds a test cron job, which you can uncomment to confirm all will work when the cert is due for renewal.

  • Exit the editor and save when prompted.

Testing Your Renewal Script

Since the cron jobs can run with different permissions or contexts it's always good to test. Certbot offers a nice --dry-run option to do a complete run-through.

If you would like to run a test:

  • Reopen crontab via sudo crontab -e
  • Remove the # to uncomment the second cron entry above, then exit and save when prompted
  • The cron job will now run every minute.
  • Watch the output via tail -f /tmp/cron-log.txt for a dry-run success message similar to what you saw when first generating your certificate
  • After confirmation run sudo crontab -e one last time and re-comment the testing script so your server isn't restarting every minute (!)

Additional Information

Here are some things to keep in mind as you search this topic and encounter other tutorials:

  • Some sites have commands and examples written before lets-encrypt was renamed to certbot
  • Parts of this guide were based on a tutorial found here, but the cron job command has a typo that will check for renewal every year instead of every month. Ouch!

Useful Links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment