You are viewing a plain text version of this content. The canonical link for it is here.
Posted to wiki-changes@httpd.apache.org by Apache Wiki <wi...@apache.org> on 2009/04/08 20:35:33 UTC

[Httpd Wiki] Update of "NameBasedSSLVHostsWithSNI" by DanPoirier

Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Httpd Wiki" for change notification.

The following page has been changed by DanPoirier:
http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI

New page:
= SSL with Virtual Hosts Using SNI =

== Summary ==

Using name-based virtual hosts with SSL adds
another layer of complication.  Without the SNI extension,
it's not generally possible (though a subset of virtual host
might work).  With SNI, it's necessary to
consider the configuration carefully to ensure security is
maintained.

== The Problem ==

The problem with using named virtual hosts over SSL is that named
virtual hosts rely on knowing what hostname is being requested, and
the request can't be read until the SSL connection is established.
The ordinary behavior, then, is that the SSL connection is set up
using the configuration in the default virtual host for the address
where the connection was received.

While Apache can renegotiate the SSL connection later after seeing
the hostname in the request (and does), that's too late to pick
the right server certificate to use to match the request hostname
during the initial handshake,
resulting in browser warnings/errors about certificates having the
wrong hostname in them.

And while it's possible to put multiple hostnames in a modern
certificate and just use that one certificate in the default vhost,
there are many hosting providers who are hosting far too many sites
on a single address for that to be practical for them.

== Server Name Indication ==

The solution is an extension to the SSL protocol
called 
'''Server Name Indication'''
([http://www.ietf.org/rfc/rfc4366.txt RFC 4366]), 
which
allows the client to include the requested hostname in the first
message of its SSL handshake (connection setup).  This allows the
server to determine the correct named virtual host for the request
and set the connection up accordingly from the start.

== Prerequisites to use SNI ==

 * Use OpenSSL 0.9.8f or later
 * Build OpenSSL with the TLS Extensions option enabled (option enable-tlsext; OpenSSL 0.9.9 might have this enabled by default).
 * Apache must have been built with that OpenSSL (./configure --with-ssl=/path/to/your/openssl).  In that case, mod_ssl will automatically detect the availability of the TLS extensions and support SNI.
 * Apache must use that OpenSSL at run-time, which might require setting LD_LIBRARY_PATH or equivalent to point to that OpenSSL, maybe in bin/envvars.  (You'll get unresolved symbol errors at Apache startup if Apache was built with SNI but isn't finding the right openssl libraries at run-time.)

How can you tell if your Apache build supports SNI?  If you
configure multiple name-based virtual hosts for an address where SSL
is configured, and SNI isn't built into your Apache, then upon
Apache startup a message like "You should not use name-based virtual
hosts in conjunction with SSL!!" will occur in the error log.  If
SNI is built in, then the error log will show "[warn] Init:
Name-based SSL virtual hosts only work for clients with TLS server
name indication support (RFC 4366)".


The client browser must also support SNI.  Here are some browsers
that do:

 * Mozilla Firefox 2.0 or later
 * Opera 8.0 or later (with TLS 1.1 enabled)
 * Internet Explorer 7.0 or later (on Vista, not XP)
 * Google Chrome
 * Safari 3.2.1 on Mac OS X 10.5.6

(per [http://en.wikipedia.org/wiki/Server_Name_Indication#Browsers Wikipedia])

== Changes in configuration to use SNI ==

There aren't any new directives related to SNI.

The first (default) vhost for SSL name-based virtual hosts
'''must''' include TLSv1 as a permitted protocol,
otherwise Apache will not accept the SNI information from the
client and it will be as if the client did not support SNI at
all.

Since the first (default) vhost will be used for any request
where the provided server name doesn't match another vhost, it
is important that the first vhost
have the most restrictive access control, otherwise clients can
access restricted resources by sending a request for any
unknown hostname. (This isn't actually any different
from using virtual hosts without SSL.)

== Environment variables ==

When Apache supports SNI and the client provided the
hostname using SNI, the new environment variable
SSL_TLS_SNI will be set to the hostname that the client
provided.

== Scenarios ==

=== SNI/Request hostname mismatch, or SNI provides hostname and request doesn't. ===

This is a browser bug.  Apache will reject the request with a 400-type
error.

=== Client doesn't support SNI. ===

If Apache has SNI support, and a request without the SNI hostname
is received for a name-based virtual host over SSL, it will be
rejected (403) and this message logged:

{{{ [error] No hostname was provided via SNI for a name based virtual host }}}

== Examples ==

=== Server configuration ===

{{{
# Ensure that Apache listens on port 443
Listen 443
    
# Listen for virtual host requests on all IP addresses
NameVirtualHost *:443

<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.example.org

  # Other directives here

</VirtualHost>
}}}