我在 Debian 上运行 Apache 2.4,为一些 SSL 网站提供服务。我的域名和证书包含我的真实姓名,因此我不希望任何随机用户输入我的 IP 地址来获取证书和我的名字。
我的方法是使用 modsecurity 在端口 443 上创建一个默认虚拟主机,以断开所有连接,因此只有知道域名才能获得证书。使用 SNI 应该可以实现 - Apache 会确定正确的虚拟主机前TLS 握手,对吧?
但是,它似乎并没有按预期工作。如果我启用默认主机,每个 TLS 连接似乎都会被断开,并且我会在浏览器中收到 SSL_ERROR_RX_RECORD_TOO_LONG 错误。
这是我的配置:
<VirtualHost *:443>
ServerName defaultserverssl
DocumentRoot /var/www/html
SecRuleEngine On
SecAction id:1,phase:1,nolog,drop
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName www1.example.com
DocumentRoot /my/document/root
SSLCertificateFile /path/to/myfullchain.pem
SSLCertificateKeyFile /path/to/myprivkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName www2.example.com
DocumentRoot /my/document/root
SSLCertificateFile /path/to/myfullchain.pem
SSLCertificateKeyFile /path/to/myprivkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
我已经尝试了SSLStrictSNIVHostCheck
强制使用 SNI 的选项,无论是在服务器级别还是在单个虚拟主机中,都没有不同的结果。
看起来 SNI 不起作用,或者我对 SNI 的工作方式的理解是错误的,并且我的方法不可行?
答案1
我找到了解决我的问题的方法。
据我所知,使用 SNI 时,客户端会在扩展的 TLS 客户端 hello 中发送请求的服务器名称 - 因此无法避免初始 TLS 握手(或者至少我没有找到断开连接的方法刚过接收客户端问候)。
作为一种解决方法,我创建了一个自签名证书(不包含个人信息),并将其与默认主机一起使用。握手后,连接似乎可以正常工作。
<VirtualHost *:443>
ServerName defaultserverssl
DocumentRoot /var/www/html
SSLEngine On
SSLCertificateFile /path/to/self-signed/default.crt
SSLCertificateKeyFile /path/to/self-signed/default.key
SecRuleEngine On
SecAction id:1,phase:1,nolog,drop
</VirtualHost>