Thursday 17 March 2011

how to compile Apache 2.2 and openssl to support SNI

With the later versions of Apache 2.2 it is possible to build a system which supports SNI (subject name indication). This allows you to host multiple ssl websites on the same ip address. It is effectively a version of host headers for ssl.

I found surprisingly little information on the internet as to how to get this to work, so I thought I would create this to show how it is done!

The installation was performed on a virtual machine running opensuse 11.1 32bit, however I would imagine other Linux/unix versions would be similar.

First the installation of opensuse installs openssl however this is not compiled with TLS support built in, so it has to be recompiled to allow us to continue.

So, first back up the existing openssl executable:

root> cp /usr/bin/openssl /usr/bin/openssl.orig

Now download the latest openssl source code from www.openssl.org and place it in /tmp. When I did this the version available was 1.0.0d, so the rest of the document will reference this version. Extract the tar file and install it with the following commands:

root> cd /tmp
root> tar -xvzf openssl1.0.0d.tar.gz
root> cd openssl1.0.0d
root> ./config --prefix=/usr --openssldir=/usr/local/openssl enable-tlsext shared
root> make
root> make install

Openssl is now installed, so we confirm this by checking the version, with the following command:

root> openssl version

This should return the version installed, ie 1.0.0d

So we can now move onto the Apache installation, download the latest Apache 2.2 from www.apache.org, and place it in /tmp. I downloaded version 2.2.17, so will reference this version from this point forwards.

Compile and install it with these commands:

root> cd /tmp
root> tar -xvzf http-2.2.17.tar.gz
root> cd http-2.2.17
root> ./configure --prefix=/usr/local/apache-2.2.17 --with-mpm=worker --enable-deflate --enable-mime-magic --enable-proxy --enable-ssl --with-ssl=/usr/bin --disable-status --enable-vhost-alias --disable-cgid --disable-userdir --enable-rewrite --enable-mods-shared='isapi file_cache cache disk_cache mem_cache ext_filter expires headers usertrack unique_id status info cgi cgid speling'
root> make
root> make install

Apache should now be installed into the /usr/local/apache-2.2.17 directory.

I then like to symlink it to /usr/local/apache so run the command:

root> ln -s /usr/local/apache-2.2.17 /usr/local/apache

We now need to configure the ssl to use sni, so first make sure Apache will load the ssl configuration, to do this uncomment the following line in the /usr/local/apache/conf/http.conf file:

Include conf/extra/http--ssl.conf

We now need to create the ssl configuration file. For test purposes, we will create a new one, so let's move the old one out of the way:

root> cd /usr/local/apache/conf/extra
root> mv httpd-ssl.conf httpd-ssl.conf.orig

Now recreate the httpd-ssl.conf file with the following contents:


# Ensure that Apache listens on port 443
Listen 443

# Listen for virtual host requests on all IP addresses
NameVirtualHost *:443

# Go ahead and accept connections for these vhosts
# from non-SNI clients
SSLStrictSNIVHostCheck off

<VirtualHost *:443>
# Because this virtual host is defined first, it will
# be used as the default if the hostname is not received
# in the SSL handshake, e.g. if the browser doesn't support
# SNI.
DocumentRoot /www/example1
ServerName www.example.com

# Other directives here

</VirtualHost>

<VirtualHost *:443>
DocumentRoot /www/example2
ServerName www.example2.org

# Other directives here
</VirtualHost>

 

Save this file.

Next we need to create stubs for the two sites mentioned in the file above.  So lets create these now:

root> cd /
root> mkdir www
root> cd www
root> mkdir example1
root> mkdir example2

We are now in a position to try and start apache:

root> cd /usr/local/apache/bin
root> ./apachectl start

You should find that apache returns with no errors, however upon checking with the following command:

root> ps -ef |grep http

You will find it is not running.  However the fact that no errors were returned to the screen, shows that apache is successfully compiled with SNI support.

If you look in the error logs in /usr/local/apache/logs you will see that it is missing information about the ssl certificates.

This is now configured in the usual way you would do for a single SSL website, so will not be covered here.  To run multiple sites, each site definition in the httpd-ssl.conf file can now reference different certificates.

A word of note however, not all web browsers support TLS which is required for this to work.  Browsers that do not support TLS will use the first defined site in the httpd-ssl.conf file, therefore this should be defined as being the default site.  The list of browsers not supporting TLS is wide-ranging and can be found with a quick internet search.  One suprise for me is Internet Explorer 8 running on Windows XP does not support TLS, it does however support TLS on Windows Vista and later.

I hope this helps getting SNI working with Apache.
Published with Blogger-droid v1.6.7

3 comments:

  1. Thank you! it was useful...

    ReplyDelete
  2. This was very helpful..

    ReplyDelete
  3. The "SSLStrictSNIVHostCheck off" directive in ssl.conf or httpd.conf?

    Thanks

    ReplyDelete