您只能为配置文件中的第一个VirtualHost设置SSLProtocol。所有后续的VirtualHost条目都将从第一个条目继承该设置,并且由于OpenSSL错误而无视其自身的设置。
有一个针对mod_ssl的错误报告,但如错误报告中所述,该问题需要在OpenSSL中解决(证书是继承的,而不是协议的)。
必须为每个VirtualHost分别设置密码套件,否则,您将得到默认列表,其中包括很多不安全的密码。另外,请注意,不支持服务器名称指示(SNI)的较旧客户端将始终使用默认主机(除非使用阻止SSLStrictSNIVHostCheck
),这可能会使测试感到困惑。
简而言之,您应该能够为每个虚拟主机指定自定义密码套件和证书,但是在修复该错误之前,不要指望每个虚拟主机具有自定义协议的正确行为。
我在Apache 2.4和带有OpenSSL 1.0.1k的modssl上遇到了这个问题,我希望Apache 2.2也会遇到同样的问题。
更新(2016年10月): OpenSSL错误被标记为在2016年10月13日解决。但是,这是大量关闭未解决问题的一部分,尽管提供了“部分修复”,但从未完全解决问题。
更新(2018年4月):重新提交的OpenSSL错误现在具有可用的补丁程序(截至2018年4月9日)。该补丁将改变配置有多个SNI虚拟主机的Apache实例的行为:
拒绝不符合vhost SSLProtocol的连接
它是使用2.4.27开发和测试的,并已在该版本中投入生产。该补丁已针对2.4.33进行了修改,并经过了轻微测试。
这将根据为基于SNI匹配的虚拟主机配置的SSLProtocol检查连接的版本。因为连接最初是使用为端口的默认主机配置的SSLProtocol进行的,所以默认主机必须包括任何虚拟主机将支持的所有协议。
此修补程序将APR_EMISMATCH的其他返回状态添加到init_vhost函数,以便向OpenSSL注册的ssl_callback_ServerNameIndication回调可以返回致命警报SSL_AD_PROTOCOL_VERSION。这旨在对ClientHello产生与指定的SSLProtocol(不包含所讨论版本)相同的响应。因为SNI回调是在ClientHello的处理过程中以及在生成响应之前调用的,所以它确实可以做到这一点。
如果您突然看到以下格式的消息:
Rejecting version [version] for servername [hostname]
然后,应仔细检查您SSLProtocol
的默认主机。
SSLStrictSNIVHostCheck
非常受赞赏。但是,还应该从引用的文档中注意到,如果在任何其他虚拟主机中将其设置为on,则不允许SNI意识不到的客户端访问此特定虚拟主机。