mod_ssl and Server Name Indication (SNI)


While configuring Apache for SSL / SNI I ran into a few errors:

 

[root@webapps ~]# service httpd restart

Stopping httpd: [ OK ]

Starting httpd: Syntax error on line 1068 of /etc/httpd/conf/httpd.conf:

Invalid command 'SSLEngine', perhaps misspelled or defined by a module not included in the server configuration

[FAILED]

 

[root@webapps ~]# service httpd restart

Stopping httpd: [ OK ]

Starting httpd: [Sun Jan 01 03:15:08 2012] [error] (EAI 5)No address associated with hostname: Could not resolve host name *443 -- ignoring!

[Sun Jan 01 03:15:08 2012] [warn] _default_ VirtualHost overlap on port 443, the first has precedence

[ OK ]

Notes:

 

About Server Name Indication:

SNI (Server Name Indication) Allows multiple SSL websites to be hosted off of a single IP Address with each using a different certificate. Given that I don't have unlimited budget for dedicated IP Addresses, I am implementing it on my VPS based web applications. There are 2 important limitations that I should note here:

  • Windows XP machines running Internet Explorer or Safari do *not* support SNI
    • The work-around is to use Firefox 2.0+ or Chrome 6+
  • Mac OS Versions lower than 10.5.6 / 10.5.7 need to use Chrome 5+ or Firefox 2.0+

Given that there are still a lot of XP machines out there (wikipedia.org) whose browser state is unknown, implementing SNI may not be the best thing to try in every case. I'm just using SSL to secure the channel against eavesdropping. If I were an e-commerce site I'd stick to more traditional methods.

Install mod_ssl:

mod_ssl on Apache allows SNI to be implemented in virtual hosts. There are a few Important Notes that you should keep in mind when implementing mod_ssl on Apache for purposes of SNI:

  • Use OpenSSL 0.9.8f or later
  • Apache must be able to resolve OpenSSL at startup
  • Read the Complete List so you don't get caught by suprises

 

To install mod_ssl on Centos 6, you can use these commands:

 

  • yum install mod_ssl
  • service httpd restart

Note: yum will install mod_ssl. Once installed you should restart apache to use it.

 

How to resolve the Errors listed in the Article Header:

  • Invalid command 'SSLEngine', perhaps misspelled or defined by a module not included in the server configuration
    • To get around this error I just had to install mod_ssl (using the command listed above).

  • [warn] _default_ VirtualHost overlap on port 443, the first has precedence
    • To get around this error I had to:
      • Edit my Apache config file (httpd.conf) to allow NameVirtualHosting
      • Setup a VirtualHost directive to listen on port 443
        (See further down for an example of a working SSL/SNI VirtualHost directive)

    • Here is the line I added to httpd.conf for SSL NameVirtualHost (Bolded Line):
      #
      # Use name-based virtual hosting.
      #
      NameVirtualHost *:80
      NameVirtualHost *:443

  • [error] (EAI 5)No address associated with hostname: Could not resolve host name *443 – ignoring!
    • This error resulted from a typo. When I setup the NameVirtualHost directive I omitted the colon between the asterisk and the port (I used *443 where *:443 is the correct form. Once I added the colon in this error went away

 

Example of a VirtualHost Directive with SSL/SNI enabled:

Here is a functioning example of a VirtualHost directive setup to use SSL / SNI. You can compare the differences between this and the non-SSL/SNI version by checking out my article on mod_rewrite (Bolded Lines are explained below):

 

<VirtualHost *:443>

# Enable the SSL Engine

SSLEngine on

SSLCertificateFile /var/path/to/certificate_file.pem

SSLCertificateKeyFile /var/path/to/private_key.key

 

#Specify the server name and SSL Options (Disallow SSLv2)

ServerName html5clipboard.net

SSLOptions StrictRequire

SSLProtocol all -SSLv2

 

# Specify the document root

DocumentRoot /var/www/apps/php/webapp

 

#

# Rewrite rules for vanity urls

RewriteEngine On

 

# Prevent folder or file access

RewriteCond %{SCRIPT_FILENAME} !-d

RewriteCond %{SCRIPT_FILENAME} !-f

 

#RewriteBase /var/www/apps/php/production/html5clipboard

RewriteRule ^/about/us$ /about.php

RewriteRule ^/about/legal$ /legal.php

RewriteRule ^/[a-zA-Z0-9]+/*$ /service/clip.php?id=$1

 

# Logging

ErrorLog logs/webapp.net-error_log

CustomLog logs/webapp.net-access_log common

</VirtualHost>

 

Explanation:

  • SSLEngine on
    • This enables SSL for the VirtualHost
  • SSLCertificateFile /var/path/to/certificate_file.pem
    • This specifies the certificate associated with the VirtualHost
  • SSLCertificateKeyFile /var/path/to/private_key.key
    • This indicates where the corresponding Private Key is located
  • SSLOptions StrictRequire
  • SSLProtocol all -SSLv2
    • This enables all Secure protocols except for SSLv2 (see documentation)

 

With all of the above configured, I have 0 errors when apache boots and I'm able to assign ssl key/certificate pairs for each VirtualHost on my apache server.