我们有一个面向前端的 Linux 机器,运行着 Apache HTTP 服务器,它充当多个后端服务器的反向代理。这些服务器通过特定的域名和端口进行访问,并在 Apache 中设置为虚拟主机,如下所示:
Listen 8001
Listen 8002
<Virtualhost *:8001>
ServerName service.one.mycompany.com
ProxyPass / http://internal.one.mycompany.com:8001/
ProxyPassReverse / http://internal.one.mycompany.com:8001/
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F]
</Virtualhost>
<Virtualhost *:8002>
ServerName service.two.mycompany.com
ProxyPass / http://internal.two.mycompany.com:8002/
ProxyPassReverse / http://internal.two.mycompany.com:8002/
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F]
</Virtualhost>
代理服务器只有一个 IP 地址,两个域都指向它。通过 service.one 访问 internal.one 可以正常工作,通过 service.two 访问 internal.two 也可以正常工作。
现在的问题是,Apache 在访问虚拟主机时不考虑请求域。我的意思是两个域都适用于两个端口:对 service.one:8002 的请求代理到 internal.two:8002,对 service.two:8001 的请求代理到 internal.one:8001,理想情况下这两个请求都应该被拒绝。
我可以通过创建更多明确拒绝这些请求的虚拟主机来解决这个问题:
NameVirtualHost *:8001
NameVirtualHost *:8002
<Virtualhost *:8001>
ServerName service.two.mycompany.com
Redirect permanent / http://errorpage.mycompany.com/
</Virtualhost>
<Virtualhost *:8002>
ServerName service.one.mycompany.com
Redirect permanent / http://errorpage.mycompany.com/
</Virtualhost>
但这不是理想的解决方案,因为我们计划向代理添加更多服务,并且每个新端口都需要在所有其他域上明确拒绝,并且每个新域都需要在其未使用的所有端口上明确拒绝。随着我们添加更多服务,虚拟主机的数量很快就会失控。
那么,我的问题是是否有更好的方法?我们是否可以明确地将特定端口绑定到虚拟主机中的特定域,以便只处理该域端口组合,而不处理所有其他组合?
我尝试过的事情:
- 添加 NameVirtualHost *:8001 等,无需额外的虚拟主机。
- 将 ProxyRequests 设置为打开或关闭,将 ProxyPreserveHost 设置为打开或关闭
- 将服务器名称或 IP 地址添加到虚拟主机标头,例如 <VirtualHost service.one.mycompany.com:8001>
- 在虚拟主机指令内使用 <proxy> 指令。
- 进行大量的谷歌搜索。
代理服务器运行的是 CentOS 6.2 64 位、Apache HTTPD 服务器 2.2.15。如前所述,代理服务器只有一个 IP 地址,我们使用的所有域都指向它。
答案1
Apache 总是希望为给定端口设置默认后备,这就是您现在看到的。因此,即使服务器名称不匹配,这也是它最后/唯一的选择。这就是为什么有 000-default catch-all 作为标准的原因。
您可以mod_rewrite
在 vhost 配置中使用它来明确阻止/重定向任何不匹配的域。
RewriteCond %{SERVER_NAME} !my.domain.com
RewriteRule (.*)$ http://my.domain.com$1 [L,R=301]