Disabling SNI for specific virtualhost on Apache

As others have stated just put the first site as the first virtual host and it will work whether SNI is enabled or not:

<VirtualHost *:443>

   ServerName www.site1.com

   DocumentRoot /site1/

   SSLCertificateKeyFile /ssl/server1.key
   SSLCertificateFile /ssl/server1.crt

</VirtualHost>

<VirtualHost *:443>

   ServerName www.site2.com

   DocumentRoot /site2/

   SSLCertificateKeyFile /ssl/server2.key
   SSLCertificateFile /ssl/server2.crt

</VirtualHost>

However non-SNI browsers to site 2 will be served the certificate for site1 and so will error (and the users might wonder why they've got a certificate for a different site, though if still on non-SNI browsers they are probably not that tech savvy).

However, it is possible to provide access to all users for all your sites, despite the apparent SNI issue, if you have a single certificate that covers all the sites subject alternative name field.

You can then have two virtual hosts using the same key and cert:

<VirtualHost *:443>

   ServerName www.site1.com

   DocumentRoot /site1/

   SSLCertificateKeyFile /ssl/server.key
   SSLCertificateFile /ssl/server.crt

</VirtualHost>

<VirtualHost *:443>

   ServerName www.site2.com

   DocumentRoot /site2/

   SSLCertificateKeyFile /ssl/server.key
   SSLCertificateFile /ssl/server.crt

</VirtualHost>

So you have the same key and certificate for two sites (or three, or more if you want).

So www.site1.com always works as, even without SNI support it's the default host.

For www.site2.com it gets more interesting:

  • For browsers that support SNI, they provide the server name and go straight to the site2 virtual host config and that works.
  • For browsers which do not support SNI, they default to the site1 config, which returns it's certificate, but as the certificate works for both sites, that's actually OK. After SSL negotiation is complete the first web request comes in, but as this time the server is given the server name, it can correctly serve the document from /site2/ directory.

So this works because a https connection involves two distinct and unrelated steps: 1) do SSL negotiation and 2) request document using that SSL connection, and these two steps do not have to be from the same virtual host (though most people assume it does).

The main downside with this option is that, depending how closely related the websites are, it may look unprofessional to have two different URLs on the same certificate. However, presumably if they are sharing a host, they are somewhat related businesses (unless the server is owned by a hosting company) so this may not be an issue.

I find this a handy little workaround, especially for dev servers where I might want to host several sites on one IP address, where I use self-signed cents with multiple URL in the subject alternative name field.


You don't "disable" SNI on the server-side -- you can't even control whether or not the client sends the extension. All you can do is define how your server responds to the presence (or absence) of SNI information.

Typically, when a server receives a request which lacks SNI information, it will select one of the certificates that are available to present to the client. For Apache, it will be the first vhost for the address/port pair that is being listened on.

As to whether or not to have a separate "non-SNI" address for the site you wish to make securely accessable without SNI, I don't think it's important. You may as well save a valuable IPv4 address and just put them all on the same IP. Anyone accessing an SNI-only site from a non-SNI browser is going to get the same certificate warnings anyway, whether or not its the same address as the non-SNI site or not. The only consideration is whether or not you want the certificate for the site which supports non-SNI clients being presented to non-SNI clients when they access an SNI-only site.

I've now typed "SNI" so many times, it's starting to lose all meaning...