Any opinions expressed here are my own and not necessarily those of my employer (I'm self-employed).

Oct 13, 2013

Hardening Windows Server 2008/2012 and Azure SSL/TLS configuration

SSL Labs A grade symbol
I guess it was long overdue for me to follow up on my Hardening Windows Server 2003 SSL/TLS configuration and Windows server 2003 vs 2008, SSL/TLS comparison posts. They were two of my very first blog posts and they still receive a decent amount of traffic. The world has fortunately moved forward since then, so in this blog post we’ll have a look at the default configuration of recent Windows Server (WS) versions in light of the latest recommendations from SSL Labs. We’ll keep the discussion at a reasonably high level, but I’ve included references to more in-depth information along the way for those who want to dig into the details. We’ll finish off with an announcement (Hint: it might have something to do with TLS configuration and Windows Azure).

There have been several attacks on various SSL/TLS configurations the last few years so configuring SSL/TLS correctly is a slippery slope. To keep up to date on the current state of affairs I strongly recommend you keep an eye on SSL Labs and follow @ivanristic on Twitter. SSL Labs provides a SSL server test that quickly assesses your servers’ current configuration and you’ll find a series of blog posts by Ivan Ristic that go into detail on the various SSL/TLS issues.

As I was finishing this blog post, a brilliant example of poor TLS configuration showed up in my Twitter timeline: 
Tweet on insecure TLS configuration
It refers to a blog post discussing insecure TLS configuration for a governmental site. The configuration was later hardened to the point where the site became incompatible with most browsers (click “Updates” at the top of the blog post). TLS configuration is a slippery slope indeed!

I did an SSL Labs scan of the governmental site, and it reported "HTTP server signature: Microsoft-IIS/7.5" so it was almost certainly running on WS 2008 R2 servers with default TLS configuration (we’ll get to those in a bit). The incident is a brilliant example because it shows two out of three outcomes based on how you configure TLS. First, you might be called out for running with an insecure configuration and not protecting your users. Second, you can't enable only the latest and most secure protocol versions, as you would break your site for a large number of users. TLS configuration is all about finding the right balance — the third and preferred outcome.

Windows Server and SSL/TLS

These days we’re running WS 2008 or WS 2012 and the cryptographic support has improved a lot over previous versions. Here are the important differences between the Windows Server versions:
  • WS 2003 had SSL 2.0/3.0 and TLS 1.0 enabled by default. The default installation did not support AES ciphers – but support could be added through a hotfix.
  • WS 2008 also had SSL 2.0/3.0 and TLS 1.0 enabled by default, but improved the cryptographic support with new AES cipher suites.
  • WS 2008 R2 introduced TLS 1.1 and TLS 1.2, but they were disabled by default.
  • WS 2012 takes us a step further with TLS 1.2 enabled by default.
As the list shows, supported versions are one thing, enabled versions are another. To complicate things further there’s a set of supported cipher suites for each protocol version, i.e. combinations of key exchange, encryption and hash algorithms used to secure the channel. We need to enable both secure protocol versions and secure cipher suites to secure the connections to our servers.

If you’re running a web server, IIS relies on the Secure Channel (Schannel) security support provider included in the Windows OS to handle SSL/TLS connections. You’ll find the default cipher suites and their preferred order documented in Cipher Suites in Schannel. Schannel is configurable through a number of registry settings.

Current TLS recommendations

The SSL Labs TLS configuration guidance was updated recently (v1.3), introducing new recommendations. Here’s the changelog:
  • Recommend replacing 1024-bit certificates straight away.
  • Recommend against supporting SSL v3.
  • Remove the recommendation to use RC4 to mitigate the BEAST attack server-side.
  • Recommend that RC4 is disabled.
  • Recommend that 3DES is disabled in the near future.
  • Warn about the CRIME attack variations (TIME and BREACH).
  • Recommend supporting Forward Secrecy.
  • Add discussion of ECDSA certificates.
We’ll briefly discuss each recommendation before we look into default Windows Server TLS configurations.

Replacing 1024-bit certificates

The new recommendation is to use certificates with 2048-bit RSA keys. Google announced in May that they were switching to 2048 bit keys in their certificates, and are now using new certificates on e.g. google.com. There are also upcoming changes to Google Chrome's certificate handling. In early 2014 we can expect Chrome to start warning users about certificates that fit certain criteria: if they have a key length < 2048 and are valid from or after 1. July 2012 or expire after 31. December 2013. The Microsoft Security Development Lifecycle (SDL) Process Guidance - Version 5.2 requires that you use 2048-bit or better RSA keys, and it’s also a requirement for SSL certificates in Windows Azure. Consequently, this recommendation is in practice already a requirement, so make sure you generate new 2048 bit keys when ordering new certificates or renewing old ones.

Disable SSL 3

Clients that only support SSL 3 are (finally) dying off, so disabling this version will only break the internet for the tiny fraction of users that still run ancient software such as IE 6 on Windows XP. Google announced three years ago that they would start phasing out support for IE 6, and many other sites have followed. Note that Microsoft still supports Windows XP (until April 8, 2014), but a patched Windows XP will be running IE 8 and support TLS 1.0. Consequently, it should be safe to disable SSL 3. 

Disable RC 4 ciphers

The RC4 cipher is now considered insecure, and it is recommended to drop support for it. The recommendation might well become a formal requirement in the future. A recent Internet-Draft, Prohibiting RC4 cipher suites, requires that TLS clients and servers drop support for RC4 cipher suites. RC4 was the recommended mitigation to the BEAST attack, but recent browsers have implemented client-side mitigations for this attack (except Safari). Weighing one risk against the other, it makes sense to disable RC4 since it affects all clients. To learn more about the RC4 vs BEAST tradeoff, see Is BEAST still a threat?

Disable 3DES

The recommendation to disable 3DES is a bit more problematic. Windows XP does not support the AES cipher suites added for TLS 1.0, and when we’ve sifted out the insecure cipher suites (including RC4) supported by XP we’re left with 3DES as our only option. Disabling 3DES means we’d break our site for XP/IE8 users — that could be devastating considering XP still holds a 20% market share. So unfortunately, we’ll have have to stick with 3DES for now.

CRIME attack variations (TIME and BREACH)

The CRIME attack showed how a middleperson attack could extract information from the encrypted traffic to sites that had TLS compression enabled. Schannel does not support TLS compression, so CRIME is not a threat for applications running under IIS. Earlier this year two related attacks emerged, TIME and BREACH, both targeting compressed HTTP responses. It is unclear how we can mitigate these attacks in a practical manner, but you’ll find a discussion on how e.g. CSRF tokens can be protected in Defending against the BREACH Attack. We can’t mitigate the attack through TLS configuration (which is the topic of this post), so we’ll move on to the next recommendation.

Forward secrecy

Forward secrecy refers to how session keys are set up for a TLS session. In the TLS cipher suites that are typically used (such as TLS_RSA_*), session keys are protected under the RSA key found in the server’s certificate. If someone records the encrypted traffic to the server and at some later point gets access to the server’s key, all recorded sessions can be decrypted.

Cipher suites that offer forward secrecy improves the situation by employing temporary keys during the TLS key exchange. These keys are thrown away after the session keys have been generated. This protects each session under separate, temporary session keys. An adversary would have to crack the session keys to learn the contents of a recorded session — and would have to repeat the process for each session. The cipher suites that offer forward secrecy are the ones named TLS_DHE_*and TLS_ECDHE_*. We won’t go in to further details here, but you’ll find a nice explanation in Deploying Forward Secrecy. Google started rolling out forward secrecy two years ago, and other big players are following their lead. We should all follow their example to better protect our users.

ECDSA certificates

The final SSL Labs recommendation is to use ECDSA certificates. These certificates contain an ECDSA public key instead of an RSA key. ECDSA keys rely on a different type of math based on elliptic curves (EC), yielding a better keylength/security ratio than RSA. This means we can use smaller keys, but still achieve the same level of security. Unfortunately, ECDSA certificates aren’t quite mainstream yet. I’ve tried to find a CA that would issue ECDSA certificates, but no luck there (yet). When these certificates become more generally available, we should seize the opportunity when current certificates expire and make the switch. Note that if you’re running your own CA you could set it up to issue ECDSA certificates.

That was a brief overview of the new SSL Labs recommendations, next we’ll look at the default configuration for recent Windows Server versions and see how they fare against the recommendations.

The default state of affairs

To give a snapshot of what Windows Server offers out-of-the-box in terms of SSL/TLS, I’ve collected some data based on the Virtual Machines (VMs) and web role instances that are available through Windows Azure today. If you spin up a new VM on Windows Azure you can choose between WS 2008 R2 SP1 and WS 2012 Datacenter (or a bunch of Linux distros which is really cool). For web roles you can choose between Guest OS family 1-3. Microsoft is retiring support for version 1 (WS 2008) so we’ll look at version 2 (WS 2008 R2) and version 3 (WS 2012). Guest OS family 2 is the default for new cloud service projects in Visual Studio 2012 with the latest Azure SDK. You can manually change the OS family version to 3 in the ServiceConfiguration file in your cloud project to get the latest version.

Windows Server 2008 R2 SP1

The WS 2008 VM flunks the SSL Labs test.
SSL Labs result for default Windows Server 2008 TLS configuration
The server scores 0 on “Protocol support” since it supports SSL 2.0, and there’s also a note that SSL 2 support will give you the grade F. Due to laziness I set the server up with a self signed certificate which also gives it a zero score on the certificate.

We also note that SSL 3 is enabled, and that TLS 1.1/1.2 are disabled in the next figure.
SSL Labs result for default Windows Server 2008 TLS configuration
SSL Labs warns about two insecure SSL 2.0 cipher suites and we see that RC4 is enabled. There are two cipher suites offering forward secrecy (TLS_ECDHE_*), but they’re placed towards the end of the list. This means that they won’t be selected in practice since browsers support at least one of the suites with higher priority, i.e. unless you disable them by hand in your browser configuration.

The picture could have been much prettier as WS 2008 R2 supports TLS 1.1/1.2, but unfortunately these versions are disabled by default. The decision to enable SSL 2 by default is questionable to say the least. SSL 2 was released in 1995 but a number of security flaws led to a redesign and the release of SSL 3 in 1996.

If you’re running WS 2008 servers you don’t have much of a choice — you have to harden the TLS configuration! I assume this was the problem for the governmental website mentioned earlier.

Windows Server 2008 R2 Azure web role (Guest OS family 2)

Next we’ll have a look at the WS 2008 R2 based web roles, this time I’ve also installed a trusted certificate.
SSL Labs result for default Azure OS family 2 TLS configuration
SSL 2.0 is disabled for OS family 2 instances and this does wonders for the score. We still get a warning that TLS 1.2 is unsupported.
SSL Labs result for default Azure OS family 2 TLS configuration
The SSL 2 ciphers are now gone, apart from that we see that the list is identical to that of the WS 2008 R2 VM. Even though this configuration is an improvement over the default WS 2008 configuration, it still needs tweaking to meet the SSL Labs recommendations.

Windows Server 2012 / Azure Guest OS family 3

The TLS configuration is identical for WS 2012 VM’s and OS family 3 Azure instances, so we’ll just refer to them as WS 2012. The default configuration gives us a better score on protocol support since WS 2012 supports TLS 1.2 out-of-the-box.
SSL Labs result for default Azure OS family 3 TLS configuration
In addition to TLS 1.2 support, we also get three new SHA256 cipher suites.
SSL Labs result for default Azure OS family 3 TLS configuration
Things are starting to look better, but forward secrecy ciphers suites still aren’t prioritized and SSL 3 is still enabled along with the RC4 cipher. For the WS 2012 there’s also room for improvement.

Now that we’ve covered the current state of affairs, let’s turn our attention to how we can harden the TLS configuration.

Configuring Schannel

You might recall that you can configure enabled protocol versions and cipher suites in Schannel through a number of registry settings. The preferred order and support for cipher suites is configurable through group policy (and native code). Tweaking the registry can be cumbersome so you’ll find various clients that can help you manage Schannel configuration. Unfortunately, configuring TLS by hand doesn’t work very well for Azure applications. You’ll need to do it in an automated fashion since Azure instances can be re-provisioned at any time. That brings us to my announcement!

Announcing NWebsec.AzureStartupTasks

The very first version of NWebsec.AzureStartupTasks includes an Azure startup task that configures Schannel according to the recommendations from SSL Labs. The scripts are available through a NuGet package for easy installation in an ASP.NET project. You’ll need to copy a few lines of config from the included ReadMe file to the ServiceDefinition.csdef in your cloud service project and you’ll be all set!

You can download the scripts from the project website and add them to a project by hand if you don’t have the option of using NuGet packages. The scripts also work stand-alone if you want to run them by hand on a Windows Server. Refer to the Install.txt for instructions.

The TLS configuration script requires PowerShell version 2 and so works for WS 2008 R2 (OS family 2) and later. It disables SSL 2.0 and 3.0, and makes sure TLS 1.0/1.1/1.2 are enabled. I’ve taken the default list of cipher suites and modified it slightly. I’ve moved cipher suites that offer forward secrecy to the top of the list and RC4 suites are excluded, but the 3DES suite is still enabled to not break the internet for XP/IE8 users. I’ve also added two newer TLS 1.2 AES GCM suites (but they require an ECDSA certificate). For reference, here’s the complete list of enabled cipher suites (in version 1.0):


I’ll update the package in accordance with new recommendations from SSL Labs. This is what the SSL test results will look like (at the time of writing) with this configuration:
SSL Labs result for NWebsec Azure OS family 3 TLS configuration
Still all green, but we’ve turned the score on protocol support up a notch. Under “Cipher suites”, the forward secrecy suites are now preferred.
SSL Labs result for NWebsec Azure OS family 3 TLS configuration
Things are looking a whole lot better! Since we’ve brought the protocol versions and supported cipher suites in line with the current SSL Labs recommendations, we’ll look at the some of the “Protocol Details” in the test result.
SSL Labs result for NWebsec Azure OS family 3 TLS configuration
Things are mostly looking good, but there’s a warning about the BEAST attack. Unfortunately, at this point we can’t win. One countermeasure to thwart BEAST is to prioritize the now-considered-insecure RC4 cipher. Another option is to disable TLS 1.0 — which would break the site in most browsers. We’ll simply have to live with the risk for now and hope that Apple implements the client side BEAST countermeasure found in other browsers (and that all browsers move fast to implement TLS 1.2).

There’s also a warning about session resumption. This is due to the Azure load balancer and non-sticky sessions. If you run a single instance in your cloud service, session resumption will turn green since all connections will hit the same instance.

Session tickets, aka RFC 5077 (TLS Session Resumption without Server-Side State), are underway in Windows Server 2012 R2 Preview and can solve the problem with non-sticky sessions. As a side note, key management for session tickets must be implemented with great care to avoid breaking forward secrecy. For more details, refer to How to botch TLS forward secrecy. Fortunately, it’s Microsoft’s problem to get this right.

OCSP stapling has been enabled by default since WS 2008. It improves performance and users' privacy.

Strict Transport Security is a HTTP security header that instructs web browsers to use HTTPS only when communicating with your web site. You’ll find more details in my blog post on Security through HTTP response headers. The header must be set in your web application, the NWebsec security library helps you set this and several other important security headers.

Wrapping up

The default TLS configuration in recent Windows Server versions needs hardening to meet recent recommendations. You can easily test your site at SSL Labs to see how it fares — note that anyone can do this for your site (recall the governmental website) so you’d better harden that configuration!

The NWebsec.AzureStartupTasks NuGet package provides scripts that help you bring the TLS configuration in order for Azure applications. The scripts are available for download so you can use them on other servers, and you can easily tweak them to your needs. The NWebsec demo site will always be using the latest version of the package, feel free to put it to the SSL Labs test (select the www.nwebsec.com entry). Follow @NWebsec on Twitter to keep up with new releases.

We’ve been focusing on TLS server side, but if you’re curious about how your browser is configured you should also check out the SSL Client Test. It takes two to tango, both the browser and server needs to support secure protocol versions and cipher suites.

Happy TLS hardening!

Final note

Scanning a WS 2012 through SSL Labs generated 84 errors in the system event log, these two errors showed up pairwise:

An TLS 1.2 connection request was received from a remote client application, but none of the cipher suites supported by the client application are supported by the server. The SSL connection request has failed.
A fatal alert was generated and sent to the remote endpoint. This may result in termination of the connection. The TLS protocol defined fatal error code is 40. The Windows SChannel error state is 1205.
If your event log fills up with these, you’ve probably been SSL Lab’ed!


  1. Thanks in advance. Really helpful.

  2. Thanks, good article.
    any change you will update with windows 2012 R2 details?
    and what do you recommend we do with MD5 hash?

  3. Hi,
    I see your SSL Certificate on https://www.nwebsec.com/ is expired.
    can you update this please (we getting SSL warnings because of it) and cant test it properly on the SSLLab as you suggested (there are two IPs, one fails with an F because the certificate is not trusted and the other fails because it cannot connect to the server)

  4. Perfect.
    Please update for upcoming server versions (maybe through your TechNet account? ;-)
    If you need a good powershell script to have this settings automated, use:


  5. Hi,
    Any chance of an update especially after the new ciphers recently implemented by MS in one of the more recent windows updates.
    I see someone else also asked the question, but any news about a Server 2012 R2 version taking into account the new SHA's Hashes and the ECDH Key exchange. (I see IIS Crypto's latest version also shows them)

  6. Thanks for the tip regarding "Scanning a WS 2012 through SSL Labs generated 84 errors in the system event log," brought me in the right mindset while troubleshooting an unrelated issue. :)

  7. Really helpful.
    I used IISCrypto with predefined Best Practices which doesn't include:
    In addition I disabled:
    to prevent DoS and MiTM attacks. I managed to get Grade A at the end, but Chrome says that I'm using obsolete cryptography (AES_256_CBC / ECDHE_RSA) Still not able to use AES_256_GCN on IIS 7.5 / 8... Is it possible? I think not :)

  8. In ssl labs test from where it will fetch the information about the protocols , it is from regestry editor of web server or else from where?

  9. Very helpful article ! I was always curious about all these complex algorithms that are being used in these ssl encryptions.

  10. Great article and better job, thank you.

  11. And here you can read about hardening servers using Android.

  12. I certainly agree to some points that you have discussed on this post. I appreciate that you have shared some reliable tips on this review.


Copyright notice

© André N. Klingsheim and www.dotnetnoob.com, 2009-2015. Unauthorized use and/or duplication of this material without express and written permission from this blog’s author and/or owner is strictly prohibited. Excerpts and links may be used, provided that full and clear credit is given to André N. Klingsheim and www.dotnetnoob.com with appropriate and specific direction to the original content.

Read other popular posts