The process of acquiring TLS/SSL certificates has never been one that I'd call smooth. Its certainly gotten easier and cheaper over the years - I remember once having to prove I received a piece of physical snail mail to satisfy a certificate authority - but there's still plenty of room for improvement.


> Aside: SSL (Secure Sockets Layer) is the name of the proprietary protocol originally developed by Netscape. When the IETF improved and standardized the protocol in 1999 with RFC 2246, they renamed it TLS (Transport Layer Security). To this day the names SSL and TLS are used interchangeably even though they are technically different.


Let's Encrypt

This is where letsencrypt.org comes in. Let's Encrypt is a new certificate authority backed by some of the internet's biggest players, including: the Electronic Frontier Foundation, Mozilla, Google Chrome and many others. Let's Encrypt eliminates the complex process of manual certificate creation, validation, signing, installation and even renewal by instead leveraging an automated DevOps style approach with open source command line tooling built upon an open standard called ACME (Automated Certificate Management Environment).

At a high level, the ACME protocol is surprising easy to understand. It's already well documented on the Let's Encrypt site, so I won't take the time to recap it here.

If your web site is hosted on a platform that's already supported (e.g. Apache running on a recent Debian-based operating system), these three simple commands will both obtain and install a certificate for you:

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto --apache -d example.com -d www.example.com

This example illustrates just how easy using Let's Encrypt can be. Of course, some scenarios might be more complex, but the documentation for Let's Encrypt is quite good, and will walk you through all the various options.

Let's Encrypt entered public beta last month, and while they already support several popular platforms (Apache, Nginx), and have a growing list of community built plugins, my platform of choice, IIS on Windows, is yet to be officially supported. 😞

But remember how I said Let's Encrypt was based on an open standard called ACME? Well that's where things get interesting...

Let's Encrypt on IIS

In August of last year, Eugene Bekker began work on ACMESharp, a .NET based library and PowerShell client for the ACME protocol.

Don't like PowerShell? That's fine. Bryan Livingston built on top of ACMESharp and created letsencrypt-win-simple which uses the plain old Window's Command Prompt. To get a feel for what's involved, here's the command line arguments:

LetsEncrypt.ACME 1.0.5795.26498
 Let's Encrypt
  --baseuri         (Default: https://acme-v01.api.letsencrypt.org/) The address of the ACME server to use.
  --accepttos       Accept the terms of service.
  --renew           Check for renewals.
  --test            Overrides BaseURI setting to https://acme-staging.api.letsencrypt.org/
  --help            Display this help screen.
  --version         Display version information.
  --centralsslstore The path to the central ssl store to use (not in yet in a released version)

Shy on the command line and prefer a graphical tool? WebProFusion built a GUI over ACMESharp called Certify, which is currently in alpha.

Certify

The point is, if you're running your own IIS based web server, you can get a Let's Encrypt certificate via several different clients; just choose the one your most comfortable with.

But what if you don't run your own web server? What if, like me, you've bought into this whole "cloud thing" and host your sites on Azure? Don't worry, Simon J. K. Pedersen has you covered.

Let's Encrypt on Azure Web Apps

With 706 votes, "Add support for free SSL certs like those from Let's Encrypt" is one of the highest rated suggestions of all time on the Azure Web Apps Feedback Forum. You see, as nice as the community built Let's Encrypt clients mentioned above are, we've still had no way to run them on Azure's PaaS offerings.

That was true until about a week ago, when Simon ingeniously packaged up ACMESharp in an Azure Site Extension called _Azure Let's Encrypt_, and published it to the Azure Site Extension gallery. In fact, he's done such a good job with it that Azure team member Nir Mashkowski closed the forum suggestion calling it "community solved".

I've tried the extension out and I can attest that besides a bit of polish needed here and there, it works and it's really nice. I'll use the rest of this post to cover how to get it up and running.

Prerequisites

There's a few things required in order to get Let's Encrypt running on Azure Web Apps. To be fair most of these are requirements for SSL/TLS in general, regardless of the certificate authority.

1. Scale Up

First, you'll need to make sure that you Scale Up your App Service Plan from the Azure Portal settings, choosing that any plan that allows SNI (Server Name Indication) and Custom Domains / SSL, which is anything above Basic.

Scale Up

2. Custom Domain

Next, a custom domain name (not {my site name}.azurewebsites.net) is required. You can buy a domain name from any registrar you like. For example, I usually use hover.com to register my domains. Once you've purchased a domain, you'll need to configure it from the Custom domains and SSL panel in the portal.

3. Storage Account

The Azure Let's Encrypt site extension leverages a feature of Azure Web Apps called WebJobs. WebJobs persist various bits of state over time, which requires a Storage account to be created.

4. Application Settings

With Storage account in hand, go to Application Settings in the Portal and add two App Settings to the web app in question called AzureWebJobsStorage and AzureWebJobsDashboard. Set the value of these two settings to your storage account connection string, which looks something like this: DefaultEndpointsProtocol=https;AccountName={storage account name};AccountKey={storage account key}.

5. Register a Service Principal

I had never registered a Service Principal in Azure before, and unfortunately, I found this to be the most cumbersome prerequisite of the batch. The good news is that once you've completed this step, you're in the home stretch.

First, you need to install the Azure PowerShell module, which can be done though WebPI or the PowerShell Gallery.

Once installed use a PowerShell console to login to Azure:

Login-AzureRmAccount

If prompted, use the credentials you usually use to login the Azure Portal. If you have more than one Azure Subscription, you may have to pass the -SubscriptionId you'd like to login with as well.

Next, store a unique URI and secure password into a couple variables:

$uri = 'http://{some random name}'
$password = '{some strong password}'

With those set, create a new application:

$app = New-AzureRmADApplication -DisplayName {some display name} -HomePage $uri -IdentifierUris $uri -Password $password

Then a Service Principal for the new application:

New-AzureRmADServicePrincipal -ApplicationId $app.ApplicationId

Finally, assign the Contributor role to the Service Pincipal:

New-AzureRmRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $app.ApplicationId

While you're still in the PowerShell conosole, run $app.ApplicationId and save the GUID that is displayed. Later on it will be refered to as your ClientId and the value of $password will be refered to as your ClientSecret.

With the Service Principal properly registered, Azure Let's Encrypt will be able to use the Azure API's on your behalf to configure certificates.

Setup

With the prerequisites out of the way, we can install and configure the site extension.

1. Install Site Extension

To install the Azure Let's Encrypt site extension, open your site's SCM page at the url https://{your site name}.scm.azurewebsites.net. In my screen shots you'll see that I'm using a site called glutlybeta, which is a small side project of mine that never quite made it out of the starting gates.

If authentication is required, log in with the same credentials you'd use to access the Azure Portal.

The SCM site is a treasure trove of useful information and tools. If you haven't seen it before, check out my Azure Web App Secrets Exposed presentation on Vimeo. (I also cover what a site extension is in that video, if you were wondering.)

In the SCM site's main navigation, click on Site extensions, then the Gallery tab and search for "Azure Let's Encrypt". Find it in the list and install it by clicking the + button.

Install

Once the site extension has finished installing, you'll be required to restart the site. After the restart, click the triangle Launch button that replaced the extension's install button.

Note: If you get a "No route registered for '/letsencrypt/'" error, go to the portal, Stop then Start your site (not Restart), and try again.

2. Configure Azure Let's Encrypt

The Azure Let's Encrypt site extension will greet you with this, slightly intimidating screen:

Authentiation Settings

It's a tad confusing, but don't fill in the boxes you see near the bottom of the screen. Instead, go back to the Portal's Application Settings screen and input App Settings for letsencrypt:Tenant, letsencrypt:SubscriptionId, letsencrypt:ClientId, letsencrypt:ClientSecret and letsencrypt:ResourceGroupName with the values as described by the table above (highlighted in red).

Finding the Settings

Some of the values can be found very easily in the portal:

  • letsencrypt:Tenant is highlighted in the above image as #1.
  • letsencrypt:SubscriptionId is #2
  • letsencrypt:ResourceGroupName is #3

The other values come from the Service Principal that was registered in the prerequisites:

  • letsencrypt:ClientId is the GUID from $app.ApplicationId
  • letsencrypt:ClientSecret is the value from $password

When you're done, you should have something that looks like this in the portal:

App Settings

Once the App Settings are saved, refresh the Azure Let's Encrypt page and the form field boxes will be automatically filled in.

Click the Next button at the bottom of the screen. If everything is configured properly, you'll be presented a page showing a list of the Hostnames, SSL bindings and Certificates form your site.

Click Next on this screen to finally get to the last step: requesting and installing a certificate.

3. Request and Install a Certificate

If you've made it this far, the good news is that this step is the easiest to complete.

Request and Install Certificate

Select the Hostname you'd like a certificate for from the drop down menu, enter your email address and click the Request and Install certificate button.

(Don't check the Use Staging option, it's mostly useful for testing Let's Encrypt without running into their rate limits.)

In the background, the site extension uses ACMESharp to obtain and verify a certificate from Let's Encrypt. Once it has the certificate, it leverages Azure API's to automate configuring the certificate in IIS using the provided Service Principal credentials. Let's Encrypt never recieves the Service Principal credentials.

4. Success!

Once complete, you can browse to the HTTPS version of the hostname you selected. For me, I browsed to https://beta.glut.ly. As long as you don't have any mixed content issues (HTTP resources on the HTTPS page), you'll see the familiar "Secure Connection" padlock and notification.

Secure Connection

Not only do I have a Secure Connection, but a quick scan through the Qualys SSL Labs Report shows that I have a very good configuration to boot.

Qualys SSL Labs Report

5. Certificate Renewal

If you dig into the details of the certificate on https://beta.glut.ly, you'll see that it expires on April 19th. That can't be right, it's just three months from now!

Well, that's part of Let's Encrypt's model. They issue certificates with much shorter lifespans than typical certificate authorities, which can actually improve security. Also, because acquiring certificates is so easy, it doesn't end up being that big of an issue.

In fact, the Azure Let's Encrypt site extension will automatically renew your certificate 14 days before it expires - which means you shouldn't have to worry about certificate renewals at all! To do so, it internally sets up a continuous WebJob which does the work of making sure the certificate is renewed before it expires.

WebJobs

If you follow the link to the url listed under the "Logs" column, you'll even be able to see the status of the job and when it last ran:

WebJobs Dashboard

Wrapping Up

It's awesome to know that it's so easy (and free!) to get SSL/TLS running on our Azure Web Apps now. Yes, there are a few hoops that need to be jumped though, but Azure Let's Encrypt is in it infancy - currently only at version 0.2.3. I fully expect the community to continue to refine and improve this site extension - and if you'd like you can get involved and contribute to the project directly on GitHub.

Update - Three Months Later...

It's now been three months since I installed my Let's Encrypt certificate with the Azure Let's Encrypt Site Extension. Here's a quick update on how things have been going:

  • Let's Encrypt sends out emails a few weeks before your certificate is about to expire to remind you to renew it. I thought that was a nice little touch.
  • I half wittingly canceled my glut.ly domain name (but still have glutly.com). This seemed to cause some fits for the site extension, so much so that when I logged into the Azure Portal, I saw this message:

Certificate Expired - I was a bit disheartened that my certificate was able to expire, but when I dug into the Azure WebJobs logs, the error made it clear that the problem was with trying to resolve the now expired domain name. Oops, my bad... - Once I removed the glut.ly domain name binding from the Azure Portal, I was able to get a new certificate issued without a problem. - I also took the oppertunity to update the site extension, which has gone though several rounds of improvement since I wrote this. Updating was very easy from the SCM Site Extension Gallery:

Update Button

Three months in and I wish I could have reported that my certificate was just automatically renewed as expected, but given the fact that I canceled my domain name, I'm not too upset that it didn't. I will say though, that once I removed the domain from Azure, the Azure Let's Encrypt Site Extension was still the easiest way to provision a certificate - getting to this in about 2 minutes:

Certificate

I'll follow up again three months from now and report how that renewal goes. I'm hopeful that everything will run smoothly.