Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
500 views
in Technique[技术] by (71.8m points)

ssl - Is SNI actually used and supported in browsers?

I can find various information about SNI (see Wikipedia), but I can't find any statistics about actual support in browsers.

The best I could find out is that it should work on Windows XP with SP3.

Does anyone know if SNI can actually be used in practice?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I can share my experience and approach to switching from one-IP-per certificate in a virtual hosting environment (multiple domains per server) to a load balanced environment with one IP for all domains.

We looked at our Analytics (over 1 million unique visitors / month), which is mostly North American male users looking to buy auto parts online, and found on March 8th, 2014 that approximately 4 % of users were on Windows XP using Internet Explorer (others were minor -- worst case 4.5 % of total users would be affected by not supporting SNI). Keep in mind that we have no "control" over these users so we can't tell them to switch browsers. This percentage is also dropping fairly quickly, at least in the US.

We first decided that it was "OK" for non SNI customers to have a somewhat different experience than customers supporting SNI.

Our approach was to detect server-side (using UA string) which browser/operating system combination does not support SNI (as other people mentioned: Wikipedia article on SNI support). All our domains (~ 120) would have an A record pointing to a single load-balanced IP. We had a second IP (also load balanced) for a domain we can call generic-autoparts.com.

So the setup is [I'm not associated with any domains I use as examples below]:

mikesautoparts.com --> A Nameserver Record of IP X
dansautoparts.com --> A Nameserver Record of IP X
jensautoparts.com --> A Nameserver Record of IP X
... etc

generic-autoparts.com --> A Nameserver Record of IP Y

If a customer hits http://www.dansautoparts.com, and supports SNI, nothing happens. He browses dansautoparts.com, and when it comes time to check out, he uses https://www.dansautoparts.com.

If a customer hits http://www.dansautoparts.com, and we detect that he does not support SNI, we immediately redirect the customer to http://generic-autoparts.com/dansautoparts.com. He shops on there, and at checkout he uses https://generic-autoparts.com/dansautoparts.com

Now, if a customer hits https://www.dansautoparts.com DIRECTLY (link in e-mail, indexed page in search engines), you are out of luck. They'll get a nasty certificate error. In our case, we made sure all e-mails our system sent didn't use https, and we knew that search engines had not indexed our https pages.

Each environment has different challenges and potential trade-offs. We found that this worked well in our case and customers would "accept" (or not notice) getting redirected to http://generic-autoparts.com/[ORIGINAL DOMAIN].com . We also kept checkout secure through generic-autoparts.com.

Let's say 20 % of nonSNI users notice the redirect, it seems fishy, and they leave. In our case, that's 0.8 - 0.9 % (based on March 8th, 2014 numbers) of users and we were willing to "live" with that. I don't have specific data on this right now, but overall sales held steady. [EDIT 3/28/2014: We saw no impact to sales after we switched 100 % of our customers]

Implementation Update July 8th, 2014

Turns out that it's impossible to detect every UA Agent string statically on the server. We implemented the following JavaScript to detect the browser's SNI capability. The general approach is to do a JSONP request against a domain that requires SNI (Apache supports this through "SSLStrictSNIVHostCheck on"). If the JSONP request fails by timing out, we redirect the customer to the nonSNI domain.

To further complicate matters, we do not want to redirect everyone just because the SNI_TEST_DOMAIN is down. If the JSONP request fails (by timing out since there's no way to detect a JSONP failure directly), we verify that the server is available by doing an HTTP "health-check" request. In addition, we do not want to run this javascript code on every page load, since that increases the chance of some strange timeout and incorrectly redirecting many customers, so we set a session variable once the SNI check is done so it won't happen again as the customer navigates the sites.

We know that we get certain false checks that fails due to the JSONP timeout being unreliable, but since implementing this we are getting no complaints from customers.

var redirect='http://REPLACE_WITH_NON_SNI_URL';

var sni_https_timeout, sni_http_timeout;
var https_req = $.ajax({
    url : 'https://SNI_TEST_DOMAIN.com/snitest.php',
    dataType : "jsonp",
}).done(function() {
        window.clearTimeout(sni_https_timeout);
        var request = $.ajax({
        url: "index.php?ua=sni_check_done",
       type: "POST"
    });
})

sni_https_timeout = window.setTimeout(function() {
    var http_req = $.ajax({
        url : 'http://SNI_TEST_DOMAIN/sni_healthcheck.php',
        dataType : "jsonp"
    }).done(function()
        {
            window.clearTimeout(sni_http_timeout);
            window.setTimeout(function()
            {
                window.location = redirect;
            },
        200);
    });

    sni_http_timeout = window.setTimeout(function() { sni_http_fail(); }, 8000);

}, 8000);

function sni_http_fail() {
    var request = $.ajax({
        url: "index.php?ua=sni_check_done",
        type: "POST"
    });
}

snitest.php / sni_healthcheck.php:

<?php
if (array_key_exists('callback', $_GET))
{
    header( 'Content-type: application/javascript' );
    echo "{$_GET['callback']}();
";
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...