Apache HTTP Server 版本 2.4
本文档旨在解释 Apache HTTP Server 在决定为请求提供服务的虚拟主机时所执行的操作。
大多数用户应该阅读有关 基于名称的虚拟主机与基于 IP 的虚拟主机 的内容,以决定要使用哪种类型,然后阅读更多有关 基于名称的 或 基于 IP 的 虚拟主机的知识,最后查看 一些示例。
如果您想了解所有细节,可以返回此页面。
存在一个主服务器,它包含出现在<VirtualHost>
部分之外的所有定义。
存在虚拟服务器,称为vhost,它们由 <VirtualHost>
部分定义。
每个VirtualHost
指令包含一个或多个地址和可选端口。
在虚拟主机定义中可以使用主机名代替 IP 地址,但它们在启动时解析,如果任何名称解析失败,则会忽略这些虚拟主机定义。因此,不建议这样做。
地址可以指定为*
,如果没有任何其他 vhost 具有接收请求的显式地址,则此地址将匹配请求。
VirtualHost
指令中出现的地址可以包含可选端口。如果未指定端口,则将其视为通配符端口,也可以使用*
显式表示。通配符端口匹配任何端口。
(VirtualHost
指令中指定的端口号不会影响 Apache 监听的端口号,它们只控制哪个VirtualHost
将被选中来处理请求。使用 Listen
指令来控制服务器监听的地址和端口。)
总的来说,整个地址集(包括来自 DNS 查找的多个结果)称为 vhost 的地址集。
每当在多个虚拟主机中列出 IP 地址和端口组合的最具体匹配项时,Apache 会根据客户端提供的 HTTP Host
标头自动进行区分。
ServerName
指令可以出现在服务器定义中的任何位置。但是,每次出现都会覆盖之前的出现(在该服务器内)。如果没有指定ServerName
,服务器会尝试从服务器的 IP 地址推断它。
配置文件中给定 IP:port 对的第一个基于名称的 vhost 很重要,因为它用于接收该地址和端口的所有请求,对于这些请求,该 IP:port 对的任何其他 vhost 都没有匹配的 ServerName 或 ServerAlias。它还用于所有 SSL 连接,如果服务器不支持 服务器名称指示。
VirtualHost
指令中的完整名称列表与(非通配符)ServerAlias
相同(但不会被任何ServerAlias
语句覆盖)。
对于每个 vhost,都会设置各种默认值。特别是
ServerAdmin
、Timeout
、KeepAliveTimeout
、KeepAlive
、MaxKeepAliveRequests
、ReceiveBufferSize
或 SendBufferSize
指令,则相应的 value 会从主服务器继承。(也就是说,从主服务器中该 value 的最终设置继承。)本质上,主服务器被视为“默认值”或“基础”,用于构建每个 vhost。但是,这些主服务器定义在配置文件中的位置基本上无关紧要——在最终合并发生时,主服务器的整个配置已经被解析。因此,即使主服务器定义出现在 vhost 定义之后,它也可能会影响 vhost 定义。
如果主服务器此时没有ServerName
,则使用运行 httpd
的机器的主机名。我们将主服务器地址集称为通过对主服务器的ServerName
进行 DNS 查找返回的那些 IP 地址。
对于任何未定义的ServerName
字段,基于名称的 vhost 默认使用VirtualHost
语句中定义 vhost 的第一个地址。
任何包含魔法_default_
通配符的 vhost 都将使用与主服务器相同的ServerName
。
服务器通过以下方式确定为请求使用哪个 vhost
当连接首次在某个地址和端口上接收时,服务器会查找所有具有相同 IP 地址和端口的VirtualHost
定义。
如果没有地址和端口的精确匹配项,则会考虑通配符 (*
) 匹配项。
如果未找到匹配项,则由主服务器提供服务。
如果存在 IP 地址的VirtualHost
定义,则下一步是决定是否需要处理基于 IP 的 vhost 还是基于名称的 vhost。
如果只有一个VirtualHost
指令列出了被确定为最佳匹配的 IP 地址和端口组合,则不会执行任何进一步的操作,并且从匹配的 vhost 提供服务。
如果有多个VirtualHost
指令列出了被确定为最佳匹配的 IP 地址和端口组合,则以下步骤中的“列表”是指匹配的 vhost 列表,按照它们在配置文件中的顺序排列。
如果连接使用 SSL,服务器支持 服务器名称指示,并且 SSL 客户端握手包含带有请求主机名的 TLS 扩展,则该主机名将在下面使用,就像Host:
标头在非 SSL 连接中使用一样。否则,第一个地址匹配的基于名称的 vhost 将用于 SSL 连接。这很重要,因为 vhost 决定服务器将使用哪个证书进行连接。
如果请求包含Host:
标头字段,则会在列表中搜索第一个具有匹配ServerName
或ServerAlias
的 vhost,并且从该 vhost 提供服务。Host:
标头字段可以包含端口号,但 Apache 始终忽略它,并根据客户端发送请求的实际端口进行匹配。
配置文件中第一个具有指定 IP 地址的 vhost 具有最高优先级,并捕获对未知服务器名称的任何请求,或没有Host:
标头字段的请求(例如 HTTP/1.0 请求)。
上面描述的IP 查找仅对特定 TCP/IP 会话执行一次,而名称查找在 KeepAlive/持久连接期间对每个请求执行。换句话说,客户端可以在单个持久连接期间从不同的基于名称的 vhost 请求页面。
如果来自请求的 URI 是绝对 URI,并且其主机名和端口与主服务器或一个配置的虚拟主机以及与客户端发送请求的地址和端口匹配,则会剥离方案/主机名/端口前缀,并且剩余的相对 URI 将由相应的主服务器或虚拟主机提供服务。如果它不匹配,则 URI 保持不变,并且请求被视为代理请求。
ServerName
和ServerAlias
检查。Host:
标头字段中的任何端口在匹配过程中都不会使用。Apache 始终使用客户端发送请求的实际端口。*
vhost)不匹配时,才会使用主服务器来提供服务。换句话说,主服务器只捕获对未指定地址/端口组合的请求(除非存在与该端口匹配的_default_
vhost)。VirtualHost
指令中指定 DNS 名称,因为它会强制您的服务器依赖 DNS 启动。此外,如果您不控制列出的所有域的 DNS,它会构成安全威胁。有关此主题和接下来的两个主题,请参阅 更多信息。ServerName
。否则,需要对每个 vhost 进行 DNS 查找。