SSL certificates on multiple virtual hosts with Apache2

As you can see if you already tried to install multiple SSL virtualhosts using mod_ssl (which relies on OpenSSL), if you activate them and restart Apache2, you will get a warning like :

[warn] vhost2 VirtualHost overlap on port 443, the first (vhost1) has precedence

If the warnings are not enabled or not displayed, you may see on a web browser a security alert for all SSL virtualhosts except the default one.

Indeed, it will always send the default SSL certificate if you use mod_ssl, the default SSL library.

What is the source of this issue ?

The SNI support in the SSL libraries, SNI means Server Name Indication, this option is not enabled by default in OpenSSL.

When a client connects to the webserver, it will first establish the SSL connection before knowing the server name, so the certificate that is sent is always the default one.

In OpenSSL, the SNI support has been integrated in the production versions since 0.9.8k, but it is not enabled by default, you will have to compile OpenSSL to get it to work.

An other library called GnuTLS has this option enabled so you may use it directly to create multiple SSL virtualhosts, each using their own certificate.

With a new OS version (Debian squeeze with security updates or Ubuntu LTS 1204 for example), OpenSSL is compiled with SNI by default, no need to re-compile OpenSSL or use GnuTLS, it will work out of the box.

How to solve this issue ?

Compile Apache2 & OpenSSL

The problem and the prerequisites to use OpenSSL with the SNI support and Apache2 is explained on the wiki of

Using the GnuTLS library

If compiling is not a thing you like to do, you can avoid the use of mod_SSL and use mod_GnuTLS, install first the package:

apt-get install libapache2-mod-gnutls 

Disable mod_SSL and enable mod_GnuTLS :

a2dismod ssl 
a2enmod gnutls 

Then configure the virtualhosts with the certificates :

  • erase the mod_ssl informations, espacially the two lines below :
<IfModule mod_ssl.c>
  • add the informations of the certificate using GnuTLS :
<VirtualHost *:443>
    ServerName domain1.tld
    DocumentRoot /var/www/domain1


    GnuTLSEnable on
    GnuTLSExportCertificates on
    GnuTLSCacheTimeout 500
    GnuTLSCertificateFile /etc/ssl/certs/domain1.crt
    #GnuTLSClientCAFile    /etc/ssl/
    GnuTLSKeyFile         /etc/ssl/private/domain1.key

    #GnuTLSPriorities NONE:+AES-128-CBC:+ARCFOUR-128:+RSA:+SHA1:+MD5:+COMP-NULL:$
    GnuTLSPriorities      NORMAL

    # SSL Protocol Adjustments:
    BrowserMatch ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force$

  • Do the same operation for the others SSL virtualhosts
  • restart the Apache2 service

Source : Multiple SSL certificates on a single IP/port using mod_GnuTLS

Last modified: 02/27/2013 at 10:43 by EM2419-GANDI