本文档说明了如何使用基于域名的虚拟主机。
参见
基于域名的虚拟主机VS基于IP的虚拟主机
基于IP的虚拟主机使用链接的IP地址来决定相应的虚拟主机。 这样,你就需要为每个主机设定一个独立的IP地址。 而基于域名的的虚拟主机是根据客户端提交的HTTP头中的关于主机名的部分决定的。 使用这种技术,很多虚拟主机可以享用同一个IP地址。
基于域名的虚拟主机相对比较简单, 因为你只需要配置你的DNS服务器将每个主机名映射到正确的IP地址, 然后配置Apache HTTP服务器,令其辨识不同的主机名就可以了。 基于域名的服务器也可以缓解IP地址不足的问题。 所以,如果没有特殊原因使你必须用一个基于IP的虚拟主机, 您最好还是使用基于域名的虚拟主机。 下列情况下,你可能会想要使用基于IP的虚拟主机:
- 一些古董级的客户端与基于域名的虚拟主机不兼容。 为了与基于域名的虚拟主机兼容,客户端必须发送HTTP Host头。HTTP/1.1规范中对此做了要求。 而所有现在流行的支持HTTP/1.0的浏览器都以附加的方式实现了这个要求。 如果你又想支持这些老浏览器,又想使用基于域名的虚拟主机。 我们提供了一个技术方案,你可以在本文末尾看到它。
- 由于SSL协议先天决定了基于域名的虚拟主机无法成为SSL安全服务器。
- 一些操作系统和网络设备实现的带宽管理技术无法在主机共享一个IP的情况下区别它们。
使用基于域名的虚拟主机
相关模块 | 相关指令 |
---|---|
为了使用基于域名的虚拟主机,你必须指定服务器IP地址(和可能的端口)来使主机接受请求。 您可以用NameVirtualHost
指令来进行配置。 如果服务器上所有的IP地址都会用到, 你可以用*
作为NameVirtualHost
的参数。 请注意,在NameVirtualHost
指令中指明了IP地址并不会使服务器侦听那个IP地址。 请参阅设置Apache使用的地址和端口一章获取详情。 另外,这里设定的IP地址必须对应服务器上的一个网络接口。
下一步就是为你建立的每个主机设定<VirtualHost>
配置块。 <VirtualHost>
的参数与NameVirtualHost
指令的参数是一样的 (比如说,一个IP地址,或是*
代表的所有地址)。 在每个<VirtualHost>
定义块中,至少都会有一个ServerName
指令来指定伺服哪个主机和一个DocumentRoot
指令来说明这个主机的内容存在于文件系统的什么地方。
取消中心主机(Main host)
如果你想在现有的web服务器上增加虚拟主机, 你必须也为现存的主机建造一个<VirtualHost>定义块。 这个虚拟主机中ServerName
和
DocumentRoot
所包含的内容应该与全局的
ServerName
和
DocumentRoot
保持一致。 还要把这个虚拟主机放在配置文件的最前面,来让它扮演默认主机的角色。
比如说,假设你正在为域名www.domain.tld
提供服务, 而你又想在同一个IP地址上加一个名叫www.otherdomain.tld
的虚拟主机, 你只需在httpd.conf
中加入以下内容:
NameVirtualHost *
<VirtualHost *>
ServerName www.domain.tld
ServerAlias domain.tld *.domain.tld
DocumentRoot /www/domain
</VirtualHost>
<VirtualHost *>
ServerName www.otherdomain.tld
DocumentRoot /www/otherdomain
</VirtualHost>
当然,你可以用一个固定的IP地址来代替NameVirtualHost
和 <VirtualHost>
指令中的*号,以达到一些特定的目的。 比如说,你可能会希望在一个IP地址上运行一个基于域名的虚拟主机, 而在另外一个地址上运行一个基于IP的或是另外一套基于域名的虚拟主机。
很多服务器希望自己能通过不只一个域名被访问。 我们可以把ServerAlias
指令放入<VirtualHost> 小节中来解决这个问题。比如说在上面的第一个<VirtualHost>配置块中ServerAlias
指令中列出的名字就是用户可以用来访问同一个web站点的其它名字:
ServerAlias domain.tld *.domain.tld
这样,所有对域domain.tld
的访问请求都将为虚拟主机 www.domain.tld
所处理。通配符标记 * 和 ? 可以用于域名的匹配。 当然你不能仅仅搞个名字然后把它放到ServerName
或 ServerAlias
里就算完了。你必须先在你的DNS服务器上进行配置, 将这些名字和您服务器上的一个IP地址建立映射关系。
最后,你可以用把其他一些指令放入<VirtualHost>
配置段中的方法来更好的配置一个虚拟主机。 大部分指令都能放入这些配置段中而改变相应虚拟主机的配置。 如果您想了解一个特定的指令是否可以这样运用, 请参见指令的上下文。 主服务器上下文中的配置指令 (在所有<VirtualHost>
配置段之外的指令) 仅在它们没有被虚拟主机的配置覆盖时才起作用。
如此,当一个请求到达的时候,服务器会首先检查它是否使用了一个能和 NameVirtualHost
相匹配的IP地址。如果能够匹配, 它就会查找每个与这个IP地址相对应的<VirtualHost>
配置段, 并尝试找出一个ServerName
或ServerAlias
配置项与请求的主机名相同的。 如果找到了,它就会使用这个服务器的配置。 否则,将使用符合这个IP地址的第一个列出的虚拟主机。
综上所述,第一个列出的虚拟主机在这里充当了默认虚拟主机的角色。 当一个IP地址与NameVirtualHost
指令中的配置相符的时候, 主服务器中的DocumentRoot
将永远不会被用到。 所以,如果你想做一个处理不对应任何一个特定虚拟主机的请求的特殊配置的话, 你只要简单的把它的配置放到<VirtualHost>
配置段中, 并把它放到配置文件的最前面就可以了。
与旧版浏览器的兼容性
前面提过,有些浏览器无法对基于域名的虚拟主机发送必要的数据, 从而使其无法正常工作。这些浏览器将会收到由配置中符合那个IP 地址的第一个列出的虚拟主机发出的页面(基于域名的主虚拟主机)。
究竟什么算旧?
请注意,当我们说到旧的时候,我们并不是真的说它们很古老。 其实现实中您未必就能用上这些浏览器。 现在几乎所有的浏览器都会发送基于域名的虚拟主机所必须的Host
头了。
虽然有点麻烦。但您还是有可能会用到ServerPath
指令:
配置实例:
NameVirtualHost 111.22.33.44
<VirtualHost 111.22.33.44>
ServerName www.domain.tld
ServerPath /domain
DocumentRoot /web/domain
</VirtualHost>
以上这些说明了什么呢?它说明一个具有"/domain
"开头的任何URI 都会为www.domain.tld
这个虚拟主机所伺服。 这意味着这个页面可以由http://www.domain.tld/domain/
的形式为所有的浏览器所访问。 能够发送Host:
头的浏览器也能使用 http://www.domain.tld/
这种形式来访问它。
为了达到这样的目的。您先要在您的主虚拟主机的页面上放一个到 http://www.domain.tld/domain/
的链接。 然后,确保在虚拟主机的页面中使用的全是相对链接(诸如: "file.html
"或"../icons/image.gif
")或者是包含 /domain/
这个前缀(比如: "http://www.domain.tld/domain/misc/file.html
"或" /domain/misc/file.html
")。
完成这些可能需要一些尝试, 但遵照上述指导将会确保你的页面能够为所有的浏览器所正确显示,不论新旧。