简体   繁体   中英

Calling Bindings.Remove does not remove SSL cert from HTTP.sys

The shortest version of my question is that calling ServerManager.Binding.Remove seems to remove a binding from IIS, but still leave it in HTTP.sys or wherever SSL bindings are set and breaks layers of my code further down.

I'm running an Azure Cloud Service that needs to use SNI to support multiple hostnames using SSL. Effectively what I'm doing is in OnStart removing the default binding using ServerManager.Binding.Remove(binding) and adding my own bindings using ServerManager.Binding.Add(binding) . So for example:

ServerManager serverManager = new ServerManager();
Site site = serverManager.Sites[0];

// Add my site bindings.
foreach (string host in listOfHostsToBind)
{
    X509Certificate2 cert = LookupCertificate(host.sslThumbprint);
    var binding = site.Bindings.Add(":443:" + host, cert.GetCertHash(), "My");
    binding.SetAttributeValue("sslFlags", 1);  //Set SNI flag
}

// Remove the default binding
var bindingsToRemove = new List<Binding>();
foreach (Binding binding in site.Bindings)
{
     if (binding.Protocol == "https" && Convert.ToInt64(binding.Attributes["sslFlags"].Value) != 1)
     {
         bindingsToRemove.Add(binding);
     }
}

foreach (Binding binding in bindingsToRemove)
{
    site.Bindings.Remove(binding);
    serverManager.CommitChanges();
}

serverManager.CommitChanges();

What ends up happening is that the default IP:Port binding is removed from the list of IIS bindings, but it still shows up in the list of SSL bindings when I call netsh http show sslcert .

So, for example, here's the output from calling Get-WebBinding in Powershell. Notice that the default IP:Port binding is not there:

protocol     bindingInformation                       sslFlags
--------     ------------------                       --------
http         10.20.30.40:80:                          0
https        :443:myfirstaddedhost.com                1
https        :443:mysecondaddedhost.com               1

Looks good, but it still doesn't work, because if I run netsh http show sslcert I get the following:

IP:port                      : 10.20.30.40:443
Certificate Hash             : xxx
Application ID               : {00000000-0000-0000-0000-000000000000}
Certificate Store Name       : MY
...

Hostname:port                : myfirstaddedhost.com:443
Certificate Hash             : xxx
Application ID               : {4dc3e181-e14b-4a21-b022-59fc669b0914}
Certificate Store Name       : My
...

Hostname:port                : mysecondaddedhost.com:443
Certificate Hash             : xxx
Application ID               : {4dc3e181-e14b-4a21-b022-59fc669b0914}
Certificate Store Name       : My
...

Why would the SSL Cert binding still be there if I successfully removed the binding from IIS using ServerManager?

Turns out that configuring the role for Remote Desktop from the Azure Portal was adding the binding. More specifically, updating the Certificate configuration for the role (which happens as part of RDP config) is causing it. This meant that it worked until I went in via RDP to check whether it was working at which point it would start to fail. Of course, genius that I am I was trying to be methodical and do things in the same order every time, which meant I was configuring remote desktop before actually attempting a request, so from my perspective it looked like it was failing from the beginning. It was only when I tried things in the opposite (running requests before configuring RDP) that it started to work.

You can use netsh http delete sslcert to delete the binding and it does not affect your ability to log in via RDP to that instance.

When you configure RDP it calls the RoleEnvironment.Changing and RoleEnvironment.Changed events, but unfortunately when those events are called the binding has not been created yet, so there's not an obvious place where you could use netsh http delete sslcert to delete the binding in code.

I don't know that this is an "answer" exactly. It means I still have an issue where configuring an Azure Instance for RDP or changing the cert configuration breaks my SNI bindings. For my organization this is OK because there are only a couple people with enough permissions to configure RDP and they can be trained to explicitly delete the new binding if they need to use RDP. I'll follow up here if I figure out a way to prevent this altogether.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM