Do you need to set/include ssl settings for each individual virtual host?
No. When all sites on a server should always have the same modern security requirements and the same TLS settings then setting them once in the "server config" context should be sufficient.
Otherwise: Yes. When (in the future) an customisation needs to be made in the TLS settings for one of the virtual hosts that override global default values from the server config context; that override could become unintentionally the new default for all other virtual hosts as well.
TL;DR
It depends a bit on the Apache and openssl versions what behaviour you get to see, but for (some) mod_ssl SSL/TLS directives the behaviour is not completely intuitive.
Most Apache mod_ssl settings and directives can indeed be set in the "server config" context and "virtual host" context, some are even valid in "directory" and ".htaccess" contexts.
The manual lists for each directive where it can be set.
Directive values set in the server config context will be used unless they're (also) set in a "virtual host" context.
The counter intuitive part is that for some settings, when they get a value assigned in "the base virtual host", that value overrides server config for the other virtual hosts. In other words: for some some settings defined in a virtual host, the scope (effect) was/is not restricted to that particular virtual host.
It's only "explained" in the manual section for the SSLProtocol
directive.
(I'm not sure if I remember correctly and this might also be (or have been) applicable for other directives such as the SSLCipherSuite
) :
SSLProtocol for name-based virtual hosts
Before OpenSSL 1.1.1, even though the Server Name Indication (SNI) allowed to determine the targeted virtual host early in the TLS handshake, it was not possible to switch the TLS protocol version of the connection at this point, and thus the SSLProtocol
negotiated was always based off the one of the base virtual host (first virtual host declared on the listening IP:port of the connection).
Beginning with Apache HTTP server version 2.4.42, when built/linked against OpenSSL 1.1.1 or later, and when the SNI is provided by the client in the TLS handshake, the SSLProtocol
of each (name-based) virtual host can and will be honored.
For compatibility with previous versions, if no SSLProtocol
is configured in a name-based virtual host, the one from the base virtual host still applies, unless SSLProtocol
is configured globally in which case the global value applies (this latter exception is more sensible than compatible, though).
For example
A main server config configuration with three virtual host blocks:
#/etc/httpd/conf/httpd.conf
...
LoadModule ssl_module modules/mod_ssl.so
SSLProtocol All -SSLv2 -SSLv3 -TLSv1
Listen 443
<VirtualHost *:443>
ServerName insecure.example.com
SSLEngine on
SSLCertificateFile "/path/to/insecure.example.com.cert"
SSLCertificateKeyFile "/path/to/insecure.example.com.key"
SSLProtocol All
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
SSLEngine on
SSLCertificateFile "/path/to/www.example.com.cert"
SSLCertificateKeyFile "/path/to/www.example.com.key"
</VirtualHost>
<VirtualHost *:443>
ServerName secure.example.com
SSLEngine on
SSLCertificateFile "/path/to/www.example.com.cert"
SSLCertificateKeyFile "/path/to/www.example.com.key"
SSLProtocol TLSv1.2
</VirtualHost>
On my old RHEL 7 with openssl 1.0.2 and apache 2.4.6 ; the legacy apache / openssl versions the manual warns about:
That has the effect that for www.example.com
; where the virtual host block has no explicit SSLProtocol defined: the value All
from default host insecure.example.com
gets used and not the value main server context SSLProtocol All -SSLv2 -SSLv3 -TLSv1
.
Additionally for secure.example.com
the explicitly defined SSLProtocol TLSv1.2
also gets ignored and the value All
from default host insecure.example.com
gets used instead.
Copy that configuration to a modern host with a recent Apache httpd version and openssl that now also supports TLS version 1.3:
That has the effect that for www.example.com
; where the virtual host block has no explicit SSLProtocol defined: the value from main server context SSLProtocol All -SSLv2 -SSLv3 -TLSv1
gets used. In other words after expanding All
: SSLProtocol TLSv1.3 TLSv1.2
Additionally for secure.example.com
the explicitly defined SSLProtocol TLSv1.2
also gets used, but the configuration is not the most secure because it doesn't support the newer TLSv1.3