I just had a rash of questions about SSL and Azure Web SItes/Web Apps (just for clarity, Azure Web SItes was renamed to Azure Web Apps a few weeks ago). I’ve been looking for an article or post to send people to and am quite amazed at the lack of info. Yes, there are plenty of posts and articles but you have to read quite a few of them in the right order if you want to fill in the blanks. I aim to address all the questions you might ask in this post.
First – I’d recommend you read my post on how SSL actually works first. You might then find, you don’t know enough about the relationships between keys, certificates and signatures, so I’d recommend you watch my crypto primer video.
There is a video of the whole article here...
SSL is already enabled on your Azure WebSite/WebApp
Yes, that’s right. Let’s imagine you go to the portal and create an entirely naked website in the Free tier called plankytronixx.azurewebsites.net, it will already be enabled for SSL. You can just type in to the browser address bar https://plankytronixx.azurewebsites.net and it will work just fine.
I created plankytronixx.azurewebsites.net 90 seconds ago, as shown above in the figure. I’ve done absolutely nothing to the site since I created it. When I connect to it over SSL it works! And this is a Free WebSite/WebApp.
You can see the certificate that is being used to protect it. More interesting is the cert path up to the Microsoft Internal Corporate Root….
Of course the disadvantage of this SSL implementation is that you have to use the .azurewebsites.net address. Even if you map to a new custom domain, like say, plankytronixx.co.uk, the .azurewebsites.net configuration is still there, it still exists, you can still connect to it… But users might get suspicious if you ask them for a password over SSL and they now appear to be on an entirely different site. Most of them won’t know how Azure works so their suspicions would be reasonable…
You can actually see in the screenshot above that a wildcard cert exists for every single Azure Web Site/Web App in the world. *.azurewebsites.net…. Plus – this certificate is included in the price (and that means the Free tier as well!). SO free SSL is available, but but but…
Custom Domain Names
This is the bit where it gets a bit more complicated and this is the bit everybody talks about: when you want to SSL-enable a site to give a URL like https://plankytronixx.co.uk… First things first – you can’t get a custom domain name in the Free Tier. So you can now start to see where the confusion comes in? People say SSL is not available for Free sites because of that. But as you’ve just seen, you do get SSL, only it comes with a collection of limitations. You have to move up to Basic or Standard to get SSL on custom domain names.
To set up a custom domain name you have to set up a mapping between the IP address of the web server and the DNS name. You do this at a Domain Registrar. I use Go Daddy. The record you add is called an A (address) record. So plankytronixx.co.uk might get mapped to say 184.108.40.206. It’s dead easy to configure this at a domain registrar – you just update the zone file. They’ll give you some kind of tool to do it, usually web-based. This is what it looks like on Go Daddy…
To get Azure to recognise it involves a hurdle to jump. If you just update the A record and nothing else, Azure will give you this error:
It’s because Azure wants to be assured that you “own” this domain. It wants you to prove that you own it. It does this using the “azure websites verify” process – more normally known as awverify.
Anatomy of an HTTP GET request
Let’s have a quick review of what happens when you type http://plankytronixx.com.uk in to a web browser.
- The browser does a DNS query against the name plankytronixx.couk.
- The DNS server returns the IP address – let’s say it’s 220.127.116.11.
- The web browser formats an HTTP GET and sends it to IP address 18.104.22.168.
- In the header of the GET request is the host name – plankytronixx..co.uk
- Azure is sat at IP address 22.214.171.124; it inspects the host name in the header and looks to see if it has a site that matches the name. If it does…
- It returns the page.
- If it doesn’t – you get the error in the screenshot above.
When you are setting this up for the first time, Azure gives you a piece of DNS information which you add to your DNS registrar’s zone file for your domain (plankytronixx.co,uk in this case). When you set up the Azure end of the configuration, Azure sends a query to your domain registrar and expects to see the DNS information it gave you. By this mechanism you are proving that you have control of the records in the domain you are trying to configure: that you “own” the domain.
If this works, any requests received in steps 5 and 6 above return the correct page. If you can’t prove you “own” the domain, Azure won’t configure the domain for you and it returns the blue-page 404 you can see in the screenshot above.
Proving Domain Ownership
To prove you own the domain, Azure gives you some instructions on the Domains configuration page…
I’ll go through it assuming the custom domain name I want is plankytronixx.co.uk and the default Azure Website/WebApps name is plankytronixx.azurewebsites.net.
- Add a CNAME record called “awverify” and point it to “awverify.plankytronixx.azurewebsites.net”. I’m showing this in the Go Daddy screen below:
- You might have to wait a few minutes (or even a few hours in some cases) for the DNS records to propagate (don’t forget to save the changes)…
- If you get it right, when you type your domain name in to the Azure configuration page – you’ll get a little green tick in the text-box.
- If something has gone wrong (or the domain update hasn’t yet propagated), you get a little red exclamation mark.
- You can now save the configuration. You’ll see both the custom domain name and the raw Azure Websites/WebApps name in the portal screen.
Essentially what Azure did during this process was send a DNS query for awverify.plankytronixx.co.uk and it expected to see back, exactly what it told you to configure in the first place – awverify.plankytronixx.azurewebsites.net. If it gets that back, it reasons that you must have the power to make that record change at the DNS registrar and you must therefore own that domain name.
Custom Domain SSL
Now you have a custom domain name, you can set up SSL for it (in this case, plankytronixx.co.uk). But there are 2 types of SSL certificate. Traditional certificates, known as IP-based SSL certs. And SNI certs (Server Name Indication).
Let’s go back to 1994 when SSL was first introduced by Netscape. There weren’t really all that many web servers running. And the assumption made at the time was that each web site ran on a single server with a single IP address. But these days, IP addresses are very scarce resources. It’s not unusual to have many thousands, or even tens of thousands of web sites all running at the same IP address. One of the things that helped this was the introduction of the host name in the HTTP header as mentioned in Anatomy of an HTTP GET request above.
You can still use IP-based certificates for SSL with Azure. But there’s a 1:1 mapping between the certificate and the site it’s attached to. For an IP-based certificate, it will run on exactly one IP address. You’d think it must be possible to use the host-header trick I mentioned above. But the trouble is that the SSL session is set up before the HTTP request is executed. It’s therefore not possible for the server to see what site to route the traffic to. When there’s only one site to send the traffic to, there’s no decision to make. But it means the site needs to have its own dedicated public IP address. The disadvantage is that it costs more as a result.
SNI certificates were introduced to get round the problem of the 1:1 mapping between sites and IP addresses. When an SNI certificate is used, the browser sends the host name as part of the SSL setup. But you’ve probably already spotted the problem? Older browsers that don’t support SNI certificates won’t work. So you have to decide between high coverage and higher costs (IP-based certs) or lower coverage and lower costs (SNI-based certs). Your ball…
The certificate needs to be in a format that can transport not only the public key, but also the private key. This usually means there is some form of protection on the file that contains the certificate, like a password. But there’s another problem. Normally, the server on which the certificate sits will generate both the public and the private key. You will then send the public key, plus some information about your site (it’s DNS name for example) and yourself as the site admin. All this gets wrapped up in to a Certificate Signing Request (CSR). Azure Websites don’t give you access to the underlying server (in the way that say Cloud Services do). You keep the private key, well, private (you don’t even reveal the private key to the certificate provider). You add the private key in to the certificate file. THe file has to be in .pfx format.
Probably the easiest way to do this is to fire up IIS Manager on a machine and create a Certificate Request on it. Open the root then on the main pane double-click Server Certificates. You’ll see an option in the panel on the right hand side to Create Certificate Request. Go through the wizard and save the text file in a convenient location. This process generates a public and a private key. The public key is in the CSR text file. The private key is kept on the machine and is, well, private.
Now you need to present this Certificate Request to a Cert Issuer such as VeriSign, InstantSSL, Thawte and so on. Or your own CA… Quite a few of the providers will give you a 30-day or 90-day trial certificate. Typically if you apply for a certificate for say, plankytronixx.co.uk, you’ll need an email address at plankytronixx.co.uk. Each issuer has its own process: some ask for lots of information, others ask for a little. What you will end up with is a signed certificate. They will email the response to you.
Remember that when you created the request, the private key was kept private? Well, it’s still hanging around. When you complete the certificate request in IIS, it will marry up with the file the CA sent you in email. You go back and click "Complete Certificate Request.
You’ll be asked for the file the CA sent you. Put all the details in and click OK.
You now get the option to export the certificate and it and that’s a good thing because you can export the certificate in .pfx format which is exactly what Azure WebSites/WebApps requires.
The easiest way to do this is to find your certificate in the Server Certificates section of IIS. Identify your certificate, right-click it and select Export. You’ll end up with a .pfx file.
You go to the Azure Portal and click upload a certificate on the Configure page (this is as long as you are in the Basic or higher tier).
That’s not the end of the process. You now have a certificate in Azure – to get your Azure Website/WebApp to use it – you need to configure the SSL Bindings section of the page. You’ll specify which DNS name you want to protect with SSL, you’ll select the certificate you just uploaded and, depending on the type of cert you bought, you’ll select either SNI or IP based certificate.
Once you save those settings you’re done. Try it out by connecting a browser to your site. If you used an EV certificate, the address bar turns green. A padlock icon appears in the address bar of most browsers. If you click it in IE you can actually view the certificate plus its certification path – all the way up to the root authority.
I hope you found this useful. Remember, I made a video of how to do it here. Click Here.