This may have been one of the most exciting things (from a web site owner's perspective) to happen in quite a while, and something I think the industry has been hoping would happen for a long time. Free SSL certificates for everyone! With the creation of letsencrypt.org, an organization whose goal is to make certificate usage free and easy, we are finally freed from the shackles of organizations like GoDaddy or Verisign who charge (sometimes exorbitant) fees just so that an individual or organization can have the ability encrypt their web traffic.
Now the tricky thing with Let's Encrypt is the automation part. Because of how Let's Encrypt uses automation to provision certificates, it was originally built to work with Apache/Linux based web servers. This made anyone who used Azure or IIS feel like the kid on the outside looking in. Luckily, nothing that Let's Encrypt does is voodoo magic and it didn't take long for the Azure community to build the necessary parts to get this working in Azure.
There is a fantastic post from Nik Molnar that describes how to get this working on Azure. I definitely want to talk about Let's Encrypt on Azure, but I don't want to take away from Nik's post, so go there and check it out.
What I'm going to add though is a bit of PowerShell goodness around some of his steps that makes it a bit easier to get Let's Encrypt up and running on your Azure website. I'm also going to add a couple tidbits about getting it working on ASP.NET Core.
Pre-requisites
Just going to re-iterate Nik's prerequisites:
- Scale up your Azure Website to at least an S1 (1 dedicated IP, 5 SNI)
- Acquire your custom domain. The {domain name here}.azurewebsites.net domains are all secured with by a Microsoft certificate so if you aren't planning on using your own domain name, you can just stop now.
- Create a storage account for the Let's Encrypt Site extension to use
- Put your storage account conne ction strings into two Application Settings on your website.
- Register a Service Princpal. This is the identity that is allowed to execute the web jobs the the site extension uses to do the work
PowerShell
Again, as per Nik's post, you'll need the Azure PowerShell module before we get started.
In an Azure .ps1 (script) or .psm1 (module), or in PowerShell ISE, paste the function below.
1 | function Set-AllAzureDetailsForLetsEncrypt() { |
After you've pasted this function into a PowerShell script file or directly into a session type in the following:
1 | $letsEncrypt = Set-AllAzureDetailsForLetsEncrypt -subscriptionId <Insert SubscriptionId Here> -uniqueUri "http://myapplication-091820398123" -strongPassword "P@ssw0rd" -displayName "Let's Encrypt Site Extension" -resourceGroupName "Default-Web-WestUS" |
You do not need to provide the SubscriptionId if your account/login is only associated with one subscription. Also, you do not need to provide a DisplayName if you don't mind the display name being "Let's Encrypt Site Extension". You must provide the other parameters.
Once you have run through the script, you should have an object in the $letsEncrypt
variable that has everything you need for entering the data in the Site Extension.
1 | $letsEncrypt |
Now you will be able to type $letsEncrypt.Tenant | clip
to get the TenantId for pasting into the Site Extension fields. You can do this for each
field that is required for the extension to run.
ASP.NET Core
ASP.NET Core (formerly know as ASP.NET 5/MVC 6) had a different approach to handling static files, which are required for Let's Encrypt to work. Basically, what happens is the WebJob gets some files from Let's Encrypt. Let's Encrypt will then use the DNS entry and this "well-known" location on your site to see if the files are there. If they are there, you own the domain, and the certificate can be approved automatically. If you didn't own the domain, and hadn't setup the Let's Encrypt Site Extension to do all of this work, none of this would have worked and it could be assumed that you do not own the domain.
If you look in your Kudo dashboard after the Let's Encrypt Site Extension has run, you'll see the following you your folder structure:
d:/home/site/wwwroot/.well-known/acme-challenge
And you'll see the challenge files in the last folder
The Thing I had Trouble With
I couldn't find a good example at the time of how to allow Let's Encrypt to get these .well-known files using ASP.NET Core. So I created a controller that basically returned the contents when asked for a specific route.
The URI that Let's Encrypt will look for these well-known files is http://{mydomainname}.com/.well-known/acme-challenge
1 | [ ] |
Update
At the time of this writing, I haven't had a chance to confirm if this works since the Let's Encrypt files do not have an extension. Handling Static Files in ASP.NET Core
That's It!
Hopefully, between Nik's fantastic post and this post, you should have a fairly good understanding of what has been happening, and you've got your ASP.NET Core site secured and up and running on Azure using Let's Encrypt!!!