Adding TLS certificate to Azure Application Gateway

Adding TLS certificate to Azure Application Gateway

Adding TLS certificates to web applications may be second hand to many experienced developers. Hosting providers like Wordpress handles the setup of TLS for your web application - no hassle. However if you have a custom developed application that you deploy with, let's say Azure App Service with a Application Gateway in front, that's a different beast.

Let's start simple - What and why?

TLS - Transport Layer Security (previously known as SSL) is a protocol that provide secure communication while browsing the web. It simply ensures that all communication between the server and client is encrypted. The reason we want this is to protect our users from having their data stolen.

Why is this so hard?

Well.. It's not. Azure offers to handle creation and maintenance of certificates for you. That would be all fun and games if it fit my needs. I was placing a Application Gateway in front of the app service, which required me to place the certificate on the gateway. The entrypoint for all users is then an AG, and Azure does not handle creation/maintenance of certificates for their AG services (at least not at the time of writing this or to my knowledge).

So how do we solve this?

We "simply" need to access the container that the App Service is running on, run a certbot client on it to request certificates from Let's Encrypt, download the certificate and upload it to our AG. This seems rather simple, however I encountered a couple of issue.

New updates to the azure CLI seem to have simplified the process a bit!

az webapp ssh -n <APP-SERVICE-NAME> -g <RESOURCE-GROUP>
SSH to Azure App Service

Next - install and run the certbot

apk add certbot
certbot certonly -d <DOMAIN> --manual --preferred-challenges dns
Install and run certbot

Follow the instructions prompted by the certbot. It will ask you to create a TXT record with a value. If you're using azure DNS, this is done in the DNS zone.

Add your new certificate to the Application Gateway

Azure requires a private certificate in the PKCS#12 format to secure custom domains, a format that certbot does not generate by default. It can however be created using the files that the certbot do provide.

Certbot creates and stores the files needed in the /etc/letsencrypt/live/yourdomain.com/ directory.

# Create temporary folder
mkdir /tmp/sandbox -p
cd /tmp/sandbox

# Copy the files to a temporary folder
S=/etc/letsencrypt/live/<YOUR-DOMAIN>
cp $S/chain.pem $S/privkey.pem $S/cert.pem .

# Change ownership of files
chown <USER-NAME> *.pem

# Install openssl
apk add openssl

# Create the private cert and save to certificate.pfx
openssl pkcs12 -export -out certificate.pfx -inkey privkey.pem -in cert.pem -certfile chain.pem
Create private certificate

The last command will prompt you for a password. Make a note of this password as it will be needed when you upload your certificate later.

Finally - upload your brand new certificate to the App Service

This should be easy, right? I thought so..

This is a janky workaround and I would prefer to have a better solution. If you have a better solution, please let me know so that myself and anyone else reading this can learn from my mistakes :)

On the app service container convert the certificate.pfx to base64 and copy the output to your clipboard

cat certificate.pfx | base64

On your local machine decode the data into a new file

echo "<BASE64-CERT>" | base64 -d > certificate.pfx

Now you can upload the certificate to Azure

Personally, I store my certificates in Azure keyvault, but they can also be uploaded directly to the Application Gateway!

If you've done this yourself and have alternative solutions, I would greatly appreciate it if you share.