我想在同一个 IP 上托管三个 HTTPS 站点,每个站点都有自己的证书和服务器名称。我已经使用 HTTP 多次完成此操作,似乎 HTTPS 配置应该不会有太大不同。我有最新的 CentOS7 + Apache。服务器位于执行 NAT 的防火墙后面,但我认为这应该不是问题。每个虚拟主机配置都在单独的文件中。
我遇到的问题是,无论我做什么,无论我在浏览器中输入哪个地址,我都会获得第一个服务器的内容。
第一个 HTTPS 服务器是一个普通的 HTTPS,之前就已经存在了。现在我添加了两个,比如这个:
<VirtualHost *:443>
ServerAdmin [email protected]
ServerName www.domain1.com
CustomLog logs/ssl_www.domain1.com-combined_log combined
SSLEngine on
SSLCertificateKeyFile conf/ssl.key/www.domain1.com.key
SSLCertificateFile conf/ssl.crt/www.domain1.com.crt
SSLProxyEngine on
SSLProxyCheckPeerCN off
SSLProxyCheckPeerExpire off
SSLProxyCheckPeerName off
ProxyRequests off
ProxyPreserveHost on
ProxyPass / https://10.10.10.10:443/
ProxyPassReverse / https://10.10.10.10:443/
</VirtualHost>
它们尚未加入 DNS,因此我在客户端中为其公共 IP 添加了 /etc/hosts 条目,并尝试查看它们是否正常工作。Apache 在重新启动时报告以下行:
[Wed Jan 10 08:40:56.048248 2018] [ssl:warn] [pid 20391] AH02292: Init: Name-based SSL virtual hosts only work for clients with TLS server name indication support (RFC 4366)
这意味着 Apache 支持 SNI。其他虚拟主机的日志为空,而第一个处理所有请求的虚拟主机在日志中报告了正确的主机名:
x.x.x.x - - [10/Jan/2018:08:49:37 +0000] "GET / HTTP/1.1" 200 3294 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
x.x.x.x - - [10/Jan/2018:08:49:37 +0000] "GET /styles.css HTTP/1.1" 200 4335 "https://www.domain1.com/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
日志第二行中的主机名显示引荐来源 (www.domain1.com) 实际上是未显示的网站。因此显然浏览器请求了正确的主机名。在这种情况下证书也是错误的,因为 apache 始终只使用第一个虚拟主机。
我还尝试设置一个普通的第二个 HTTPS 站点(没有反向代理),结果是一样的。我没有更多的想法,不知道该尝试什么。我不想安装像 HAProxy 或 sniproxy 这样的附加软件。我相信 Apache 应该能够处理它。
根据要求,我在这里添加了其他虚拟主机。第一台服务器:
<VirtualHost 10.163.3.1:443>
ServerAdmin [email protected]
DocumentRoot /home/domain0/ftp/www
ScriptAlias /cgi-bin/ /home/domain0/cgi-bin/
ServerName www.domain0.com
CustomLog logs/ssl_www.domain0.com-combined_log combined
CookieTracking on
AddType application/x-httpd-php .php
DirectoryIndex index.php index.html index.htm
SSLEngine on
SSLCertificateKeyFile /etc/letsencrypt/live/www.domain0.com/privkey.pem
SSLCertificateFile /etc/letsencrypt/live/www.domain0.com/cert.pem
<Directory /home/domain0/ftp/www>
AllowOverride None
Require all granted
Options None
</Directory>
<DirectoryMatch "\.svn">
Require all denied
</DirectoryMatch>
# Mercurial (Hg) version control system, using WSGI
WSGIScriptAlias /hg "/srv/hg/cgi-bin/hgweb.wsgi"
<Location /hg>
AuthType Basic
AuthName "mercurial"
AuthUserFile /srv/hg/repos/.htpasswd
Require valid-user
</Location>
</VirtualHost>
第二个和第三个除了地址和名称外,其他完全相同:
<VirtualHost *:443>
ServerAdmin [email protected]
ServerName www.domain3.com
CustomLog logs/ssl_www.domain3.com-combined_log combined
SSLEngine on
SSLCertificateKeyFile conf/ssl.key/www.domain3.com.key
SSLCertificateFile conf/ssl.crt/www.domani3.com.crt
SSLProxyEngine on
SSLProxyCheckPeerCN off
SSLProxyCheckPeerExpire off
SSLProxyCheckPeerName off
ProxyRequests off
ProxyPreserveHost on
ProxyPass / https://11.11.11.11:443/
ProxyPassReverse / https://11.11.11.11:443/
</VirtualHost>
我更改了真实姓名和 IP 地址,因为我不想发布真实的姓名和 IP 地址。apachectl -S
什么都没有显示。我也试过了apachectl configtest
,它说Syntax OK
。我还想提一下,第二和第三个虚拟主机的日志文件是空的。
我将每个虚拟主机放在一个单独的文件中。这应该不会起任何作用吧?