Is it possible to set an SSLProtocol in Apache for a single VirtualHost (poodle)?

Solution 1:

You can set the SSLProtocol only for the first VirtualHost in the configuration file. All subsequent VirtualHost entries will inherit that setting from the first entry and silently ignore their own setting due to an OpenSSL bug.

There is a corresponding bug report for mod_ssl, but as described in the bug report, the problem needs to be resolved in OpenSSL (certificate is inherited but not the protocols).

The cipher suites must be set independently for each VirtualHost, otherwise you will end up with the default list, including a lot of insecure ciphers. Also, be aware that older clients that do not support Server Name Indication (SNI) will always use the default host (unless blocked using SSLStrictSNIVHostCheck), which can confound your testing.

In short, you should be able to specify custom cipher suites and certificates for each virtual host, but until the bug is fixed do not expect correct behavior with custom protocols for each virtual host.

I encountered this problem with Apache 2.4 and modssl with OpenSSL 1.0.1k, and I expect that Apache 2.2 would be subject to the same issues.

Update (October 2016): The OpenSSL bug was marked as resolved on October 13, 2016. However, it was part of a mass closure of open issues and although a 'partial fix' was supplied, the problem was never fully addressed.

Update (April 2018): The resubmitted OpenSSL bug now has a patch available (as of April 9, 2018). This patch will change the behavior of Apache instances configured with multiple SNI virtual hosts:

Reject connections not conforming to vhost SSLProtocol

This was developed and tested with 2.4.27 and in production with that version. The patch was modified for 2.4.33 and lightly tested.

This checks the version of the connection against the SSLProtocol configured for the virtual host that is matched based on the SNI. Because the connection is initially made with the SSLProtocol configured for the default host for the port, the default host must include all protocols that will be supported by any virtual host.

This patch adds an additional return status of APR_EMISMATCH to the init_vhost function so that the ssl_callback_ServerNameIndication callback registered with OpenSSL can return fatal alert SSL_AD_PROTOCOL_VERSION. This is intended to produce the same response to the ClientHello as having an SSLProtocol specified that does not include the version in question. Because the SNI callback is called during the processing of the ClientHello and before a response is produced, it seems to do exactly that.

If you suddenly see messages of the following format:

Rejecting version [version] for servername [hostname]

Then you should double-check your SSLProtocol for your default host.

Solution 2:

You can have different SSL protocols for each Vhost if they are listening on a different IP.

Example with a specific host allowing TLSv1 and all others only allowing TLSv1.1 and TLSv1.2 - and one allowing TLSv1.2 only:

<VirtualHost *:443>
  SSLEngine On
  SSLProtocol All -SSLv2 -SSLv3 -TLSv1
  ServerName test.mysite.com
  # bunch of other stuff omitted
</VirtualHost>

<VirtualHost 10.0.0.2:443>
  SSLEngine On
  SSLProtocol All -SSLv2 -SSLv3
  ServerName test2.mysite.com
</VirtualHost>

<VirtualHost 10.0.0.3:443>
  SSLEngine On
  SSLProtocol TLSv1.2
  ServerName test2.mysite.com
</VirtualHost>