我正在尝试设置两个子域,分别为和a
。我使用了两个 .conf 文件,它们看起来几乎相同,但 ServerName 和 ProxyPass 进行了相应的更改:b
domain.com
<VirtualHost *:80>
ServerName a.domain.com #This was added as a try for a fix.
Redirect permanent / https://a.domain.com/
</VirtualHost>
<VirtualHost *:443>
ServerName a.domain.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/a
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
#SSL stuff
#Proxies
ProxyPass / https://a.domain.com:8444/
ProxyPassReverse / https://a.domain.com:8444/
ProxyPass /a/ https://a.domain.com:8444/
ProxyPassReverse /a/ https://a.domain.com:8444/
ProxyPass /b/ https://b.domain.com:8445/
ProxyPassReverse /b/ https://b.domain.com:8445/
</VirtualHost>
这是在我的测试环境中完成的,复制了与当前生产环境中类似的内容。在 /etc/hosts 中,我将a.domain.com
和添加b.domain.com
到 127.0.0.1。生产环境中的 DNS 记录了 whata.domain.com
和b.domain.com
are,它们是相同的 IP(我也在我测试的机器上做了这个)。
另请注意,我没有提供来自其根目录的任何内容。我添加了该内容以尝试修复标题中所述的问题。不过,两个目录中都有一个简单的 html。
实际问题是什么?
简单来说,尝试 时,结果与预期一致,a.domain.com
是来自 的 Web 应用程序。尝试 时,结果也是,而不是。和都已启用,如果我禁用,那么我就会正确获取。如果我还尝试,则重定向会解析回。localhost:8444
b.domain.com
localhost:8444
localhost:8445
a.conf
b.conf
a.conf
localhost:8445
a.domain.com/b
a.domain.com
我读过几个问题和教程,其中大部分要么像我的配置一样工作,要么添加了 NameVirtualHost,我知道我的 Apache 版本不需要它。我还在端口 80 中添加了一个 ServerName,因为我认为请求可能被匹配,b
因为a.conf
它们是同一个 IP,但这也没有用。
我这里漏掉了什么?是不是我似乎忽略了 mod_proxy 的某些东西?如果可能的话,我想为每个 webapp 保留一个文件。谢谢!
这是在 Ubuntu 18.04.2、Apache 2.4(mod_proxy 和 mod_ssl)、Tomcat 9 上。如果您需要任何其他信息,我会尽力提供。
更新
也尝试了这个配置。结果同样不理想。
<VirtualHost *:80>
ServerAlias a.domain.com
Redirect permanent / https://a.domain.com/
</VirtualHost>
<VirtualHost *:443>
ServerName a.domain.com
ServerAdmin webmaster@localhost
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
#SSL stuff
#Proxies
Redirect /b https://b.domain.com
<Location />
ProxyPass https://localhost:8444/
ProxyPassReverse https://localhost:8444/
</Location>
<Location /a>
ProxyPass https://localhost:8444/
ProxyPassReverse https://localhost:8444/
</Location>
</VirtualHost>
更新
好吧,我刚刚发现了一件非常烦人的事情。如果我用浏览器输入 或a.domain.com
,它们b.domain.com
都会解析为a.domain.com
。这就是我最初描述的问题。但如果尝试https://a.domain.com
或,两者都会解析到https://b.domain.com
正确的服务器:a
和。8444
b
8445
由于这非常令人沮丧,我会暂停一下,过一会儿再分析一下。
更新
经过长时间的休息后,我尝试了一些其他随机调整,只是为了看看会发生什么,但仍然没有按预期工作,除非使用 HTTPS。我安装了 Postman 来查看请求中发送的内容,发现在 Postman 中,HTTP 和 HTTPS 都可以正确使用主机。更好/更糟:当我使用 Postman 时,实际响应显示了a.domain.com
和的不同欢迎页面b.domain.com
,这意味着我的配置正常工作。
我认为所有这些麻烦可能只是缓存问题,但我选择的测试浏览器(Firefox dev ed)设置为不缓存内容。我将使用 curl 和其他浏览器检查响应。
答案1
罪魁祸首:缓存。
有一次,我的浏览器配置发生了变化(可能是更新?),我有超过 3GB 的缓存,包括我试图设置为子域的测试站点。哎呀。
清除缓存后,访问我的 URL 时会弹出有关我的自签名证书的警告,这很正常。接受风险后,我被重定向到正确的网站。这是通过使用b.domain.com
而不添加协议实现的。
为了确保它正常工作,我在其他 7 个浏览器中进行了测试(必须确保),并使用和不使用协议进行了 curl 测试,结果也符合预期。
最后配置没问题。我会在这里发布它以防你需要Apache 服务器通过子域代理到特定的 Tomcat 实例,使用 proxy_mod 也会立即从端口 80 重定向到端口 433。
<VirtualHost *:80>
ServerName a.domain.com
Redirect permanent / https://a.domain.com/
</VirtualHost>
<VirtualHost *:443>
ServerName a.domain.com
ServerAdmin [email protected]
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
#SSL stuff
SSLEngine On
SSLCertificateFile /etc/ssl/certs/DONT_USE_SELF_SIGNED.pem
SSLCertificateKeyFile /etc/ssl/private/CERTS_IN_PRODUCTIve.key
SSLVerifyClient none
#Proxies
ProxyRequests Off
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
#Redirections
Redirect /b https://b.domain.com
<Location />
ProxyPass https://localhost:8444/
ProxyPassReverse https://localhost:8444/
</Location>
<Location /a>
ProxyPass https://localhost:8444/
ProxyPassReverse https://localhost:8444/
</Location>
</VirtualHost>
请注意,SSL 代理和 SSL 的设置适用于自签名证书。如果您在生产环境中实施此设置,请阅读每个设置的相关文档。另请注意,这是的配置文件a.domain.com
。的等效项b.domain.com
完全相同,具有适当的 ServerName、ServerAlias、重定向、Location 和 localhost 端口。