As you may be well aware by this, Microsoft’s Azure gets me rather excited. That’s not without merit IMHO, it’s a sensational product for all the reasons you can read about in the blog posts at the end of that link. Almost without exception, when I get a question about Azure I have an awesome answer ready to go. Almost…
The one question that throws me is the one I was once again asked just recently:
I can only justify paying for a Shared Azure website but I need SSL – what do I do?
I have not had a good answer for this, including the one I usually give – “Maybe Azure is not for you”. Now that’s sad because Azure does many wonderful things and with the increasing ubiquity of SSL, offering a service tier which explicitly denies it is really unfortunate. Here’s where the problem lies:
Thing is though, that Shared tier is less than $10 a month and if you have to go to Basic you’re looking at $56 a month which is a hell of a mark-up. One thing worth mentioning is that you can host unlimited websites on that Basic plan for your $56 (assuming the logical machine underneath it can handle the load, of course), but you’ve got to have a handful of sites before you can justify that and then you still need to pay for SSL on top of that. The bottom line is that you’re looking at nearly a seven-fold increase in cost over Basic and that simply rules it out for many people. Or does it?
The CloudFlare value proposition
You may recognise the CloudFlare name in the context of DDoS protection and they regularly feature as a means of mitigation against the attack. They don’t host your content, rather your traffic is routed through them which gives them a great deal of control over which packets they let through and which ones they reject. Once they’re handling traffic it means they can also do a bunch of other things like provide additional security services, optimise the content and distribute static assets via CDN. There’s a bunch of really, really neat stuff they can do that I’ll talk more about another time.
For now though, here’s what I’m interested in:
“Easy” SSL sounds good because quite frankly, it’s usually a big clunky. But it’s the pricing that really caught my attention, particularly the starting price:
Starting from free – that’s just what people on a Shared Azure Website budget need! Let’s make it all work.
Provisioning the Azure website
Let’s jump right into it and I’ll spin up a new websi… whoops, I mean “Web app” (thank you Azure name change department for changing this right in the middle of recording my new Azure course on Pluralsight!) and I’ll put it on the shared pricing tier:
There actually wasn’t an existing site called “cloudflare” so yeah, it’s mine now :)
Once it’s created I can see it running on the Shared tier with the discounted pricing offered by my MSDN subscription:
I can also see a new site running at cloudflare.azurewebsites.net:
That’s about as easy as creating a website gets! But there’s one more thing – I can also do this:
Hurrah, it’s already running SSL! Except that’s Microsoft’s wildcard certificate and it only works on *.azurewebsites.net:
The whole point of this exercise is that we want SSL on our own domain, not Microsoft’s. For this we need CloudFlare but before doing that, we also need a domain so let’s go and grab one of those right now.
Setting up the domain
I use DNSimple for all my domain things and if you’ve any doubt whatsoever as to whether you should use them or, well, let’s just say “A large register with some very attractive faces”, read this.
Moving on, I forked over a whole $14 to bring you this post (you know there’s a donation page on my Have I been pwned? service…) and I bought cloudflareonazure.com. DNSimple makes it exceptionally easy to configure the domain for Azure, you just enter the name of the site and you’re done:
At least that’s the DNSimple piece done, we still need to bind it to Azure so back to the portal and drop the domain in:
Remember you can only set up a domain for an Azure Website once it has the awverify CNAME on it but fortunately DNSimple did this for us automatically in the earlier step so we get a green tick as soon as the domain is entered. Save that, test and…
Success! Note that I captured all this pretty much in real time too, no waiting 24 to 48 hours for DNS to update (although I’m sure propagation will be slower to some name servers).
Final thing on domains – you can’t do this:
This is serving Azure’s wildcard cert we saw earlier and it’s not valid for cloudflareonazure.com which is really the heart of the problem we’re solving here. To get this working on a Basic website we need CloudFlare so let’s head over there now.
Setting up CloudFlare
After you create an account on CloudFlare, you can jump right into adding a new website. Now remember, if I was on a Standard Azure website I’d just go and get a free certificate from StartSSL and be done with it, but of course the whole purpose of this exercise is to make it work on a Shared site.
Edit: StartSSL is now well and trul dead, plus you can now get free certificates on the Azure App Service.
Let’s start with this:
CloudFlare thinks for a bit and shows a countdown while playing a video with instructions effectively saying it’s going to copy over all the DNS records:
Once everything is wrapped up, here’s what it found:
So a couple of things here. Firstly, it successfully found the A record, CNAME and TXT entry DNSimple added so that Azure could verify the domain. Secondly, I don’t really care about the MX record as there’s no mail on this domain anyway so I removed it rather than allow CloudFlare to handle any errant mail sent to the domain (including things like domain ownership verification emails…)
That done, CloudFlare offers to default me to a $200/m plan:
That’s a little incommensurate with a Shared Azure website at $9.67 a month so let’s take that all the way down to “Free” which gives us this:
I’ve just gone with all the defaults here. There’s actually a really interesting story around perf that I’ll save for another time, the main thing right now is that SSL is “on” which is just great.
The last thing we need to do is change name servers from DNSimple to CloudFlare. This is so that CloudFlare can manage routing for CDNs and optimise the traffic. There are other options available if you don’t want to effectively hand over the keys to you domain name resolution, but we’re keeping it simple here and going with the recommendation:
Hey look at that – name servers with personalities! There’s actually a story behind the naming convention which makes good sense when you read it.
DNSimple makes it dead easy to change name servers (there’s a theme here with these guys…) so here’s what my records now look like in their management interface:
That done, we now play the name server waiting game:
If you’re impatient like me, you can keep hitting the “Re-test” link:
Eventually, things will go green:
Once DNS magic successfully propagates, nothing looks any different when loading the HTTP version of cloudflareonazure.com, but hitting HTTPS results in this:
And there we have it – a valid cert on a site being served by the Azure Shared website service!
Strengthening the CloudFlare SSL implementation
As it stands, we have what CloudFlare calls “Flexible SSL” and it looks like this:
There’s transport layer protection between the client and CloudFlare but not between CloudFlare and the server. This is both good and bad; good because it protects the user from many of the lower-hanging risks such as their wifi or DNS being hijacked or their ISP pilfering data, but bad because everything between CloudFlare and Azure is in the clear. That’s a show-stopper in some cases: any requirement for data encryption in transit is going to leave you short as there’s a great big whack of the network segment which is not unencrypted.
If we jump into CloudFlare’s settings for the site, we’ll see Flexible SSL represented:
However, we can step it up to Full SSL:
Per the picture, the dependency here is that the server the site is running on has to support SSL. This can be a self-signed cert so CloudFlare clearly won’t be validating it, but it does mean you’ve got encrypted traffic.
But of course we’ve already got a valid cert on the Azure site by virtue of the *.azurewebsites.net one. Because it’s a valid cert you might think we could go to Full SSL (strict):
Except we can’t do that because if we do, we get this when we try to load the site:
As you can read on the support page, one of the requirements for Full SSL (strict) is:
The requested domain name (hostname) is in the Common Name or Subject Alternative Name configuration of the certificate
So back to Full SSL and everything plays nice again because the Azure cert is no longer checked as being valid for the custom hostname. We could always get a cert for cloudflareonazure.com and load it into Azure and use the strict approach, but then we’re pushed into at least the Basic website tier which entirely defeats the purpose of this exercise!
So this approach is satisfactory, however, it is Microsoft’s cert and it is valid for a very large number of websites (effectively anything running on the Azure website PaaS service) and that won’t sit well with everyone. But perhaps more significantly, CloudFlare is obviously not validating it as it wouldn’t check out for the domain and we’d get that last error we see above. But let’s also not lose sight of the objective here – this is about getting padlocks in address bars for less than ten bucks a month and when that’s the value of your site, this cert setup is isn’t going to be worrying you.
It’s SSL, but is it good SSL?
SSL ain’t SSL. There’s a lot a variety in what constitutes a good implementation and a favourite test is Qualys’ SSL Labs test. Running it over the Azure website SSL implementation, we get this:
Azure gets penalised for supporting the RC4 cipher which has long been considered inadequate. There’s also no forward secrecy supported so it cops a markdown for this too. This is all just for a standard website with nothing in it, we can actually get the Key Exchange rating up a bit by implementing an HSTS header. Microsoft needs to get with the times here and I can only assume they haven’t because of concerns of what might break for some customers. It’ll happen though, it’s just a matter of time.
CloudFlare, on the other hand, fares somewhat better:
The main things here are no RC4 and support for forward secrecy. This creates an interesting risk conundrum for those worried about the earlier point on CloudFlare being able to man in the middle the traffic and not validating the Azure cert; is that a stronger holistic position than having Azure serve the cert but via a weaker SSL implementation? It would depend on where you believe threats will primarily come from but in most cases you’d be far more worried about the traffic on the client’s end than you would the traffic between CloudFlare and Azure.
So yes, it’s good SSL but it poses a different risk discussion.
But what about performance?
Ah, good question! Per the last diagram above, your traffic is now routed through CloudFlare so what does that do to perf? I mean isn’t it always going to be slower due to having them in the middle?
With the caveat that this is going to differ massively based on factors such as the design of the site and the location of the user, no, perf doesn’t take a hit. Let’s quantify that.
Here is a speed test from Melbourne down here in Australia to cloudflare.azurewebsites.net or in other words, hitting the site directly and not going through CloudFlare:
And here is one to cloudflareonazure.com which is the domain bound to CloudFlare:
A few things here and firstly, let us allow the penny to drop on an important fact: CloudFlare is modifying the page. Yes, these were requested over HTTP but it’s the same result over HTTPS and it’s possible because that’s where the SSL for cloudflareonazure.com is terminating. Requests and responses are decrypted on their end and as you can see by virtue of the additional file in the CloudFlare response (cloudflare.min.js), the page is being modified. This also means my site is now running their script.
Despite this though, CloudFlare comes in a fair bit faster. Of course the caveat here is that these figures differ wildly on each request because that’s just the nature of the web. In this test, the Azure request spent a lot of time on DNS compared to CloudFlare, other results are different. But one other oddity kept jumping out and it was this:
See the size of the first request? It’s 60kb more than before. Same site. Same file. Same scheme. In fact consistently, the request to the Azure domain returned inconsistent results (yes, I know, consistently inconsistent). Confused, I reached out to good friend and performance extraordinaire Nik Molnar. He explained it like so:
By default, IIS does not compress a file the first time you access it. You have to request a file two times within 10 seconds before it will compress. Even then, that will just kick off a "background process" to compress the file. It won't begin serving the compressed file until the background process is finished.
CloudFlare was obviously keeping an optimised copy whilst IIS was doing its default compression thing on the static .html file that’s found in every new site.
Now of course you’d expect a CDN like CloudFlare to serve content more efficiently than just grabbing it from the one single global source that is my West US instance of the website and I don’t want to get too bogged down in the perf side of things here. The point is that you’re almost certainly only going to gain performance with CloudFlare in front of any single location website, particularly once you start configuring it’s dedicated perf features and standing up real world websites on it. But that’s a story for another time.
Let’s Encrypt: SSL for everyone
By now, really, this shouldn’t all be a thing. I mean we shouldn’t have to be mucking around and penny pinching just to secure website traffic. That’s by no means a problem with Azure alone, SSL remains a “premium” feature for many hosting environments. However there is hope on the way via the Let’s Encrypt initiative:
This is a joint venture backed by the EFF and Mozilla (among others) and the hope is pretty much what’s in the image above – make it free so the cost barrier goes away, make it automated so all the mucking around with certs goes away and make it open so that the traditional CA model goes away. My hope is that if you’re reading this in the future (relatively speaking), Let’s Encrypt has actually gained some serious traction and it enables you to simply click the “Add SSL to my site automagically” button in Azure. Whether it’s this initiative or a general groundswell of hosts making SSL more easily achievable for all is yet to be seen, but certainly the traditional way of creating, charging for and managing certs needs to die a fiery death.
Learn more about Azure on Pluralsight
As I mentioned earlier, I’ve just launched a new Pluralsight course and it’s actually the first one I’ve done that isn’t about security! Modernizing Your Websites with Azure Platform as a Service contains a heap of practical lessons on using Azure Websites and Azure SQL Databases (both are Microsoft’s PaaS offerings) and a significant amount of the content in that course has come from real world experiences tackling problems just like this one. It’s very practical, very hands on and a great resource if you want to learn more about the mechanics of how to use Azure websites and databases in the real world.