![Apache SNI namevhosts 始终路由到第一个 VirtualHost 条目](https://linux22.com/image/612128/Apache%20SNI%20namevhosts%20%E5%A7%8B%E7%BB%88%E8%B7%AF%E7%94%B1%E5%88%B0%E7%AC%AC%E4%B8%80%E4%B8%AA%20VirtualHost%20%E6%9D%A1%E7%9B%AE.png)
Apache 似乎将所有 https 请求路由到第一个,<VirtualHost *:443>
而不管 ServerName/ServerAlias 字段上的 SNI 匹配情况。
Apache 使用 SNI 构建
服务器版本:Apache/2.2.22 (Ubuntu)
服务器构建时间:2013 年 3 月 8 日 15:53:13
OpenSSL 1.0.1 2012 年 3 月 14 日
error.log 报告:
Init: Name-based SSL virtual hosts only work for clients with TLS server name indication support (RFC 4366)
这表明 SNI 正在按以下方式运行http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI(如何判断您的 Apache 构建是否支持 SNI?)
SSL_TLS_SNI
当使用 HTTPS 请求时似乎设置得当(已通过 验证phpinfo()
)
配置:
<IfModule mod_ssl.c>
# If you add NameVirtualHost *:443 here, you will also have to change
# the VirtualHost statement in /etc/apache2/sites-available/default-ssl
# to <VirtualHost *:443>
# Server Name Indication for SSL named virtual hosts is currently not
# supported by MSIE on Windows XP.
NameVirtualHost *:443
Listen 443
</IfModule>
#<VirtualHost *:443>
# <Location />
# Order allow,deny
# Deny from all
# </Location>
#</VirtualHost>
<VirtualHost *:443>
SSLEngine on
ServerAdmin webmaster@localhost
ServerName server.com
ServerAlias server.com
DocumentRoot /web/default
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLCertificateFile /path/server.com.crt
SSLCertificateKeyFile /path/server.com.key
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
ServerAdmin webmaster@localhost
ServerName alias.com
ServerAlias alias.com
DocumentRoot /web/default
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLCertificateFile /path/alias.com.crt
SSLCertificateKeyFile /path/alias.com.key
</VirtualHost>
两个都https://server.com和https://alias.com尝试从 server.com 提供证书(如果忽略证书警告,则提供内容)
类似的配置使用 HTTP:80 工作正常(唯一的变化是 SSLEngine 开启以及证书/密钥路径)
如果我取消注释第一个虚拟主机(限制对已定义的站点的 HTTPS 访问),那么我总是会收到 SSL 错误(即使它是一个已定义的站点)
谢谢
编辑:
附加标志
SSLProtocol all
SSLCipherSuite HIGH:MEDIUM
SSLStrictSNIVHostCheck on
SSLVerifyClient none
SSLProxyEngine off
SSLStrictSNIVHostCheck on
所以它应该只支持启用 SNI 的浏览器
apache2ctl -S
输出:
*:443 is a NameVirtualHost
default server server.com (/etc/apache2/sites-enabled/000-default:22)
port 443 namevhost server.com (/etc/apache2/sites-enabled/000-default:22)
port 443 namevhost alias.com (/etc/apache2/sites-enabled/000-default:39)
port 443 namevhost other.com (/etc/apache2/sites-enabled/other:22)
答案1
更新
因此,出于某种奇怪的原因,问题似乎已经自行解决。
也许是某种奇怪的缓存问题或其他问题(尽管我已经多次apache2ctl stop/start/restart
尝试sudo service apache2 stop/start/restart/reload
过,并在服务器上本地以及使用几台不同的机器进行过测试)。
如果可以作为参考,请随意删除或保留此问题。
感谢大家的帮助!
答案2
您的配置看起来没问题;指令 SSLEngine On 已被包含;根据日志消息,问题似乎来自客户端。
并非所有客户端都支持 SNI,但大多数都支持。这取决于 SSL 协商的方式,由系统(在 Win XP 上不起作用)或由浏览器(版本必须足够新)进行。查看支持 SNI 的浏览器列表。如果您必须确保所有客户端都能访问您的网站,则由于这些旧版本(浏览器或系统),您无法使用 SNI。您需要每个 ServerName 一个 IP,并对 ServerName alias.com 使用 VirtualHost $IP_alias:443,对 ServerName server.com 使用 VirtualHost $IP_server:443,而不是对两者使用 VirtualHost *:443。
答案3
第一个虚拟主机会出错,因为没有包含该SSLEngine on
指令,Apache 会发送不带 SSL 的 HTTP 响应。如果您想要这种功能,您必须为默认虚拟主机设置另一个站点(可能使用另一个证书,除非您重用现有域),即使您想要做的只是返回一个不错的错误。
也许检查一下证书是否真的不同?您的配置似乎正确。
另外,请检查是否有其他VirtualHost
部分在监听端口 443。Apache 将选择最匹配的部分,这意味着如果有任何内容更具体到连接所处的地址,则该条目将优先。不过,我认为这不是您的问题。
此外,有趣的是,从用户端您看到的是,如果客户端在大多数情况下不支持 SNI,会发生什么情况。
答案4
我们花了一上午的时间在 Oracle Linux 8(与 RHEL8 / Alma 8 / Rocky 8 / 等相同)上排除与此相关的问题。此行为可能也存在于其他发行版中。
如果您的服务器的主机名(即hostname
)与 <VirtualHost> 部分中的 ServerName 或 ServerAlias 相同,那么将呈现主服务器部分,而不是 VirtualHost 中指定的 DocumentRoot。 因此,<VirtualHost> 部分中的 SSL 和 DocumentRoot 设置将被忽略! 出于同样的原因,它还将从 /var/www/html/* 而不是 <VirtualHost> 定义加载文件。
修复方法是在顶部配置文件 /etc/httpd/conf/httpd.conf (或 /conf.d/foo 文件)中定义,以便 apache 认为的主机名与安装时操作系统定义的ServerName www.example.com
运行结果不同(即,网络脚本中的 /etc/hostname 或 HOSTNAME=)。hostname