Apache SNI namevhosts always route to first VirtualHost entry
Apache seems to route all https requests to the first <VirtualHost *:443>
regardless of SNI matching on ServerName/ServerAlias fields.
Apache is built with SNI
Server version: Apache/2.2.22 (Ubuntu)
Server built: Mar 8 2013 15:53:13
OpenSSL 1.0.1 14 Mar 2012
error.log reports:
Init: Name-based SSL virtual hosts only work for clients with TLS server name indication support (RFC 4366)
Which suggests SNI is working as per http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI (How can you tell if your Apache build supports SNI?)
SSL_TLS_SNI
seems to be set appropriately when requested using HTTPS (verified with phpinfo()
)
Configuration:
<IfModule mod_ssl.c>
# If you add NameVirtualHost *:443 here, you will also have to change
# the VirtualHost statement in /etc/apache2/sites-available/default-ssl
# to <VirtualHost *:443>
# Server Name Indication for SSL named virtual hosts is currently not
# supported by MSIE on Windows XP.
NameVirtualHost *:443
Listen 443
</IfModule>
#<VirtualHost *:443>
# <Location />
# Order allow,deny
# Deny from all
# </Location>
#</VirtualHost>
<VirtualHost *:443>
SSLEngine on
ServerAdmin webmaster@localhost
ServerName server.com
ServerAlias server.com
DocumentRoot /web/default
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLCertificateFile /path/server.com.crt
SSLCertificateKeyFile /path/server.com.key
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
ServerAdmin webmaster@localhost
ServerName alias.com
ServerAlias alias.com
DocumentRoot /web/default
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLCertificateFile /path/alias.com.crt
SSLCertificateKeyFile /path/alias.com.key
</VirtualHost>
Both https://server.com and https://alias.com try to serve the certificate (and content if you disregard the cert warning) from server.com
Similar configuration works fine using HTTP:80 (only change is SSLEngine on and the certificate/key paths)
If I uncomment the first virtual host (restricting HTTPS access to sites that are defined) then I always get a SSL error (even if it is a defined site)
Thanks
EDIT:
Additional flags
SSLProtocol all
SSLCipherSuite HIGH:MEDIUM
SSLStrictSNIVHostCheck on
SSLVerifyClient none
SSLProxyEngine off
SSLStrictSNIVHostCheck on
so it should only support SNI enabled browsers anyway
apache2ctl -S
output:
*:443 is a NameVirtualHost
default server server.com (/etc/apache2/sites-enabled/000-default:22)
port 443 namevhost server.com (/etc/apache2/sites-enabled/000-default:22)
port 443 namevhost alias.com (/etc/apache2/sites-enabled/000-default:39)
port 443 namevhost other.com (/etc/apache2/sites-enabled/other:22)
Update
So for some strange reason, the problem seems to have resolved itself.
Perhaps it's some sort of strange caching issue or something (though I have apache2ctl stop/start/restart
and sudo service apache2 stop/start/restart/reload
ed many times and have performed tests locally on the server as well as using several different machines).
Feel free to take this question down or leave it up if it serves as any sort of reference.
Thanks for all the help guys!
Your configuration looks OK; The directive SSLEngine On has been included; According to the log message, it looks like the issue comes from the client side.
Not all clients support SNI, however most of them do. It depends on how the SSL negociation is made, by the system (does not work on Win XP then) or by the browser (the version must be recent enough). Look at list of browsers with support of SNI. If you must ensure all clients get access to your websites, you can't use SNI because of these old versions (of the browser or of the system). You would need an IP per ServerName and use VirtualHost $IP_alias:443 for ServerName alias.com and VirtualHost $IP_server:443 for ServerName server.com instead of VirtualHost *:443 for both.