Difference in IIS 6, IIS 7.x and IIS 8 with regards to SSL

There were lot of differences with regards to SSL moving from IIS 6 to IIS 7.x and then to IIS 8. IIS 6 in itself was a breaking change, however there were lot of limitations and they were addressed in higher versions. I will try to pen down as I remember them and will update the blog if I come across other changes.

Before I proceed further, for readers who are not familiar with IIS and Windows versions, this is a small info to set the stage:

  • IIS 6 (Windows Server 2003 and Windows XP 64 bit only)
  • IIS 7 (Windows Server 2008 and Windows Vista)
  • IIS 7.5 (Windows Server 2008 R2 and Windows 7)
  • IIS 8 (Windows Server 2012 and Windows 8)

I will be addressing both IIS 7 and IIS 7.5 as IIS 7.x.

Differences from architectural perspective:

One major difference between IIS 6 and the IIS 7.x was the way they would handle incoming HTTPS requests. Lets discuss how HTTPS requests were handled in IIS 6 before we proceed any further.

image

Taking the above architecture into consideration this is how the IIS 6 request flow looks like:

  1. HTTPS requests comes into SSL Queue within HTTP.SYS, which is in the KERNEL Mode.
  2. The encrypted requests is then sent to a USER Mode process called LSASS.exe for decryption. The request is decrypted using SChannel.dll loaded inside the lsass.exe process.
  3. The decrypted request is not sent back to the HTTP.SYS In the Kernel Mode.
  4. This is now placed in the corresponding Application Pool queue and then routed to corresponding worker process in USER Mode based upon which w3wp.exe a application pool queue corresponds too.
  5. The w3wp.exe generates the response and sends it back to the HTTP.SYS in the KERNEL Mode.
  6. This response is again sent to the Lsass.exe process in the user mode for encryption.
  7. After encryption, lsass.exe sends it back to the HTTP.SYS in the KERNEL mode.
  8. The encrypted response is sent back to the client.

PROBLEM 1:

During the course of the entire processing of request, there were several context switches (Whenever there is a flow of control from KERNEL MODE to USER MODE or vice versa, it is referred as a CONTEXT SWITCH).

There were 6 context switches in the above flow, out of which 4 context switches happened for encrypting and decrypting of request and response.

Context switching induces additional overhead and delays the processing of requests. This impacts the performance as this happens for every HTTPS request-response cycle.

These 4 context switches could have been avoided if the encryption and decryption happened in the KERNEL Mode. This was addressed in IIS 7 and the same was retained in later versions.

PROBLEM 2:

Another problem is the problem with host headers. Host Headers were never defined in the original SSL Specification, as they were part of the HTTP RFC and defined there. The TCP Layer never defined the Host headers for obvious reasons. Due to this, a major problem emerged & made SSL applications not scalable.

Due to the unavailability of the Host Header in the TCP layer, the incoming encrypted HTTPS request provided only IP+Port as information to HTTP.SYS. In IIS the problem was addressed by allowing only one SERVER CERTIFICATE (Certificate Hash) per IP+PORT binding. The SSL Host Header was mostly irrelevant unless the Server Certificate was either a Wild Card Certificate or a SAN Certificate.

This problem was later addressed by the IEEE by introducing Subject Name Indication (SNI). Here the host header was made available in the Client Hello,sent by the client to the serer during the initiation of the SSL Handshake.

This was implemented in IIS 8. However, it has its own set of limitations.

SOLUTION:

In IIS 6, the solution was already present in the form of KERNEL MODE SSL. However this required tweaking of a registry key and was not a ideal solution as it wasn’t used by most of the customers and was never recommended.

  • Go to the run prompt and type Regedit and click OK.
  • Navigate to and double-click the following key in the registry:
    • HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\HTTP\Parameters
  • Add the following DWORD registry key:
    • Name: EnableKernelSSL
    • Type: REG_DWORD
  • Data: Set this to 1 to use kernel-mode SSL; 0 is for user-mode SSL.

In IIS 7, KERNEL MODE SSL is the default option and this cannot be changed. The KSECDD.SYS driver is responsible for providing the cryptographic functionalities in the kernel mode.

This reduces the context switching during the request response cycle and hence improves the overall performance. Below is the improved request-response flow:

  1. HTTPS requests comes into SSL Queue within HTTP.SYS, which is in the KERNEL Mode.
  2. The encrypted request is decrypted with the help of KERNEL Mode SSL.
  3. This decrypted request is placed in the corresponding Application Pool queue and then routed to corresponding worker process in USER Mode based upon which w3wp.exe a application pool queue corresponds too.
  4. The w3wp.exe generates the response and sends it back to the HTTP.SYS in the KERNEL Mode.
  5. This response is encrypted via the KERNEL Mode SSL component.
  6. The encrypted response is sent back to the client.

As seen there is a clear performance improvement due to the reduced context switching.


In IIS 8, this problem 1 was already addressed as it was inheriting the architecture of IIS 7. However, considerable changes were made to the HTTP.SYS and the SSL functionality to incorporate SNI in the server architecture.

A new form of SSL binding called SNI bindings was introduced, which were in the form of HostName+Port.

You can read more about it here:

Differences from Configuration Perspective:

In IIS 6, this is how the bindings section looked like within the MetaBase.xml:

 <IIsWebServer Location="/LM/W3SVC/1" AppPoolId="DefaultAppPool"
 ...
 ...
 ...
 SSLCertHash="1c25a46a479813472f8d997b3ef4b699130b0737" SSLStoreName="MY"  
 SecureBindings=":443:"  
 ServerAutoStart="TRUE" 
 ServerBindings=":80: :80:www.kaushal.com :80:www.kaushal.edu :80:kaushal" 
 ServerComment="Default Web Site" ServerSize="1" 
 SslCtlIdentifier="{6A615835-58F1-4B6F-A779-3F5AE1F1F9E7}"  
 SslCtlStoreName="CA"  UseHostName="TRUE">

As seen in the above snippet of the config section, the SSL cert hash was stored within the MetaBase.xml along with the bindings information and SSL related information like SSLStoreName, SSLCtlStoreName etc.

This information was also present in the registry as well. There was supplication of efforts one could say because the user mode processes would refer the MetaBase.xml while kernel mode components would refer the registry related information.


This changed in IIS 7.x and later versions have incorporated it, all the certificate related information was moved to the registry, no cert related information is stored in the config file. Below is a snippet of the config:

 <sites>
     <site name="Default Web Site" id="1" serverAutoStart="true">
         <application path="/">
             <virtualDirectory path="/" physicalPath="%SystemDrive%\inetpub\wwwroot" />
         </application>
         ...
         ...
         ...
         <bindings>
             <binding protocol="http" bindingInformation="*:80:" />
              <binding protocol="https" bindingInformation="*:443:" sslFlags="0" /> 
         </bindings>
         <traceFailedRequestsLogging enabled="true" />
 </site>
 

As seen above lot of information has been removed from the config file. There were no duplication of efforts due to the removal of the cert related section from the config file, mainly due to KERNEL Mode SSL dependency. This reduced the size of the overall configuration file as well.

Differences from UI Perspective:

There was significant change as to what options were available in the IIS UI for the users when configuring SSL. This changed drastically from IIS 6 to IIS 7. Even the latest version of IIS, follows the same UI which was changed in IIS 7 with additions to incorporate the new functionalities.

IIS 6 UI was pretty limited. There were several problems associated with it. The UI allowed only one certificate to be bound to the site irrespective of whether there were 2 or more combinations of IP+Port. The reason for this was that the UI for specifying the IP+Port was different than the one which was used to bind the certificate. These were presented to the user as 2 different sections and hence was a problem.

image

To get the above UI:

  • Right click and go to the Web Site properties:
  • Go to the Web Site tab.
  • Under Web site identification click on Advanced…
  • Click on Add.. under Multiple identities for this Web site.

The above image is the UI to add the bindings for the web site. There is no option to choose the certificate or to specify the host header. The user can only specify the IP and Port and then he has to traverse to another section to choose the certificate for the site.

image

As shown above the UI to add a certificate is in a different tab altogether. Even if the user adds 3 distinct secureBindings, the UI allows only one certificate to be mapped to the Web site. This is because there was no way in the config to identify which bindings will use what certificate. As a result due to this, all the bindings for that site ended up using only one certificate. Not a ideal situation at all.


All these short comings were addressed in IIS 7 and this has remained as a base for the future IIS versions too. take a loot at this UI:

image

The UI is pretty simple. It allows the user to select a certificate for a corresponding IP+Port combination. The Host name section contains a textbox to specify the value, but is disabled by default (This is another shortcoming in IIS 7.x versions). This is enabled only if the certificate is a Wild Card certificate (If it’s a SAN certificate, the textbox would still remain disabled). When the user selects a certificate from the drop down list, it directly updates the registry values corresponding to the SSL binding.

Here is the registry key where the SSL bindings are stored:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters\SslBindingInfo

This can also be retrieved via command prompt by executing the following command:

netsh http show sslcert


In IIS 8, not much was changed, but few additions and improvements were made to the overall SSL functionality. As I mentioned earlier, significant additions were made to make IIS scalable from IIS perspective, this was done by introducing SNI and CCS bindings. The above UI was improved slightly to incorporate the new additions and overcome the limitations of the previous version. The Host name text box remains enabled regardless of the certificate.

image

There are few other changes which exist moving forth from IIS 6 to IIS 7 and are not pleasant. Yes I’m referring to Client Certificates.

IIS 7 onwards there is no UI to specify Client Certificate mapping.

However, citing these problems, the configuration editor was introduced as separate download for IIS 7 (It is available by default in IIS 7.5 and later versions).

The configuration editor was a blessing in disguise for user who still use IIS Client Cert Authentication. However, the IIS 6 UI probably was better in this regards at least.

With this, I am calling an end to the lengthy blog. I will update the list as I come across other differences between these IIS versions.

Comments

  • Anonymous
    May 28, 2013
    Nice one! Thanks for Sharing it :)

  • Anonymous
    May 28, 2013
    Good to know that it helped you.

  • Anonymous
    May 28, 2013
    Very useful one Kaushal :)

  • Anonymous
    May 28, 2013
    Very useful one Kaushal :)

  • Anonymous
    June 04, 2013
    I have web application which is deployed in multiple servers and accessed using load balancer. How to configure the ssl certificate in this scenario

  • Anonymous
    June 28, 2013
    @Srikar - Try SSL Offloading. I am not sure what type of load balancer you are using. But most of the hardware load balancers these days support SSL Offloading. If this is not viable then you need to setup the certificate on all the servers in the farm. I would rather suggest you to go forth with SSL Offloading.

  • Anonymous
    November 13, 2013
    Good Blog Kaushal :)

  • Anonymous
    January 22, 2014
    Very Nice ! Thanks for Sharing it :)

  • Anonymous
    January 23, 2014
    This information is extremely useful and really helps get a good overall understanding of how IIS works with SSL. I wonder whether you can help with a problem I have with SSL binding in powershell. Adding SSL bindings using PowerShell New-WebBinding that use the Central Certificate Store does not work. Nor does any variation of “Add-WebConfigurationProperty”. The bindings get created in the applicationhost.config files but the mapping that are needed in the registry path “HKLMSYSTEMCurrentControlSetServicesHTTPParametersSslCcsBindingInfo” do not get added and the SSL enabled website does not work. This works perfectly in IIS manager. In fact creating a website using PowerShell, opening the HTTPS binding and resaving it in IIS manager WITHOUT MAKING ANY CHANGES works. It seems that IIS creates the binding correctly but PowerShell commandlet does not. I found this out after several hours messing around with Process Monitor to see what IIS Manager was doing. My workaround was to use NETSH HTTP SSLCERT… Thank you for posting and keeping it up to date.

  • Anonymous
    January 27, 2014
    @reidca.. I tried the commandlet new-webbinding and that worked for me absolutely fine. Here is my command: New-WebBinding -Name "Default Web Site" -IPAddress "*" -protocol https -sslflags 2 -HostHeader test2.kaushal.com FYI, the sslflags can be set to 2 or 3 to ensure it is using CCS. Could you tell me what is the command that you tried??

  • Anonymous
    January 28, 2014
    Thanks for replying Kaushal. I just tried this again using the code you posted and now it works. However there have been a lot of changes since I last tested it as I have been trying to diagnose another issue with the famous "A logon session does not exist, it may have already been terminated" message when adding an SSL binding. I have been using CertUtil to look at the certificates and found that one of the certificates had a KeySpec set to 0. I have since recreated this certificate and the binding to central certificate store now appears to work. I have read more articles on SSL binding errors in the last few weeks than I care to remember whilst trying to resolve the "logon session" error but I still do not fully understand how Powershell assigns bindings compared with using the IIS manager. I have seen various issues using Powershell where using NetSh to achieve the same thing has worked perfectly. In one instance using the X509Certificate2 object that is returned from Import-PfxCertificate would work fine for a binding but if I retrieved the certificate from the store using Powershell Get-Item and used the cert:LocalMacineMyhash format to assign the same binding it would fail with the "logon session" error. I am at a loss to explain why. NetSh to the rescue again which seems to work differently. Any more articles on this subject would be really appreciated since it is clear you have a very thorough understanding of the areas.

  • Anonymous
    May 08, 2014
    Can we configure multiple websites on IIS Server? Your quick response will be appreciated. ;)

  • Anonymous
    May 08, 2014
    @Addy.. You asked me a incomplete question. :) I'm going to answer considering all versions of IIS and HTTP/HTTPS bindings. For HTTP sites: you could create as many sites as possible based on the availability of system resources. There is no hard limit on the number of HTTP sites that can be hosted on IIS. For HTTPS sites: until IIS 7.5, IIS supported only legacy IP based SSL binding. This had a restriction that one one certificate could be bound to a IP:Port combination. The solution here was:

  1. Use a Wild Card Certificate
  2. Use a SAN certificate
  3. Add another NIC card so that you have another IP
  4. Use a different port (Not viable) All the options mentioned above are not optimal. However, there was not many options for hosting multiple SSL based sites. With IIS 8, we introduced SNI and CCS bindings which made IIS truly scalable for HTTPS sites. Now you could configure multiple HTTPS sites with ease. For more info read other posts: blogs.msdn.com/.../ssl-handshake-and-https-bindings-on-iis.aspx blogs.msdn.com/.../ssl-scalability-with-iis-8-windows-8-server.aspx blogs.msdn.com/.../server-name-indication-sni-in-iis-8-windows-server-2012.aspx blogs.msdn.com/.../central-certificate-store-ccs-with-iis-8-windows-server-2012.aspx
  • Anonymous
    June 29, 2014
    One of best blog i have read very good keep it up easy understandable language and nicely potrayed

  • Anonymous
    July 22, 2014
    Hello Kaushal. It will be grateful if you answer my query too. I have migrated to IIS 8 from IIS 7 but I am having two issues.

  1. I have not been able to run our application on IIS 8's integrated mode (which leads us to the failure of opening of reports)but working perfectly for classic mode and also working perfectly for previous versions. So how to make it work?
  2. I have not been able to create excel file in my system profile. So how to go about it too? Eagerly waiting for your reply.
  • Anonymous
    July 23, 2014
    There is a difference in Integrated and Classic mode when it comes to executing a specific request. I don't understand the nature of your application but looks like it was coded against IIS 6 so it works fine in classic mode. Integrated mode is a un9ified pipeline where classic mode has dual pipelines where few events are repeated and unnecessary overhead. Regarding the second query I assume you are referring to application pool identity. You may use identity impersonation for this..

  • Anonymous
    July 24, 2014
    Reports were working fine for integrated mode IIS 7, but not for IIS 8. Identity impersonation is already turned on, but still I am facing the same problem. (I made it work for IIS 7 by creating desktop folder in c //windows/syswow64/config/systemprofile/desktop but its not working for iis 8.)

  • Anonymous
    July 25, 2014
    Ali, This needs further troubleshooting. I would suggest you to open a ticket with Microsoft CSS. One thing I would like to suggest is to enable load user profile to true under advanced settings for application pool. See if this helps.

  • Anonymous
    December 25, 2014
    post the exact differences between all, the iis versions

  • Anonymous
    May 24, 2015
    Could you help in this matter? I have a webserver at IIS 7, that is configured with mutual autentication. In the server a don´t have the certificate of Intermediate CA and even so i can access the application.

  • Anonymous
    May 26, 2015
    @Glaucius I assume when you say Mutual Auth, you refer to Client Certificate Authentication. Please refer this post for more details: blogs.msdn.com/.../client-certificate-authentication.aspx  

  • Anonymous
    June 21, 2015
    > (Whenever there is a flow of control from KERNEL MODE to USER MODE or vice versa, it is referred as a CONTEXT SWITCH) A switch from/to kernel/user mode is generally referred to as "mode switch". A context switch, in contrast, makes a CPU work on a different process/thread. Wikipedia (en.wikipedia.org/.../Context_switch) says > When a transition between user mode and kernel mode is required in an operating system, a context switch is not necessary; a mode transition is not by itself a context switch. However, depending on the operating system, a context switch may also take place at this time. So are you saying that in Windows, a mode switch implies a context switch? Or was this just a confusion of terminology?

  • Anonymous
    June 21, 2015
    The comment has been removed

  • Anonymous
    February 03, 2016
    The information was really clear to understand and useful!! I suggest if it can be tabulated the difference between IIS6/7 and 8. It would be easy to remember the points!!.

  • Anonymous
    June 09, 2016
    Great blog Kaushal... very clearly elaborate the IIS mystery which Microsoft lacks in their original docs :) thanks

  • Anonymous
    February 14, 2017
    This is very good information and detail architecture for HTTP pipeline FLOW. Its very help full.

  • Anonymous
    March 17, 2017
    Hi Kaushal,we have a website hosted on apache server, but it is listening on port other than 443. when I try to access this website using iis it fails .can u help is there any other setting that I need to perform on iis side?

  • Anonymous
    April 05, 2017
    I'm following your blog since last 2 years. Awesome blog... If you update this blog with new concepts is much appreciated.Could you explain the same way the differences and new in IIS 8,8.5 and 10. Like Automatic Certificate Rebind,Dynamic Site Activation,Dynamic IP Address Restrictions,Dynamic Site Activation,Dynamic IP Address Restriction,Multicore scaling on NUMA hardware,Splash page during application initialization.With proper Screenshots.

  • Anonymous
    May 31, 2017
    I'm having a strange issue with IIS8.5 on Windows 2012 Server trying to select a wildcard SSL cert for site bindings with SNI flag enabled. Earlier I had a single SSL certificate to be selected for all bindings and hence I did not need to set SNI flag for bindings, but to support multiple SSL certs on a single IP, I had to make this change.I am able to assign the SSL cert to binding if I do not set the SNI flag.Interestingly, if I go into the IIS Administrator and perform the steps manually to create new bindings using similar configuration, the process works fine but get following error when I try to create the binding through code using C# program and Microsoft.Web.Administration library: [code]A specified logon session does not exist. It may already have been terminated. (Exception from HRESULT: 0x80070520) [/code]What wrong I might be doing here?