Securing your Azure Web App with Let's Encrypt.

ope profile image Ope Adeyomoye ・5 min read

This post assumes that you have deployed your web app in a Docker container on Microsoft Azure's fully-managed App Service platform. It also assumes that, for some reason, you want to manually obtain an SSL certificate for your app, and manually renew it before it expires.

Before we get to certificates...

When you deploy your app on Azure's App Service platform, you automatically get a URL that can be used to view your app. It'll usually be in the form: https://your-app-name.azurewebsites.net. If you like the free domain and don't exactly see a need to use a custom domain, then you probably don't need most of the rest of this post. I'd suggest you turn on "HTTPS only" tho.

Chances are, however, you do want to serve your app using a custom domain. If you've not added a custom domain to your App Service app, please see Azure's docs on this and follow the steps there.

It could be much easier

Azure lets you create a free certificate and add it your App Service app at the click of a couple buttons. It's issued by DigiCert, managed by App Service, and renewed automatically.

If you'd like to use this instead of rolling your own, see Azure's docs on it and don't forget to turn on HTTPS Only.

Getting a certificate

Let's Encrypt recommends using the Certbot ACME client for certificate issuance. Certbot can automate certificate issuance and installation, but this post demonstrates using Certbot in manual mode.

First, let's install Certbot. On Debian 10+ systems:

$ sudo apt-get update
$ sudo apt-get install certbot

For other Debian versions, linux distros or different operating systems, please see Certbot's installation docs.

Issuing a certificate

Now, let's get an SSL certificate issued for yourdomain.com. On the command line:

$ sudo certbot certonly -d yourdomain.com --manual --preferred-challenges dns

That command:

  • via the certonly sub-command, tells Certbot to simply obtain a new certificate, and not install it on your local machine;
  • tells Certbot to use a DNS challenge. As opposed to an HTTPS challenge where you'd have to upload a certain file to a specific directory on your server, a DNS challenge requires you to add a DNS TXT record on your domain.

After a few simple questions, Certbot will ask you to create a DNS TXT record, usually under the name _acme-challenge.yourdomain.com, with a value it provides. Usually, you'll do this via your DNS provider. Please see your DNS provider's docs on how to create DNS records for your domain.

If it all went well, you should see a message like this:

 - Congratulations! Your certificate and chain have been saved at:
   Your key file has been saved at:
   Your cert will expire on <some-date>. 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

Add your shiny new certificate to App Service

To secure a custom domain for your web app, Azure requires a private certificate in the PKCS #12 file format. Certbot does not generate this file by default, but you can create it using some of the files it does generate.

Create a private certificate

For this, you'll need:

  1. your server certificate file;
  2. the private key for your certificate;
  3. the intermediate certificate from Let's Encrypt CA.

All those files can be found at /etc/letsencrypt/live/yourdomain.com/, and you can simply run the following commands to create your private certificate:

# create a staging area
$ mkdir /tmp/sandbox -p
$ cd /tmp/sandbox

# copy the needed files over
$ SOURCE=/etc/letsencrypt/live/yourdomain.com
$ sudo cp $SOURCE/{cert.pem,privkey.pem,chain.pem} .

# make the files your own
# assuming your username is ope...
$ sudo chown ope *.pem

# finally, create the private certificate,
# saving it to "certificate.pfx"
$ openssl pkcs12 -export -out certificate.pfx -inkey privkey.pem -in cert.pem -certfile chain.pem

That last command asks you to enter an export password. Please make note of that password since you'll need it when uploading your private certificate on Azure.

Upload the private certificate

From your Azure portal, navigate to your App Service web app and click on the "Custom domains" menu item. In the page that comes up, find the row that contains the custom domain you added and click "Add binding" under the "SSL Binding" column.

Alt Text

In the sidebar that comes up, click "Upload PFX Certificate"

Alt Text

Within the form that's displayed next, select the certificate.pfx file you created, and enter the password you chose.

Alt Text

Click "Upload" to proceed. The next screen should look like this:

Alt Text

Click "Add Binding" once you've selected the relevant options.

That's it! Once the deployment is complete on Azure, you can now navigate to your web app, via your custom domain, using HTTPS.

Clean up

You can't subsequently download your private certificate from Azure App Service, so you might want to store the local copy somewhere other than the system temp directory:

$ cp /tmp/sandbox/certificate.pfx /path/to/dir/

Once your private certificate is safe, you may clear out the sandbox:

$ rm /tmp/sandbox/ -R

Consider turning on "HTTPS Only"

Azure App Service has a little handy feature, called HTTPS Only, that helps redirect all of your app's HTTP traffic to HTTPS.

That makes sure that any client communication with your app is encrypted, and visitors aren't scared away with "Connection not secure" messages from their browsers.

To turn this on, head on to your App Service within the Azure portal, and click on the TLS/SSL settings menu item. You'll find the option there under "Protocol Settings".

Posted on by:


markdown guide

Thanks for this guide! I needed to do this manually for an Azure site for reasons I won't get into. All I had to do with your guide was change the preferred challenge to HTML in my case and followed all the instructions - got my certificate created and uploaded!


Awesome! Thanks a lot for your comment. Glad you found it helpful.