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