![apache2 namevirtualhost 解析错误站点](https://linux22.com/image/507355/apache2%20namevirtualhost%20%E8%A7%A3%E6%9E%90%E9%94%99%E8%AF%AF%E7%AB%99%E7%82%B9.png)
运行 apache 2.2.6。我正在设置开发环境。
开发和生产将托管在同一台机器、同一个 IP 地址上。
诸如 prod.domain.com 和 dev.domain.com 之类的 DNS 条目指向同一个 IP。
*** 重要提示:要求开发和生产完全分开。每个都将运行自己的 apache 实例。每个都将使用自己的 apache 配置。
prod 和 dev 都将托管 http 和 https。
我已经完成设置并可以运行,但还没有达到我想要的限制程度。
例如生产配置:
NameVirtualHost *:80
NameVirtualHost *:443
<VirtualHost *:80 >
ServerName prod.domain.com
# ... etc
</VirtualHost>
<VirtualHost *:443 >
ServerName prod.domain.com
# ... etc
</VirtualHost>
开发站点的设置类似,使用端口 8080 和 4443。
每个站点都运行良好。但假设两个 Apache 都在运行,也可能错误地点击“跨站点”。因此,无意中点击 prod.domain.com:8080 会成功返回来自开发网站。如果这完全失败的话会好得多。
对我来说,这个问题有点难以解决,因为需要两个 apache 配置。如果全部放在一个配置中,单个进程就能完全了解所有内容。
因此,我尝试使用蛮力来解决这个问题,包括“其他”网站的虚拟主机,但有些方法会失败,例如无法访问 documentroot。但 apache 却莫名其妙地找到了“错误的”虚拟主机。
这是用于生产的完整配置,带有虚拟开发配置。
NameVirtualHost *:80
NameVirtualHost *:443
# ----------------------------------------------
# DUMMY HOSTS
<VirtualHost *:8080 >
ServerName dev.domain.com:8080
DocumentRoot /tmp/
<Directory /tmp/ >
Order deny,allow
Deny from all
</Directory>
</VirtualHost>
<VirtualHost *:4443 >
ServerName dev.domain.com:4443
DocumentRoot /tmp/
<Directory /tmp/ >
Order deny,allow
Deny from all
</Directory>
</VirtualHost>
# ----------------------------------------------
# REAL PRODUCTION HOSTS
<VirtualHost *:80 >
ServerName prod.domain.com:80
DocumentRoot /something/valid/
<Directory /something/valid/>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:443 >
ServerName prod.domain.com:443
DocumentRoot /something/valid/
<Directory /something/valid/>
Order allow,deny
Allow from all
</Directory>
# .... other valid ssl setup
</VirtualHost>
奇怪的是,使用此配置,prod.domain.com:80 命中成功。但 prod.domain.com:443 命中失败,因为它找到了 dev.domain.com:4443。我也尝试从 ServerName 中删除端口,但仍然不起作用。
抱歉,问题太长了。希望这些信息足够了。提前感谢大家的帮助。
答案1
我对您不得不使用相同的物理系统进行开发和生产表示同情。这听起来很尴尬。也使得使用较新的操作系统安装测试 Apache 变得困难。
开发服务器上使用的端口未通过 NameVirtualHost 指定,因此 Apache 不会使用虚拟主机来匹配它们。请尝试:
NameVirtualHost *:80
NameVirtualHost *:443
<VirtualHost *:80>
ServerName dev.domain.com
</VirtualHost>
<VirtualHost *:443>
ServerName dev.domain.com
</VirtualHost>
<VirtualHost *:80>
ServerName prod.domain.com
</VirtualHost>
<VirtualHost *:443>
ServerName prod.domain.com
</VirtualHost>
为了阻止意外的跨站点链接,您可以使用 mod_rewrite 来阻止来自其他服务器的访问。因此,生产服务器将拒绝来自开发服务器(主机名)的访问,反之亦然。文章一些细节mod_rewrite引擎。
否则,使用外部/现有防火墙阻止开发服务器的 IP 地址,或者使用网络过滤器/iptables ACL 规则,因此来自 Internet 的用户(或最终用户)无法访问它。
答案2
如何使用 ServerAlias 指令来确保某人不会删除前缀?
答案3
您还可以使用 mod_rewrite 解决原始问题。例如,您可以向“prod”虚拟主机配置添加以下内容:
RewriteEngine On
RewriteCond %{HTTP_HOST} !=prod.domain.com.
RewriteRule ^(.*)$ - [F,L]
将RewriteCond
匹配任何请求主机不是 prod.domain.name 的 HTTP 请求,并且 将RewriteRule
使用 403 HTTP 错误代码(Forbidden)回答请求。F
代表“forbidden”。这样,如果有人尝试访问 dev.domain.com 并且 apache 仍然想为“prod”网站提供服务,则该请求将使用 403 错误代码回答。