Ssl – Resolving multiple apache name-based virtual host with ssl

apache-2.4sslvirtualhost

I have the following configurations in my httpd-ssl.conf

NameVirtualHost *:8443

<VirtualHost _default_:8443>
ServerName sub.domain1.com
ServerAlias sub2.domain1.com
SSLEngine on
SSLCertificateFile "/path/to/file.crt"
SSLCertificateKeyFile "/path/to/file.key"
SSLCertificateChainFile "/path/to/chainFile.crt"
# some other settings...
</VirtualHost>

<VirtualHost _default_:8443>
ServerName www.domain1.com
ServerAlias domain1.com
SSLEngine on
SSLCertificateFile "/path/to/file.crt"
SSLCertificateKeyFile "/path/to/file.key"
SSLCertificateChainFile "/path/to/chainFile.crt"
Redirect permanent / http://www.domain1.com/
</VirtualHost>

<VirtualHost _default_:8443>
ServerName www.domain2.com
ServerAlias domain2.com
SSLEngine on
SSLCertificateFile "/path/to/file.crt"
SSLCertificateKeyFile "/path/to/file.key"
SSLCertificateChainFile "/path/to/chainFile.crt"
Redirect permanent / http://www.domain2.com/
</VirtualHost>

When I enter into the browser a url like https://www.domain2.com/resource-under-sub.domain1.com, it actually goes to the path https://sub.domain1.com/resource-under-sub.domain1.com instead of redirecting to http://www.domain2.com. What is wrong with my settings?


Response to @Nic regarding SNI:

I checked my Apache, and from https://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI it looks SNI is enabled from the log message:
Name-based SSL virtual hosts only work for clients with TLS server name indication support (RFC 4366). I was also using Firefox 56 which should support SNI from https://www.kinamo.be/en/support/faq/which-browsers-support-server-name-indication-sni. However, when I go to the url for the second virtual host it still takes me to the first default virtual host.

This https://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI and this https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslprotocol suggest for Apache 2.4 (which I am running), that the default setting supports TLSv1 and SNI. In my error and ssl logs, it does not show any records for my requests to the second virtual host, although it does for other hosts, e.g. No matching SSL virtual host for servername other.domain1.com found (using default/first virtual host) and these are using SSLv3 as seen from the message OpenSSL: Loop: SSLv3 read client hello A. However I can also see from the ssl request logs that TLSv1 is being used for some resources: TLSv1 AES128-SHA "GET /javax.faces.resource/theme.css.seam...

Do I need to explicit specify using TLSv1 in the configuration SSLProtocol +TLSv1?

Thanks


Response to @dave_thompson_085:

Thanks, I tried the following configuration, and also cleared the browser cache:

NameVirtualHost _default_:8443

# Default virtual host and catch all
<VirtualHost _default_:8443>
ServerName www.domain1.com
ServerAlias www.domain1.com
SSLEngine on
SSLProtocol all -SSLv3
SSLCertificateFile "/path/to/file.crt"
SSLCertificateKeyFile "/path/to/file.key"
SSLCertificateChainFile "/path/to/chainFile.crt"
# I want to redirect the https to http
Redirect permanent / http://www.domain1.com/
</VirtualHost>

# This is the only virtual host name that should handle the ssl
<VirtualHost _default_:8443>
ServerName sub.domain1.com
ServerAlias sub2.domain1.com
SSLEngine on
SSLCertificateFile "/path/to/file.crt"
SSLCertificateKeyFile "/path/to/file.key"
SSLCertificateChainFile "/path/to/chainFile.crt"
# some other settings...
</VirtualHost>

<VirtualHost _default_:8443>
ServerName www.domain2.com
ServerAlias domain2.com
SSLEngine on
SSLCertificateFile "/path/to/file.crt"
SSLCertificateKeyFile "/path/to/file.key"
SSLCertificateChainFile "/path/to/chainFile.crt"
# I want to redirect the https to http
Redirect permanent / http://www.domain2.com/
</VirtualHost>

# Other virtual hosts like www.domain2.com

When I access https://www.domain2.com, this is what I get in the error_log_ssl:

[Mon Oct 16 08:10:07 2017] [debug] ssl_engine_io.c(1830): +------------------------------+
[Mon Oct 16 08:10:07 2017] [debug] ssl_engine_io.c(1869): | 0000: ...
[Mon Oct 16 08:10:07 2017] [debug] ssl_engine_io.c(1869): | 0010: ...
[Mon Oct 16 08:10:07 2017] [debug] ssl_engine_io.c(1869): | 0020: ...
[Mon Oct 16 08:10:07 2017] [debug] ssl_engine_io.c(1869): | ...
[Mon Oct 16 08:10:07 2017] [debug] ssl_engine_io.c(1869): | 0060: ... www.domain2.com |
[Mon Oct 16 08:10:07 2017] [debug] ssl_engine_io.c(1869): | ...
[Mon Oct 16 08:10:07 2017] [debug] ssl_engine_io.c(1875): +------------------------------+
[Mon Oct 16 08:10:07 2017] [debug] ssl_engine_kernel.c(1987): [client 207.46.13.160] SSL virtual host for servername www.domain2.com found
**[Mon Oct 16 08:10:07 2017] [debug] ssl_engine_kernel.c(1274): [client 207.46.13.160] handing out temporary 1024 bit DH key
**[Mon Oct 16 08:10:07 2017] [info] [client n1.n2.n3.n4] (70014)End of file found: SSL input filter read failed.
[Mon Oct 16 08:10:07 2017] [info] [client n1.n2.n3.n4] Connection closed to child 199 with standard shutdown (server www.domain2.com:443)

Lines marked ** only occur sometimes. It seems like SSL named virtual host is working from the line SSL virtual host for servername www.domain2.com found. In the browser, it shows that the certificate is unsafe because it doesn't match the serverName, and if I don't accept the certificate, then it doesn't go further, which is fair enough. But if I accept the certificate, it still gets redirected to sub.domain1.com, the site that truly handles the SSL. Why doesn't it redirect to www.domain2.com as specified in the settings?

Thanks so much for your help!

Best Answer

With regular Apache and SSL certificates, you cannot do that. The negotiation of SSL is done before the name virtual hosting. So the basic answer is to get one IP per site.

A couple years ago certificates and browser started supporting SNI to get around that limit. Look up SNI (Server Name Indication). The majority of recent browsers support that now. But beware that users with old browsers will not be able to access all your sites (well actually they will always try to access the first VirtualHost defined in your configuration, which is the default chosen when name virtual hosting does not work).

In your question you say that are are always sent to sub-domain1, which is logical, since it takes the first VirtualHost found, as I just explained above.