Running SSL with Azure Web Sites Today
If you’re a web developer working with ASP.NET, Node.js, PHP, Python, or you have plans on building your site in C++, Azure Web Sites is the best thing since sliced bread. With support for virtually every method of deployment and with support for most of the major web development models you can’t beat it. Until recently, SSL was the only question mark for a lot of web site owners, as WAWS doesn’t yet support SSL out of the box (trust me, it’s coming, I promise). The good news is that there’s a method of achieving SSL-secured sites now. In this blog post I’ll introduce the idea of a workaround my engineering friends in the Web Sites team call the SSL Forwarder, and to demonstrate how you can get up and running with an SSL-protected Azure-hosted web site in just a few minutes’ work.
First, I’d like to point out one very important point about the SSL Forwarder solution. This solution works, and we have a handful of community members actively using this solution to provide an SSL front-end for their web sites. So feel comfortable using it, but understand that this isn’t something you’ll have to do forever, as SSL is indeed coming as an in-the-box feature for Web Sites. If you love the idea of Azure Web Sites but the lack of in-the-box SSL support is a deal-breaker for you and your organization, this is a viable option to get you up and running now. However, the SSL Forwarder isn’t an officially supported solution, in spite of one being actively used by numerous customers. So if you set this up and you experience anything weird, feel free to contact me directly via the comment form below, or on Twitter, or by email (and I’ll give you my email address on Twitter if you need it). All that being said, I’ve heard from quite a few in the community who are using this solution that it has mitigated their concern and they appear to be running quite well with this in place.
Don’t panic when you see this solution. Do read the introduction, once you see grok how it all works, the SSL Forwarding solution is a whole lot less intimidating. I admit to having freaked out with fear when I first saw this. I’m no expert at most of the things involved in this exercise, but the Web Sites team literally put together a “starter project” for me to use, and it took me 1 hour to get it working. If I can do this, you can do this.
The idea of the SSL Forwarder is pretty simple. You set up a Cloud Service using the Azure portal that redirects traffic to your Azure Web Site. You can use all the niceties of Web Sites (like Git deployment, DropBox integration, and publishing directly to your site using Visual Studio or WebMatrix) to actually build your web site, but the requests actually resolve to your Cloud Service endpoint, which then proxies HTTP traffic into your Web Site.
The diagram to the right shows how this solution works, at a high level. The paragraph below explains it in pretty simple terms. I think you’ll agree that it isn’t that complicated and that the magic that occurs works because of tried-and-true IIS URL Rewrite functionality. In order to obtain the 99.9% uptime as outlined in the Azure SLA, you’ll need to deploy at least 2 instances of the Cloud Service, so the diagram shows 2 instances running. As well, the code provided with this blog post as a starting point is defaulted to start 2 instances. You can back this off or increase it however you want, but the 99.9% uptime is only guaranteed if you deploy the Cloud Service in 2 instances or more (and there’s no SLA in place yet for Web Sites, since it’s still in preview at the time of this blog post’s release, so you can host your Web Site on as many or as few instances as you like).
You map your domain name to your Cloud Service. Traffic resolves to the Cloud Service, and is then reverse-proxied back to your Web Site. The Cloud Service has 1 Web Role in it, and the Web Role consists of a single file, the Web.config file. The Web.config in the Web Role contains some hefty IISRewrite rules that direct traffic to the Web Site in which your content is hosted. In this way, all traffic – be it HTTP or HTTPS traffic – comes through the Cloud Service and resolves onto the Web Site you want to serve. Since Cloud Services support the use of custom SSL certificates, you can place a certificate into the Cloud Service, and serve up content via an HTTPS connection.
- A Azure Cloud Project
- A web site that’s used as a Web Role for the Cloud Project
- A web site that’s deployed to Azure Web Sites (you’ll want to replace this one with the project you’re deploying or just remove it, it’s just there as part of the sample)
Create the Cloud Service and Web Site
First thing is, I’ll need to create a Web Site to host the site’s code. Below is a screen shot of me creating a simple web site myself using the Azure portal.
Obviously, I’ll need to create a Azure Cloud Service, too. In this demo, I’ll be using a new Cloud Service called SSLForwarder, since I’m not too good at coming up with funky names for things that don’t end in a capital R (and when I do, Phil teases me, so I’ll spare him the ammunition). Below is another screen shot of the Azure portal, with the new Cloud Service being created.
If you’re following along at home work, leave your browser open when you perform the next step, if you even need to perform the next step, as it is an optional one.
Create a Self-signed Certificate
This next step is optional, and only required if you don’t already have an SSL certificate in mind that you’d like to use. I’ll use the IIS Manager to create my own self-signed certificate. In the IIS Manager I’ll click the Server Certificates applet, as shown below.
When I browse this site secured with this certificate, there’ll be an error message in the browser informing me that this cert isn’t supposed to be used by the domain name from where it’s being served. Since you’ll be using a realSSL certificate, you shouldn’t have to worry about that error when you go through this process (and I trust you’ll forgive a later screen shot where the error is visible).
Once that applet loads up in the manager, I’ll click the link in the actions pane labeled Create Self-Signed Certificate.
I’ll name my certificate SSLForwarderTesting, and then it appears in the list of certificates I have installed on my local development machine. I select that certificate from the list and click the link in the Actions pane labeled Export to save the cert somewhere as a file.
Then I find the location where I’ll save the file and provide it with a password (which I’ll need to remember for the next step).
Now that this [optional] step is complete I have a *.PFX file I can use to install my certificate in the Cloud Service.
Install the SSL Certificate into a Cloud Service
To activate SSL on the Cloud Service I’ll need to install an SSL certificate into the service using the Azure portal. Don’t panic, this is easier than it sounds. Promise. Five minutes, tops.
Back in my browser, on the Azure portal page, I’ll click the Cloud Service that’ll be answering HTTP/S requests for my site. The service’s dashboard page will open up.
I’ll click the Certificatestab in the navigation bar.
I’m going to want to upload my certificate, so this next step should be self-explanatory.
The next dialog gives me a pretty hard-to-screw-up dialog. Unless I forgot that password.
(cue the sound of hands ruffling through hundreds of post-its)
Once the certificate is uploaded, I’ll click the new cert and copy the thumbprint to my clipboard, maybe paste it into Notepad just for the moment…
Configuring the Cloud Service’s SSL Certificate
With the SSL cert installed and the thumbprint copied, I’ll open up the ServiceConfiguration.cloud.cscfg file in Visual Studio 2012 and set the thumbprint’s configuration. I could also do this using the built-in Azure tools in Visual Studio, but since I’ve got the thumbprint copied this is just as easy to do directly editing the files. Plus, the Web Sites team made it pretty obvious where to put the thumbprint, as you’ll see from the screen shot below.
Configuring the URL Rewrite Rules in the Web Role
Remember the architectural overview from earlier. The main thing this Cloud Service does is to answer HTTP/S requests and then reverse-proxy that traffic back to the Web Site I’m happily hosting in Azure. Setting up this proxy configuration isn’t too bad, especially when I’ve got the code the team handed me. I just look for all the places in the Web.config file from the Web Role project that mentions foo.com or foo.azurewebsites.net or foo…well, you get the idea.
Here’s the Web.config file from the Web Role project before I edit it to comply with the Web Site and Cloud Service I created to demonstrate this solution open in Visual Studio 2012. I’ve marked all the spots you’ll need to change in the screen shot.
Here’s the file after being edited. Again, I’ll indicate the places where I made changes.
Now that the Cloud Service and the Web.config file of the Web Role project’s been configured to redirect traffic to another destination, the proxy is ready for deployment. The solution’s Cloud project is defaulted to run at 2 instances, so that’s something you’ll want to remember – you’ll be paying for 2 instances of the Cloud Service you’ll be using to forward HTTP/S traffic to your Web Site.
Publish the Cloud Service
Within Visual Studio 2012, I right-click the Cloud project and select the Publish context menu item.
A dew dialogs will walk me through the process of publishing the SSLForwarder service into Azure. It may take a few minutes to complete, but once it publishes the Cloud Service will be running in your subscription and ready to respond to HTTP/S requests.
To verify everything’s working, try hitting the Cloud Service URL – in my case sslforwarder.cloudapp.net,to see if it’s answering requests or spewing errors about unreachable hosts, either of which wouldn’t be surprising – we’ve redirected the Cloud Service’s Web Role to a Web Site. That web site probably isn’t set up yet, so you could see some unpredictable results.
If you actually pre-configured your SSLForwarder Cloud Service to direct traffic to a *.azurewebsites.net you’re already running you’re pretty much finished, and you’re probably running behind HTTPS without any problems right now. If not, and the idea of publishing Web Sites from Visual Studio is new to you, you’ll have a chance to use that technique here.
Publish a Azure Web Site
I’ll go back into the Azure portal and go specifically to the SSLForwarder Web Site I created earlier on in the post.
Once the site’s dashboard opens up, I’ll find the link labeled download publishing profile. This file will be used by Visual Studio during publishing to make the process very simple.
Publishing and Browsing an SSL-encrypted Web Site
Once the publish settings file has been downloaded, it’s easy to push the site to Web Sites using Visual Studio 2012 or WebMatrix. With the sample project provided I’ll open up the Web Application project I want to publish to Web Sites. Then, I’ll right-click the web site project and select the Publish menu item.
Then, the publish process will make the remainder of the publishing experience pretty simple.
Remember to thank Sayed Hashimi if you need him out and about, he loves to hear thoughts on publishing and uses suggestions to make the experience an improved one for you. He also has a stupendous team of people working with him to execute great publishing experiences, who love feedback.
The publish process dialogs will walk you through the simple act of publishing your site up to Azure. Once it completes (which usually takes 30-60 seconds for a larger site) the site will open up in a web browser.
Note the URL still shows HTTP, and it also shows the URL of the Azure Web Site you created. You’ll need to manually enter in the URL for the Cloud Service you created.
For me, that’s www.sslforwarder.com. So long as the domain name you enter resolves toCloud Service you should be alright. You can also opt for the *.cloudapp.net approach too, as the domain name of the site you want to put out. Whatever your preference for solving this particular issue.
I’m going to go ahead and change the domain name andthe protocol, so our hit to the site being hosted in Web Sites will respond to it receiving an SSL-encrypted request, then load the site in the browser.
Note – this is when you’ll need to forgive me for showing you something that causes a warning in the browser. It’s just that way since I used a self-signed cert in a Azure service, so we should expect to see an error here. It’s right there in the browser’s address bar, where it says “Certificate Error.” If I’d used a real SSL cert, from a real authority, the error wouldn’t be there.
So for many months I’ve heard users request SSL on Web Sites, saying everything about it is awesome.Then they stare at me and wait about 3 seconds and usually follow it up with “but you’ve gotta get me SSL man, I’m over here and I gotta have my SSL”. I understand their desire for us to support it, and luckily, the Web Sites team and our engineering organization is so willing to share their solutions publicly. This is a great solution, but it won’t work in every situation and isn’t as good as what the Web Sites teams have in plans for the future. The SSL Forwarder solution is a good stop-gap, a good temporary solution to a problem we’ve had a lot of requests about.
Hopefully this helps in your decision to give Azure Web Sites a shot. If SSL has been your sole reason for not wanting to give it a try, now you have a great workaround in place that you can facilitate to get started right now.