Setup Certbot for Azure Virtual Machines

Certbot is a method of automating the renewal of Automated Certificate Management Environment (ACME protocol) SSL certificates and can be a handy tool to install on your Azure Virtual Machines. However, currently as of writing this there is a little snag with the Azure plugin for Certbot, as it is not yet been merged into the official library. I have gone through the process to learn how to get this setup correctly.

I would suggest reading up on Certbot from their website https://certbot.eff.org/ and also information on the Azure Plugin here https://certbot-dns-azure.readthedocs.io/en/latest/

In this article I have assumed them to be Linux Virtual Machines and using Bash to do the scripting.

Overview of Actions

  1. Generate Authentication file
  2. Install Certbot and Certbot Azure Plugin
  3. Generate Certificates
  4. Save Certificates into store
  5. Renew Certificate
  6. Automate Renewal

Generate Authentication File

First, we need to setup the authentication so Certbot can do the DNS challenge against Azure. The below is a setup for a single DNS Zone and using the more secure method of a Managed Identity for authentication, however there is also other methods to do this and how to setup multiple DNS Zones, outline here https://certbot-dns-azure.readthedocs.io/en/latest/#configuration

The below takes in the Managed Identity Client ID, Tenant ID, DNS Zone Resource Group and the DNS Zone name. It will then create the directory/file to store these details in the correct format and permissions.

 #!/bin/bash

clientId="98f63a12-3192-4999-a369-570c4a2f506c"
tenantId="2d38d338-e6a8-4d09-a4c0-0d1dc35ede1d"
dnsZoneResourceGroup="/subscriptions/99800903-fb14-4992-9aff-12eaf2744622/resourceGroups/rgName"
dnsZoneName="example.com"

filePath=".secrets/certbot/azure.ini"

mkdir ".secrets"
mkdir ".secrets/certbot"
touch $filePath

sudo chmod 755 $filePath

echo "" > $filePath
echo "dns_azure_msi_client_id = $clientId" >> $filePath
echo "dns_azure_tenant_id = $tenantId" >> $filePath
echo "" >> $filePath
echo "dns_azure_zone1 = $dnsZoneName:$dnsZoneResourceGroup" >> $filePath

sudo chmod 400 $filePath

Install Certbot and Certbot Azure Plugin

We then can setup the installation of Certbot and the Azure Plugin, which following the Certbot description we would use the tool `snap`. However, as the Azure Plugin is not added to the official list, we cannot install this plugin via the snap tool. Therefore, the only way to install the Azure Plugin is using Python and so we also need to install Certbot in the same method for them to work together.

Below we will install Python 3, Certbot, Certbot Azure Plugin and some modules as they need to be capped at certain versions for them to work with Certbot.

# Install certbot and certbot-dns-azure
sudo apt-get -y install python3-pip
sudo pip3 install certbot certbot-dns-azure 
sudo pip3 install -Iv zope.interface==5.4.0
sudo pip3 install -Iv cryptography==2.5

Generate Certificates

By this time, we have got the authentication file setup and Certbot installed. Below we can run the command that will run Certbot on the Virtual Machine. This declares it will use the configuration file that we setup previously, it will do a DNS challenge to check it has ownership on the domain and create the certificate against the URL provided. This is assuming you have the DNS Zone, DNS record, Virtual Machine and associated Managed Identity attached.

This is all automated to run non-interactively, so this can be run via a command on the VM or a pipeline task during deployment.

# Install while running
url="www.example.com"
supportEmail="example@example.com"

sudo certbot certonly \
--authenticator dns-azure \
--preferred-challenges dns \
--noninteractive \
--agree-tos \
--email ${supportEmail} \
--dns-azure-config .secrets/certbot/azure.ini \
-d ${url}

Save Certificates into store

Once we now have the certificate generate, the below script can now save the certificate into the Keytools on the Virtual Machine. This will retrieve the certificate from the auto-generated location, resign the certificate and then store it within the Keytools.

Keytool is a tool for Java applications, but this tool can be swapped for other tools and setups. For more information on Keytools you can read here https://jenkov.com/tutorials/java-cryptography/keytool.html

url = "www.example.com"
certPassword = "***"

certPath="/etc/letsencrypt/live/${url}/fullchain.pem"
privateKeyPath="/etc/letsencrypt/live/${url}/privkey.pem"
certDir="/var/lib/waagent/"
pfxName="myPfxFile.pfx"

cd $certDir

openssl pkcs12 -inkey $privateKeyPath -in $certPath -export -out $pfxName -passin pass: -passout pass:${certPassword}

keytool -importkeystore -srckeystore $pfxName -srcstoretype pkcs12 -destkeystore /usr/local/store/ssl.store.jks -deststoretype JKS -deststorepass ${certPassword} -srcstorepass ${certPassword}

Renew Certificate

This is now all great as the setup is all automated and dynamically setup to generate the certificate. However, these certificates only have a 3 month life, therefore we would like this to be automatically renewed as well.

The below script assumes that you have saved the script above, to save the certificate into the Keytool, into a shell script file for example `save-certificate.sh`. When we run the Certbot command it will create an order, which the below will renew that order and generate a new certificate.

#!/bin/bash

# Test cert update
sudo certbot renew -q

sudo /home/certbot/save-certificate.sh

Automate Renewal

We can then save this to a file for example `renew-certbot.sh` and with the following command we will create a cron job to automatically run the renewal script from above.

# Auto Renewal > https://eff-certbot.readthedocs.io/en/stable/using.html#setting-up-automated-renewal
SLEEPTIME=$(awk 'BEGIN{srand(); print int(rand()*(3600+1))}'); echo "0 0,12 * * * root sleep $SLEEPTIME && sudo /home/certbot/renew-certbot.sh" | sudo tee -a /etc/crontab > /dev/null

Published by Chris Pateman - PR Coder

A Digital Technical Lead, constantly learning and sharing the knowledge journey.

Leave a message please

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: