Ubuntu 16.0.4 + Nginx Upgrade to Certbot & Certificate Renewal

Just upgraded to Cerbot from letsencrypt for the installation of free Let’s Encrypt SSl certificates. It was actually easier than I thought as Certbot can just be installed and will replace the old letsencrypt command / method. It can be done in a few easy steps. As a bonus you can have auto renewal up and running in no time as well. Here is how it is all done.

Upgrade to Certbot

To upgrade your Let’s Encrypt setup from letsencrypt to cerbot you can check out the commands to run at the Cerbot website, but for Ubuntu 16.0.4 running Nginx do the following:

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx

These commands will add the appropriate library Software Properties Common, add the Certbot repository and then update all and install Cerbot Nginx. It will also remove the old setup:

The following packages will be REMOVED:
python-letsencrypt

Pretty neat it is all done on the fly!

Cerbot Renewal

Not that you have done this we can move on to the next step. To renew the Let’s Encrypt certificate without bumping into port conflict issues such as:

Attempting to renew cert from /etc/letsencrypt/renewal/domain.cp,.conf produced an unexpected error: Could not bind TCP port 443 because it is already in use by another process on this system (such as a web server). Please stop the program in question and then try again.. Skipping.

run the following command:

sudo certbot certonly --agree-tos --rsa-key-size 4096 -m jasper@domain.com -d domain.com --renew-by-default

This will start the interactive mode and offers the appropriate options to renew your Certbot installed Let’s Encrypt certificate.

NB Later on I also read in the documentation that you could do the non interactive mode and deal with ports blocked using:

certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start"

I will test this the next time.

Webroot Authentication

You then get the question how you would like to authenticate:

How would you like to authenticate with the ACME CA?
-------------------------------------------------------------------------------
1: Spin up a temporary webserver (standalone)
2: Place files in webroot directory (webroot)
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2

Then I got to see:

Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for domain.com
Select the webroot for domain.com:
-------------------------------------------------------------------------------
1: Enter a new webroot
-------------------------------------------------------------------------------
Press 1 [enter] to confirm the selection (press 'c' to cancel): 1

I chose one and was asked to add the webroot:

Input the webroot for domain.com: (Enter 'c' to cancel):

I added the Laravel app webroot

/usr/share/nginx/app/public

Certbot Certificate Verification

Afterwards Certbot told me all went well with these choices and all was set up accordingly:

Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/domain.com/fullchain.pem. Your cert
will expire on 2017-08-30. 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"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
Donating to EFF:                    https://eff.org/donate-le

The certificate and chain were added succesfully so all went well.

Automatic Renewal

Now we all want the certificate to be renewed automatically every 90 days instead of doing this by hand. Well you are in luck! If you did what I did all is now set up properly for an auto renew. Just do a:

sudo certbot renew --dry-run

to do a test run and check if the same goes for you. You should see something similar to this:

[sudo] password for user: 
Saving debug log to /var/log/letsencrypt/letsencrypt.log
-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/domain.com.conf
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Starting new HTTPS connection (1): acme-staging.api.letsencrypt.org
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for domain.com
Waiting for verification...
Cleaning up challenges
-------------------------------------------------------------------------------
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/domain.com/fullchain.pem
-------------------------------------------------------------------------------
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)
Congratulations, all renewals succeeded. The following certs have been renewed:
/etc/letsencrypt/live/domain.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)

As you can see it indicates renewals went well. This also mean auto renewals will work. When you check the config file you will see something like this:

user@app:/etc/letsencrypt/renewal$ cat domain.com.conf
 # renew_before_expiry = 30 days
 cert = /etc/letsencrypt/live/domain.com/cert.pem
 privkey = /etc/letsencrypt/live/domain.com/privkey.pem
 chain = /etc/letsencrypt/live/domain.com/chain.pem
 fullchain = /etc/letsencrypt/live/domain.com/fullchain.pem
 version = 0.14.2
 archive_dir = /etc/letsencrypt/archive/domain.com

# Options and defaults used in the renewal process
 [renewalparams]
 installer = None
 authenticator = webroot
 rsa_key_size = 4096
 account = key
 [[webroot_map]]
 domain.com = /usr/share/nginx/app/public

These include renewal parameters.

Certbot Cronjob

And you will find a cronjob added to run the renewal 30 days before the certificate expires:

/etc/cron.d$ cat certbot 
# /etc/cron.d/certbot: crontab entries for the certbot package
#
# Upstream recommends attempting renewal twice a day
#
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc. Renewal will only occur if expiration
# is within 30 days.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew

There had been a bug before with the Nginx server not reloading, but all should be working now with the fresh Certbot installation.

Mission accomplished!

Tagged in : Tagged in : , ,
Jasper Frumau

Jasper has been working with web frameworks and applications such as Laravel, Magento and his favorite CMS WordPress including Roots Trellis and Sage for more than a decade. He helps customers with web design and online marketing. Services provided are web design, ecommerce, SEO, content marketing. When Jasper is not coding, marketing a website, reading about the web or dreaming the internet of things he plays with his son, travels or run a few blocks.