Since SNI occurs during the SSL/TLS handshake, it's not possible to detect browser support when the client connects to HTTP.
So, you're right; a user-agent filter is the only way to do this.
The big question is whether you want to act on a blacklist against browsers that you know won't listen for SNI, or a whitelist of browsers that are known to support it. Obscure or new devices being unable to use the site seems like a deal-breaker, so I'd say the whitelist might be the better option.
In your HTTP <VirtualHost>
:
# Internet Explorer 7, 8, 9, on Vista or newer
RewriteCond %{HTTP_USER_AGENT} MSIE\s7.*Windows\sNT\s6 [OR]
RewriteCond %{HTTP_USER_AGENT} MSIE\s8.*Windows\sNT\s6 [OR]
RewriteCond %{HTTP_USER_AGENT} MSIE\s9.*Windows\sNT\s6 [OR]
# Chrome on Windows, Mac, Linux
RewriteCond %{HTTP_USER_AGENT} Windows\sNT\s6.*Chrome [OR]
RewriteCond %{HTTP_USER_AGENT} Macintosh.*Chrome [OR]
RewriteCond %{HTTP_USER_AGENT} Linux.*Chrome [OR]
# Firefox - we'll just make the assumption that all versions in the wild support:
RewriteCond %{HTTP_USER_AGENT} Gecko.*Firefox
RewriteRule ^/(.*)$ https://ssl.hostname/$1 [R=301]
Here's the blacklist option, too - keep in mind that this runs the risk of sending a client that doesn't use SNI to an SNI-needed site, but on the other hand, will send users of something new like IE 10 to the right place:
# IE 6
RewriteCond %{HTTP_USER_AGENT} !MSIE\s6
# Windows XP/2003
RewriteCond %{HTTP_USER_AGENT} !Windows\sNT\s5
# etc etc
RewriteRule ^/(.*)$ https://ssl.hostname/$1 [R=301]
There are a lot of browsers out there. I've been pretty loose with the expressions and haven't covered a lot of browsers - this could turn into quite the nightmare to maintain.
Whichever option you choose.. good luck!
The default_server
setting of the listen
directive should determine which certificate is sent for a request without SNI set in the handshake. Change the listen
directive of the desired default:
listen 443 default_server ssl;
Best Answer
That depends on how your web server reacts when receiving a HTTPS request without SNI. (If you want to test it, you can simulate a non-SNI browser with openssl. Basic HTTP protocol knowledge required.)
With IIS 10, the following happens:
If there is a "default SSL site" (a site bound to port 443 without a host name) configured, the non-SNI client will see:
This makes perfect sense:
Host:
header and returns the correct content.If there is no "default SSL site" configured, the connection will be closed.
(Source: Just tested it with an old Windows XP IE8 virtual machine.)