Saturday, October 15, 2011

Setting up secure windows azure web role with GoDaddy ssl certificate

For the current project I am working on I am using Windows Azure as the platform and I need to figure out how to setup SSL for the web apps I am deploying to Windows Azure. The documentations online are sparse and fragmented. All the information I am providing here are available somewhere but they are not all together in one place.

Now, the reason for this article, you need to create a certificate file with private key for import but the SSL certs from GoDaddy are chained and you don't have the private key for the chained certificates.  From my research Versign certificates will work without issue when uploaded to Windows Azure, but very few people got GoDaddy's certificates to work properly.  However Versign certificates cost way more than $12.99 (Google for discount) per year, so hopefully this article will save you some money.

To setup https on Windows Azure you need to create a certificate file with private key and embed the chained certificates so you can upload them to Windows Azure. There are many ways to setup the SSL certificate and export it for use later but I have only found one way to correctly install and export the SSL certificate so that it contains the chained certificates as well. I am sure the steps here apply for other vendors but GoDaddy is the only one I tested with so I am putting that down as pre-condition.

This article assume you are doing the following:
  • you know how to manage your domain and sub-domain with your domain registrar
  • you purchased an SSL certificate from GoDaddy
  • you are building .Net web applications with Visual Studio
  • you are using Azure web role to host your web application
solution layout
The first step is to create a dummy project and get it running locally. Since we are only discussing setting up SSL your test app should contain no access to database or external resources just to minimize places where your app might fail, if you have something that's ready deployed to Windows Azure and it works then you can use that as well. I am going to reuse the Html5 project I created for another article. In the same solution where your sample web project is, simply create a Windows Azure project. After the Windows Azure project has been created, right click on the Roles folder and select Add->Web Role Project in Solution. If you don't have an existing project to work with simply create a new one right now.

Once you have the project up and running locally then you are ready to deploy it to Azure.  We want to make sure the non secure version works first before we move on with the main part of the article to eliminate any issues that's not related to SSL certificates. Log onto Windows Azure management portal to create a new hosted service and a production deployment of the sample project we have created earlier. Once the deployment is ready navigate to your-host.cloudapp.net. Verify that your web role is running correctly and fix any issues that have popped up.

Next we will setup our custom domain to redirect to Azure web role.

For setup with sub-domain:
 In the DNS manager add a CNAME for sub with value of your-host.cloudapp.net.

For setup without sub-domain: In your DNS manager, add a CNAME for www with value of your-host.cloudapp.net. I also had to create an A record for @ with value of 127.0.0.1 for the domain to work not sure why, you could google it if you are really curious. *You can skip the next step and go on to the next paragraph if you are using sub domain. Once you have the DNS records setup go back to Domain Manger and click on Forward->"Forward Domain" from the tool bar and forward your-domain.com to www.your-domain.com. Verify www.your-domain.com points to Azure web role you have setup previously and fix any issues you encounter.

You can view the result for my setup at Azure generated URL vs custom domain

Now we need to generate an ssl certificate for your-domain.com, if you are using www.your-domain.com, SSL certificate for your-domain.com will work just fine, you don't need to create a separate certificate for www.your-domain.com. However if you want to use sub-domain you will need to get an ssl cert for sub.your-domain.com. GoDaddy has instruction on how to generate and install SSL certificate on your IIS server, but I will go through it here again so you don't have to read that article. Start IIS manager and double click on Server Certificate feature. In the Action panel on the right, select "Create Certificate Request ...".  In the popup dialog enter your domain name in the "Common name" field.  The rest of fields doesn't matter too much if you are using standard ssl so enter whatever information you think is appropriate.  On the next screen make sure you select "Microsoft RSA SChannel Cryptographic Provider" and Bit Length of 2048.  Save the result somewhere.

Next log into your GoDaddy account and navigate to Secure Certificate Services, select an unused credit and request a certificate. Copy the CSR content from the saved file and paste it into the input box. I selected Starfield Technologies as Certificate Issuing Organization, you may do the same if you want to follow the rest of this guide closely.  Wait a few hours and check back, your SSL should be ready. Download the certificate for IIS 7 and make sure to check include the intermediate certificates box.

Now we are ready to install the certificates, first we will install the intermediate certificates. Start Microsoft Management Console by type in mmc in the run box on the Start menu. Select File->"Add/Remove Snap-ins", then select Certificates and Add. Pick "Computer account" option in the popup box, then on the next screen with "Local computer" selected, click Finish button then Ok button. In the tree view on the left navigate to "Certificates/Intermediate Certification Authorities/Certificates". Right click->All Task->Import and import "sf_iis_intermediates.p7b" (you might have "sf_bundle.crt" if you downloaded SSL for other server option). Make sure to read through the next part before proceeding.

What we want to do next is install the SSL certificate through IIS, take note that we are not importing the SSL certificate using mmc, if you do that you cannot export the certificate with private key. Start IIS manager as administrator and select your local machine in the tree view on the left then double click on Server Certificates feature. On the right hand side is Action panel click on "Complete Certificate Request ..." and browse to your SSL certificate, this is the other certificate that was not installed in the earlier step. You might need to change the file extensions in the open file dialog because GoDaddy's certificate file is saved as *.crt while the open file dialog is defaulted to *.cer. Now you should see your SSL certificates installed in IIS manager, go back to mmc and check under "Certificates/Personal/Certificates". You should see your SSL certificate listed there, refresh if you don't see it. if that doesn't work the SSL certificate was not installed correctly; Google online for more help.

So after all that we are finally ready to export the certificates and upload to Windows Azure. In the mmc find the SSL certificate and right click->All Tasks->Export. Make sure you export through mmc, IIS export doesn't export the complete certificate chain correctly and you cannot export the intermediate certificates any other way since you don't have their private keys. Click Next on the Welcome screen and in the Private Key screen make sure to have "Yes, export the private key" selected then click Next. In the Export File Format screen select "Personal Information Exchange", check "Include all certificates in certification path if possible" and "Export all extended property" options then click Next. Enter a password and click Next, then select where you want to export the certificates to. Once the export is done you are ready to upload it to Windows Azure.

Go back to Windows Azure management console and find the host service we created earlier, there should be a certificates folder under the host. Right click on that folder and pick "Add Certificate" option; point it to the certificate file we just exported and enter the password and ok. Once the import is done you should see three certificates, this is important if any of the certificates is missing most browser will not validate your SSL certificate and your site is not shown as secure even if the communication is protected. We upload the certificates first before setting up the web role because it makes the next step slightly easier. Don't close the Windows Azure management console, start up visual studio and open your project.

All three certificates

Find your web role and bring up the property view by double click on the web role. Select Certificate tab and Add a new certificate. Name it your-domain.com, select LocalMachine for Store Location and My for Store Name.  Now go back to Azure console and select your-domain.com certificate in the properties panel to the right find the Thumbprint property and copy it's value. Back to visual studio and paste the thumbprint value we just copied into Thumbprint field. Repeat the process for the other two certificates but set Store Name to Trust.


Add certificate with thumbprint value
Next click Endpoints tab in the project property view and add a new end point for https and select your-domain.com certificate as ssl certificate.


Endpoints
Finally, create a new Azure package and upgrade the existing deployment on Windows Azure portal. If you have done everything correctly up to this point the new package should upload without any error.  Once the update is complete you can now test to see if your certificates are installed correctly by navigate to https://www.your-domain.com.  The site should load without any error, if the browser put up a warning screen about site not trusted or cannot verify site SSL then you will have to search around to figure out what went wrong.  Take a look at my https results.

Disclaimer: the ssl certificate is good for a year and I don't plan on renew it so if you visit the site after 2013/07/11 the certificate will not be valid (but you can go get a free Slurpee).  Also I might take down the site later when I need to free Azure computing credit for something else.  Here is a screenshot showing the end result.

Black Magic

26 comments:

Anonymous said...

Very useful -- worked like a charm. Many thanks.

Anonymous said...

It was very useful, thanks! In my case complemented with re-direction, found information on that topic here http://blog.smarx.com/posts/redirecting-to-https-in-windows-azure-two-methods.

Cheers.

Anonymous said...

Hello
I'm VERY grateful for this blog - it helped me enormously.

Thank you and god bless.

Anonymous said...

Very good guide, managed to get my godaddy certificate to work first time on my web site.

Many thanks

Anonymous said...

Thank yo so much for this!
A real life saver.

Assaf

Anonymous said...

Thank you very much for taking the time to document this - it worked great. I had the extra complexity that my domain was controlled by cpanel host that doesn't have an export feature. This link gave me the extra info I needed to complete your steps: http://support.citrix.com/article/CTX106630

Anonymous said...

When I am trying to export the SSL, I get 5 options, 2 of them are greyed out. The other three options are :
DER encoded Binary
Base-64
Cryoptographic Message

Which one I should chose? If I chose any of these I dont see this
"Yes, export the private key".
Please help, I dont know what I am doing wrong.

Cheers.

Peijen said...

if the "Personal Information Exchange" option is grayed out it might be one of two things, you didn't have the correct permission or the private key is not imported. To test if you have the correct permission, try to make sure you start mmc with "Run As Administrator" option, if you still don't see the option to export "pfx" enabled you might not have the private key installed. To verify that you have the private key installed, find the certificate in mmc, on the upper left corner of the certificate icon should be a yellow key. If you don't see the yellow key, then the private key was not imported correctly.

Anonymous said...

Thanks a lot! After 5 hours of googling I ended up here, and found out that exporting my cert through MMC would fix my problem with the chain.cer
Thanks!

Unknown said...

Thank you for such a complete and comprehensive write-up. It helped me immensely.

Have you ever come across the situation where opening the service URI in a browser window using HTTPS validates the certificate successfully, while calling the service URI in code gets rejected? I'm experiencing exactly this, and the only way I've found to get around it is to implement the System.Net.ServicePointManager.ServerCertificateValidationCallback to always return true. This is an unacceptable solution (hack) though. Do you know the reasons this would happen?

Gautam Jain said...

Man! Thank you very much!

Several hours after I found the exact inner details.

Thanks for your generosity!

Peijen said...

@Unknown concerning calling URI in code: in my experience the cause is usually the account level permission. Not exactly the same, but I know for wcf certificate based auth you have to install the cert locally to the client machine and put it into one of the trusted store + grant correct permission to the cert for the executing user account. Sorry that I can't help you beyond that.

Emre Nevayeshirazi said...

this works like a charm. thank you very much...

Anonymous said...

Thanks for your article.it helped me lot of.one thing am not getting.when i entered www.mydomain.com it;s redirect to my cloudapp.net with http not https.when i entered https://www.mydomain.com it will redirect to https.tell me what is the mistake i did.

Peijen said...

Did you follow the instruction under "For setup without sub-domain:"? Other than that I am not sure what could be the cause.

James Bowling said...

All these steps must be taken on the same PC. I was deeply confused as to why I couldn't export with the private key.

Andrea Coluccio said...

Thank you for this useful article!

Anonymous said...

Hi man, God bless ya, it works :-D! I would buy u a bear, but I can't see any "gimme a bear" PayPal button here ;-). Thank you so much, Andy

Shirish said...

How can I upload a chained certificate without VisualStudio? Azure portal let me import the pfx file and it imports all the chained certificate properly, but the site is still not able to recognize that the certificate is from a valid CA. Am I missing something?

Peijen said...

@Shirish,

I have not tried it through the windows azure portal. The article was written before windows azure portal allows you to upload certificates, so it probably won't work.

I could try to test it out when I have time, but that probably won't be anytime soon.

Theeranit Pongtongmuang said...

Excuse Me,
I wonder if it work if I have many web role instances.
It seem you create private key from one server, it don't know if it worker with many web instances.

Thanks

Thomas Weiss said...

Thanks a lot for this useful article. But I'm facing the same issue as 'Anonymous', with the option for "Personal Information Exchange" being grayed out...
I've tried many times and I'm sure that both MMC and IIS Manager were started as Administrator.
How to further debug an issue on private key import?

Thomas Weiss said...

UPDATE!
For the case I just described above, I've found that you can repair the certificate by following the procedure described here: http://support.microsoft.com/kb/889651/en-us

Anonymous said...

Man, this was so useful... I tried so many things to install the Godaddy cert on Azure, but this only worked! Thanks so much!
Riccardo from Italy

Peijen said...

@Theeranit

Do you mean 1 web role with many instances? That is taken care of by Windows Azure so it will not be a problem.

Many web roles? They would have different endpoints so I am not sure how you would use 1 certificate for it.

Anonymous said...

You're a legend, thanks so much for putting this article together. I spent almost an entire day trying to figure out why the hell my cert was working before I stumbled across your site.

Everything is now working perfectly.