Apache HTTP 服务器版本 2.4
基于 IP 的虚拟主机 使用连接的 IP 地址来确定要服务的正确虚拟主机。因此,您需要为每个主机使用单独的 IP 地址。
在基于名称的虚拟主机中,服务器依赖于客户端在 HTTP 标头中报告主机名。使用此技术,许多不同的主机可以共享同一个 IP 地址。
基于名称的虚拟主机通常更简单,因为您只需要配置 DNS 服务器将每个主机名映射到正确的 IP 地址,然后配置 Apache HTTP 服务器以识别不同的主机名。基于名称的虚拟主机还可以减轻对稀缺 IP 地址的需求。因此,除非您使用明确要求基于 IP 的主机的设备,否则您应该使用基于名称的虚拟主机。基于客户端支持的基于 IP 的虚拟主机的历史原因不再适用于通用 Web 服务器。
基于名称的虚拟主机建立在基于 IP 的虚拟主机选择算法的基础上,这意味着对正确服务器名的搜索仅发生在具有最佳基于 IP 的地址的虚拟主机之间。
重要的是要认识到,基于名称的虚拟主机解析的第一步是基于 IP 的解析。基于名称的虚拟主机解析仅在将候选范围缩小到最佳基于 IP 的匹配后,才会选择最合适的基于名称的虚拟主机。在所有 VirtualHost 指令中使用通配符 (*) 作为 IP 地址会使这种基于 IP 的映射变得无关紧要。
当请求到达时,服务器将根据请求使用的 IP 地址和端口,找到最佳(最具体)匹配的 <VirtualHost>
参数。如果有多个虚拟主机包含此最佳匹配地址和端口组合,Apache 将进一步将 ServerName
和 ServerAlias
指令与请求中存在的服务器名称进行比较。
如果您从任何基于名称的虚拟主机中省略 ServerName
指令,服务器将默认使用从系统主机名派生的完全限定域名 (FQDN)。此隐式设置的服务器名称会导致非直观的虚拟主机匹配,因此不建议使用。
如果在包含最具体匹配的 IP 地址和端口组合的虚拟主机集中未找到匹配的 ServerName 或 ServerAlias,则将使用第一个列出的虚拟主机,该虚拟主机与该组合匹配。
相关模块 | 相关指令 |
---|---|
第一步是为要服务的每个不同的主机创建一个 <VirtualHost>
块。在每个 <VirtualHost>
块中,您至少需要一个 ServerName
指令来指定要服务的哪个主机,以及一个 DocumentRoot
指令来显示该主机的内容在文件系统中的位置。
任何与现有 <VirtualHost>
不匹配的请求都将由全局服务器配置处理,无论主机名或 ServerName 如何。
当您将基于名称的虚拟主机添加到现有服务器时,如果虚拟主机参数与预先存在的 IP 和端口组合匹配,则请求现在将由显式虚拟主机处理。在这种情况下,通常明智的做法是创建一个 默认虚拟主机,其 ServerName
与基本服务器的匹配。然后,可以将同一接口和端口上的新域(但需要单独的配置)添加为后续(非默认)虚拟主机。
最好始终在每个基于名称的虚拟主机中显式列出 ServerName
。
如果 VirtualHost
未指定 ServerName
,则将从基本服务器配置继承服务器名称。如果全局未指定服务器名称,则会在启动时通过第一个监听地址的反向 DNS 解析来检测一个服务器名称。无论哪种情况,此继承的服务器名称都会影响基于名称的虚拟主机解析,因此最好始终在每个基于名称的虚拟主机中显式列出 ServerName
。
例如,假设您正在服务域 www.example.com
,并且您希望添加虚拟主机 other.example.com
,它指向同一个 IP 地址。然后,您只需将以下内容添加到 httpd.conf
中
<VirtualHost *:80> # This first-listed virtual host is also the default for *:80 ServerName www.example.com ServerAlias example.com DocumentRoot "/www/domain" </VirtualHost> <VirtualHost *:80> ServerName other.example.com DocumentRoot "/www/otherdomain" </VirtualHost>
您也可以在 <VirtualHost>
指令中使用显式 IP 地址来代替 *
。例如,您可能希望这样做是为了在一个 IP 地址上运行一些基于名称的虚拟主机,而在另一个地址上运行基于 IP 的虚拟主机或另一组基于名称的虚拟主机。
许多服务器希望可以通过多个名称访问。这可以通过 ServerAlias
指令实现,该指令放置在 <VirtualHost>
部分中。例如,在上面的第一个 <VirtualHost>
块中,ServerAlias
指令指示列出的名称是人们可以用来查看同一网站的其他名称
ServerAlias example.com *.example.com
然后,对 example.com
域中所有主机的请求将由 www.example.com
虚拟主机服务。通配符 *
和 ?
可用于匹配名称。当然,您不能只是编造名称并将它们放在 ServerName
或 ServerAlias
中。您必须首先正确配置 DNS 服务器,以将这些名称映射到与您的服务器关联的 IP 地址。
对于最佳匹配的 <virtualhost>
集,基于名称的虚拟主机按其在配置中出现的顺序进行处理。将使用第一个匹配的 ServerName
或 ServerAlias
,通配符(以及 ServerName 与 ServerAlias)没有不同的优先级。
VirtualHost
指令中的完整名称列表将被视为(非通配符)ServerAlias
。
最后,您可以通过将其他指令放置在 <VirtualHost>
容器中来微调虚拟主机的配置。大多数指令可以放置在这些容器中,然后只会更改相关虚拟主机的配置。要了解特定指令是否允许,请检查指令的 上下文。在主服务器上下文(在任何 <VirtualHost>
容器之外)中设置的配置指令仅在未被虚拟主机设置覆盖时使用。