Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNI support in binding #7

Open
kallex opened this issue Oct 25, 2013 · 9 comments
Open

SNI support in binding #7

kallex opened this issue Oct 25, 2013 · 9 comments

Comments

@kallex
Copy link

kallex commented Oct 25, 2013

SNI (Server Name Indication) has been supported in IIS 8. It's the feature that allows using multiple SSL certs on same endpoint.

This feature allows using multiple wildcard certs on same endpoint - effectively removing the requirement for endpoint-per-SSL-cert.

Any plans to support it? Or is it already supported, not mentioned in basic readme parts yet.

@kallex
Copy link
Author

kallex commented Oct 25, 2013

Update: I digged through the code, and found the SslFlags in Bindings, and candidate for the spot to include them. Haven't tested yet myself (trying to asap), but here's where I got:

File IISManager.cs, line 208 - captured the new binding and set it's SslFlags:

if (cert != null)
{
_logger.InfoFormat("Adding Binding '{0}' for website '{1}' with Binding Information '{2}' and Certificate '{3}'", binding.Id, site.Name, binding.BindingInformation, cert.Thumbprint);
var addedBinding = iisSite.Bindings.Add(binding.BindingInformation, cert.GetCertHash(), StoreName.My.ToString());
// Set SslFlags, TODO: Conditional binding info
addedBinding.SslFlags = SslFlags.Sni;
}

Update 2: The SslFlags property (with proper values) was there for the intellisense to find, before I started to gather the Microsoft.Web. assemblies for the build. I'm entering unfamiliar territory of where-to-get-the-Microsoft.Web assemblies...

@mikoskinen
Copy link

I have a version of AzureWebFarm which includes the SNI support. The code just needs some cleaning, which I've been planning to do for the past 3 months or so...

The SNI requires changes to couple places, all in IISManager.cs. First is when a completely new site is created:

                    if (cert != null)
                    {
                        _logger.InfoFormat("Adding website '{0}' with Binding Information '{1}' and Certificate '{2}'", site.Name, defaultBinding.BindingInformation, cert.Thumbprint);

                        iisSite = serverManager.Sites.Add(
                            siteName,
                            defaultBinding.BindingInformation,
                            sitePath,
                            cert.GetCertHash(), StoreName.My.ToString(), SslFlags.Sni);
                    }

Second change is for a new binding:

                        if (cert != null)
                        {
                            _logger.InfoFormat("Adding Binding '{0}' for website '{1}' with Binding Information '{2}' and Certificate '{3}'", binding.Id, site.Name, binding.BindingInformation, cert.Thumbprint);
                            iisSite.Bindings.Add(binding.BindingInformation, cert.GetCertHash(), StoreName.My.ToString(), SslFlags.Sni);
                        }

There's one more change I did. As the main web site has a HTTPS binding with a certificate, this binding will interfere with the SNI bindings created for other web sites. You'll get certificate errors for the SNI bindings. I ended up just deleting the HTTPS binding of the main site. I did this by adding the following code into the top of the UpdateSites:

            var iisSites = serverManager.Sites;

            _logger.DebugFormat("Sites list from IIS: {0}", string.Join(",", iisSites.Select(s => s.Name)));

            var mainSite =
                iisSites.FirstOrDefault(
                    x => x.Name.Equals(AzureRoleEnvironment.RoleWebsiteName(), StringComparison.OrdinalIgnoreCase));

            if (mainSite != null)
            {
                _logger.DebugFormat("Trying to delete the https binding's from main site: {0}.", mainSite.Name);

                var sslBinding = mainSite.Bindings.FirstOrDefault(x => string.Equals(x.Protocol, "https"));
                if (sslBinding == null)
                {
                    _logger.DebugFormat("The main site {0} doesn't have SSL Certificate set.", mainSite.Name);
                }
                else
                {
                    mainSite.Bindings.Remove(sslBinding);
                    try
                    {
                        _logger.DebugFormat("Committing updates to IIS for site '{0}'", mainSite.Name);
                        serverManager.CommitChanges();
                    }
                    catch (Exception e)
                    {
                        _logger.ErrorFormat(e, "Error committing changes for site '{0}'", mainSite.Name);
                    }
                }
            }

@robdmoore
Copy link
Member

This is awesome guys!

I'll definitely look into this with Matt and try and get it into the
codebase :)

Eta is probably a month or two though sorry!

If you send through a PR I'm happy to merge it and get it in earlier though.

Only thing is, I'd want to make SNI opt in (and possibly opt in per-site if
that's possible - or it it all or nothing?).

@kallex
Copy link
Author

kallex commented Oct 25, 2013

For what I gathered of SNI support in IIS, it also allows CSS (common certificate store), that to me looked like normal filesystem share.

While Azure WebFarm already handles certs on its own, that CSS might bring flexibility to cert management on certain dynamicly-added-binding scenarios.

@mikoskinen
Copy link

It's possible to make SNI opt-in for the installation. But AFAIK, if it's enabled, it must be enabled for all the sites in that installation. I can recheck this.

Regarding Centralized Certificate Store, it's slightly different thing from SNI. You can use SNI with CCS or without it. What CCS enables is that you can copy certificates into web share and use them from there, instead of installing certificates to every server. But, CCS isn't needed with Azure Cloud Services as Azure automatically installs the certificates to all the servers.

@robdmoore
Copy link
Member

Cool - if you can find that out it would be great. If it's an
all-or-nothing opt-in then I'd want to put it in the .cscfg probably?

Thanks for clarifying about CCS :)

@kallex
Copy link
Author

kallex commented Oct 25, 2013

Mikael, could you share your code (and care to help me with Microsoft.Web.* issues with build)?

Or is it already available in that form forked perhaps?

I'm deploying right now/Monday a version where I effectively need the SNI functionality.

@kallex
Copy link
Author

kallex commented Oct 26, 2013

Thanks to Mikael for helping with Microsoft.Web.* parts and the code parts in the thread, I migrated to my quite recently refreshed fork at: https://github.com/abstractiondev/AzureWebFarm

Completely untested by me, and also not including the assemblies, as I'm not sure where they need to be "officially" get to be redistributed properly. I'll put this bit into reality-test on Monday and report back...

@kallex
Copy link
Author

kallex commented Oct 28, 2013

Early real-world results are positive - it works! I'm not sure if there is an issue with changing bindings (by changing cert), I'll keep looking to that... and there seems to be need to support that CCS as well.

Rigth now the way I got it to work there is problem with certain scenarios: the certificates need to be introduced at the deployment so that they end up to webroles. They cannot be assigned for binding if they're not present. For scenarios where one ends up deploying certs and sites dynamically later on, this is a problem.

There might be something I'm missing in updating certs on roles more dynamic fashion... so I keep investigating a bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants