I'm setting up Apache with several distinct SSL certificates for different domains that reside on the same server (and thus sharing the same IP address).
With Qualys SSL Test I discovered that there are clients (i.e. BingBot as of december 2013) that do not support the SNI extension.
So I'm thinking about crafting a special default web application that can gather the requests of such clients, but how can I simulate those clients?
I'm on Windows 8, with no access to Linux boxes, if that matters.
Because SNI is relatively new, not all browsers support SNI. If the browser does not support SNI, it is presented with a default SSL certificate.
A non-SNI client uses port 443 and is required if you want to integrate hybrid runtime instances with Google Cloud Load Balancing or for clients that do not support SNI.
SNI can be disabled by setting the property jsse. enableSNIExtension back to false on the Message Processor component. Note: When SNI is disabled on a client (Message Processor), the client does not pass the hostname of the backend server as part of the initial TLS handshake for all the API Proxies.
You can use the most commonly used SSL library, OpenSSL. Windows binaries are available to download.
openssl s_client -connect domain.com:443
command serves very well to test SSL connection from client side. It doesn't support SNI by default. You can append -servername domain.com
argument to enable SNI.
If you are using OpenSSL 1.1.0 or earlier version, use openssl s_client -connect $ip:$port
, and OpenSSL wouldn't enable the SNI extension
If you are using OpenSSL 1.1.1, you need add -noservername
flag to openssl s_client
.
Similar to openssl s_client is gnutls-cli
gnutls-cli --disable-sni www.google.com
You could install Strawberry Perl and then use the following script to simulate a client not supporting SNI:
use strict;
use warnings;
use LWP::UserAgent;
my $ua = LWP::UserAgent->new(ssl_opts => {
# this disables SNI
SSL_hostname => '',
# These disable certificate verification, so that we get a connection even
# if the certificate does not match the requested host or is invalid.
# Do not use in production code !!!
SSL_verify_mode => 0,
verify_hostname => 0,
});
# request some data
my $res = $ua->get('https://example.com');
# show headers
# pseudo header Client-SSL-Cert-Subject gives information about the
# peers certificate
print $res->headers_as_string;
# show response including header
# print $res->as_string;
By setting SSL_hostname to an empty string you can disable SNI, disabling this line enables SNI again.
The approach of using a special default web application simply would not work.
You can't do that because said limited clients not just open a different page, but they fail completely.
Consider you have a "default" vhost which a non-SNI client will open just fine.
You also have an additional vhost which is supposed to be open by an SNI-supporting client.
Obviously, these two must have different hostnames (say, default.example.com
and www.example.com
), else Apache or nginx wouldn't know which site to show to which connecting client.
Now, if a non-SNI client tries to open https://www.example.com
, he'll be presented a certificate from default.example.com
, which would give him a certificate error. This is a major caveat.
A fix for this error is to make a SAN (multi-domain) certificate that would include both www.example.com
and default.example.com
. Then, if a non-SNI client tries to open https://www.example.com
, he'll be presented with a valid certificate, but even then his Host:
header would still point to www.example.com
, and his request will get routed not to default.example.com
but to www.example.com
.
As you can see, you either block non-SNI clients completely or forward them to an expected vhost. There's no sensible option for a default web application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With