Setting Server Name Indication (SNI) takes off certificate binding

三世轮回 提交于 2019-12-12 21:51:45

问题


I'm using Microsoft.Web.Administration (inside a Wix CustomAction) to configure Server Name Indication and bind to an existing server certificate on a IIS 8.5 site.

Turns out, setting SNI takes off the certificate binding. The following code will make things clearer:

using Microsoft.Web.Administration;

var binding = site.Bindings.FirstOrDefault(x => x.IsIPPortHostBinding && x.Host == sitename);

binding.CertificateHash = certificate.GetCertHash();
binding.CertificateStoreName = store.Name;

// this statement is causing the certificate info to get messed up.
binding["sslFlags"] = 1; // or binding.SetAttributeValue("sslFlags", 1);

Results:

With binding["sslFlags"] = 1;

Without binding["sslFlags"] = 1;

Is this a bug or am I missing something? How can get both SNI and Certificate binding to stick?


回答1:


It seems Microsoft.Web.Administration v7.0 is the culprit here. This is the official one on NuGet gallery and it seems that it is meant for IIS 7 mainly (I mean it'll work for features common in both IIS 7 & 8 but anything that 7 doesn't have will have weird results like above).

Using IIS.Microsoft.Web.Adminstration (which seems to be a community uploaded package for IIS 8.5) works. Got the hint from this answer.

Updated code:

binding.CertificateHash = certificate.GetCertHash();
binding.CertificateStoreName = store.Name;

binding.SslFlags = SslFlags.Sni;  // <<< notice it has helpful enums



回答2:


This works for me with Microsoft.Web.Administration 7.0.0.0:

public static void CreateSiteHttps(string siteName, string physicalPath)
{
    using (var serverManager = new ServerManager())
    {
        var applicationPool = serverManager.ApplicationPools.Add(siteName);
        applicationPool["startMode"] = "AlwaysRunning";

        var x509Store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
        x509Store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite);

        var certificate = x509Store.Certificates.Find(X509FindType.FindBySubjectName, "MyCertSubjectName", false)[0];

        var hash = certificate.GetCertHash();

        var site = serverManager.Sites.Add(siteName, $"*:443:{siteName}", physicalPath, hash);
        site.ServerAutoStart = true;
        site.Bindings[0]["sslFlags"] = 1;
        site.ApplicationDefaults.ApplicationPoolName = applicationPool.Name;
        site.ApplicationDefaults.EnabledProtocols = "http,https";

        serverManager.CommitChanges();
    }
}



回答3:


The certificate is removed when enabling SNI. You can simply get the certificate before and set it again after enabling SNI:

var cert = mySslBinding.CertificateHash;
mySslBinding.SetAttributeValue("SslFlags", Convert.ToInt32(1));
mySslBinding.CertificateHash = cert;


来源:https://stackoverflow.com/questions/30536005/setting-server-name-indication-sni-takes-off-certificate-binding

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!