问题
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