基于名称的虚拟主机支持

本文档介绍了何时以及如何使用基于名称的虚拟主机。

基于名称的虚拟主机与基于 IP 的虚拟主机

基于 IP 的虚拟主机使用连接的 IP 地址来确定要服务的正确虚拟主机。因此,每个主机都需要有一个单独的 IP 地址。

使用基于名称的虚拟主机时,服务器依靠 Client 端将主机名报告为 HTTP Headers 的一部分。使用此技术,许多不同的主机可以共享相同的 IP 地址。

基于名称的虚拟主机通常更简单,因为您只需要配置 DNS 服务器以将每个主机名 Map 到正确的 IP 地址,然后配置 Apache HTTP Server 即可识别不同的主机名。基于名称的虚拟主机还可以缓解对稀缺 IP 地址的需求。因此,除非您使用的设备明确要求基于 IP 的托管,否则应使用基于名称的虚拟托管。基于 Client 端支持的基于 IP 的虚拟托管的历史原因不再适用于通用 Web 服务器。

基于名称的虚拟主机构建在基于 IP 的虚拟主机选择算法的基础上,这意味着仅在具有最佳基于 IP 的地址的虚拟主机之间才搜索正确的服务器名称。

服务器如何选择适当的基于名称的虚拟主机

必须认识到,基于名称的虚拟主机解析的第一步是基于 IP 的解析。基于名称的虚拟主机解析仅在将候选范围缩小到基于 IP 的最佳匹配之后才选择最合适的基于名称的虚拟主机。在所有 VirtualHost 指令中对 IP 地址使用通配符(*),使基于 IP 的 Map 无关紧要。

当请求到达时,服务器将根据请求使用的 IP 地址和端口找到最匹配(最具体)的<VirtualHost>参数。如果有一个以上包含此最佳匹配地址和端口组合的虚拟主机,Apache 将进一步将ServerNameServerAlias指令与请求中存在的服务器名称进行比较。

如果从任何基于名称的虚拟主机中省略ServerName指令,则服务器将默认为从系统主机名派生的完全限定的域名(FQDN)。隐式设置的服务器名称可能导致虚拟主机匹配违反直觉,因此不建议使用。

IP 和端口组合的默认基于名称的虚拟主机

如果在包含最特定的匹配 IP 地址和端口组合的虚拟主机集合中未找到匹配的 ServerName 或 ServerAlias,则“将使用将与之匹配的第一个列出的虚拟主机”。

使用基于名称的虚拟主机

Related ModulesRelated Directives
coreDocumentRoot
ServerAlias
ServerName
<VirtualHost>

第一步是为您要服务的每个不同的主机创建一个<VirtualHost>块。在每个<VirtualHost>块内,您至少需要一个ServerName指令来指定要服务的主机,以及一个DocumentRoot指令来显示该主机的内容在文件系统中的位置。

Main host goes away

与主机名或 ServerName 无关的所有与现有<VirtualHost>不匹配的请求均由全局服务器配置处理。

当您将基于名称的虚拟主机添加到现有服务器时,并且虚拟主机参数与预先存在的 IP 和端口组合匹配时,请求现在将由显式虚拟主机处理。在这种情况下,通常明智的做法是创建一个与基础服务器的ServerName相匹配的默认虚拟主机。然后可以将同一接口和端口上的新域,但需要单独配置,添加为后续(非默认)虚拟主机。

ServerName inheritance

最好始终在每个基于名称的虚拟主机中明确列出ServerName

如果VirtualHost未指定ServerName,则服务器名称将从基本服务器配置继承。如果未全局指定服务器名称,则在启动时会通过反向解析第一个侦听地址来检测到服务器名称。无论哪种情况,此继承的服务器名称都会影响基于名称的虚拟主机解析,因此最好始终在每个基于名称的虚拟主机中明确列出ServerName

例如,假设您正在为域www.example.com提供服务,并且希望添加指向相同 IP 地址的虚拟主机other.example.com。然后,您只需将以下内容添加到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 的或另一组基于名称的虚拟主机。

许多服务器希望通过多个名称进行访问。放在<VirtualHost>部分中的ServerAlias指令可以做到这一点。例如,在上面的第一个<VirtualHost>块中,ServerAlias指令指示列出的名称是其他名称,人们可以用来查看同一网站:

ServerAlias example.com *.example.com

www.example.com虚拟主机将满足example.com域中所有主机的请求。通配符*?可用于匹配名称。当然,您不能只是组成名称并将它们放在ServerNameServerAlias中。首先,必须正确配置 DNS 服务器,以将这些名称 Map 到与服务器关联的 IP 地址。

最佳匹配的<virtualhost>的基于名称的虚拟主机将按照它们在配置中出现的 Sequences 进行处理。使用第一个匹配的ServerNameServerAlias,通配符的优先级没有不同(服务器名与 ServerAlias 也不相同)。

VirtualHost指令中名称的完整列表被视为(非通配符)ServerAlias

最后,您可以通过将其他指令放在<VirtualHost>容器中来微调虚拟主机的配置。大多数指令可以放置在这些容器中,然后仅更改相关虚拟主机的配置。要确定是否允许使用特定指令,请检查该指令的Context。在主服务器上下文中设置的配置指令(在任何<VirtualHost>容器之外)仅在不被虚拟主机设置覆盖的情况下使用。