简体   繁体   English

调用Bindings.Remove不会从HTTP.sys中删除SSL证书

[英]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. 我的问题的最短版本是调用ServerManager.Binding.Remove似乎从IIS中删除绑定,但仍然将其保留在HTTP.sys或设置SSL绑定的任何地方,并进一步打破我的代码层。

I'm running an Azure Cloud Service that needs to use SNI to support multiple hostnames using SSL. 我正在运行一个Azure云服务,需要使用SNI来支持使用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) . 有效地我在做什么是处理通信去掉默认使用绑定ServerManager.Binding.Remove(binding)和添加使用我自己绑定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 . 最终发生的是默认IP:端口绑定从IIS绑定列表中删除,但当我调用netsh http show sslcert时它仍然显示在SSL绑定列表中。

So, for example, here's the output from calling Get-WebBinding in Powershell. 因此,例如,这是在Powershell中调用Get-WebBinding的输出。 Notice that the default IP:Port binding is not there: 请注意,默认IP:端口绑定不存在:

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: 看起来不错,但它仍然不起作用,因为如果我运行netsh http show sslcert我得到以下内容:

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? 如果使用ServerManager从IIS成功删除绑定,为什么SSL Cert绑定仍然存在?

Turns out that configuring the role for Remote Desktop from the Azure Portal was adding the binding. 事实证明,从Azure门户配置远程桌面的角色是添加绑定。 More specifically, updating the Certificate configuration for the role (which happens as part of RDP config) is causing it. 更具体地说,更新角色的证书配置(作为RDP配置的一部分发生)正在导致它。 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. 这意味着它一直工作,直到我通过RDP进入检查它是否正在工作,它将开始失败。 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. 只有当我尝试相反的事情(在配置RDP之前运行请求)它才开始工作。

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. 您可以使用netsh http delete sslcert删除绑定,它不会影响您通过RDP登录到该实例的能力。

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. 配置RDP时,它调用RoleEnvironment.ChangingRoleEnvironment.Changed事件,但不幸的是,当调用这些事件时尚未创建绑定,因此没有明显的地方可以使用netsh http delete sslcert删除绑定码。

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. 这意味着我仍有一个问题,即为RDP配置Azure实例或更改证书配置会破坏我的SNI绑定。 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. 对于我的组织,这是可以的,因为只有几个人具有足够的权限来配置RDP,并且如果他们需要使用RDP,他们可以接受培训以明确删除新绑定。 I'll follow up here if I figure out a way to prevent this altogether. 如果我找到一种完全防止这种情况的方法,我会在这里跟进。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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