本文档介绍了如何通过Apache HTTP Server有效地为任意数量的虚拟主机提供服务。甲
单独的文档讨论了使用
mod_rewrite
以创建动态质量虚拟主机。
如果您httpd.conf
包含许多
<VirtualHost>
基本相同的部分,则此处介绍的技术很有用
,例如:
<VirtualHost 111.22.33.44> ServerName customer-1.example.com DocumentRoot "/www/hosts/customer-1.example.com/docs" ScriptAlias "/cgi-bin/" "/www/hosts/customer-1.example.com/cgi-bin" </VirtualHost> <VirtualHost 111.22.33.44> ServerName customer-2.example.com DocumentRoot "/www/hosts/customer-2.example.com/docs" ScriptAlias "/cgi-bin/" "/www/hosts/customer-2.example.com/cgi-bin" </VirtualHost> <VirtualHost 111.22.33.44> ServerName customer-N.example.com DocumentRoot "/www/hosts/customer-N.example.com/docs" ScriptAlias "/cgi-bin/" "/www/hosts/customer-N.example.com/cgi-bin" </VirtualHost>
我们希望<VirtualHost>
用一种动态解决这些问题的机制来替换这些多个
模块。这具有许多优点:
主要缺点是每个虚拟主机不能有不同的日志文件。但是,如果您有许多虚拟主机,则由于所需的文件描述符数量众多,因此无论如何都是一个坏主意。最好登录到管道或fifo,并在另一端安排该过程,以将每个虚拟主机的日志文件拆分为一个。可以在split-logfile 实用程序中找到这种过程的一个示例。
虚拟主机由两部分信息定义:其IP地址和Host:
HTTP请求中标头的内容。此处使用的动态批量虚拟主机技术基于自动将此信息插入用于满足请求的文件的路径名中。通过mod_vhost_alias
与Apache httpd一起使用,可以很容易地做到这一点。或者,
可以使用mod_rewrite。
默认情况下,这两个模块都是禁用的。如果要使用此技术,则在配置和构建Apache httpd时必须启用其中之一。
为了使动态虚拟主机看起来像普通主机,需要从请求中确定几件事。最重要的是服务器名称,服务器使用它来生成自我引用的URL等。它使用ServerName
伪指令配置
,并且可以通过SERVER_NAME
环境变量供CGI使用。运行时使用的实际值由UseCanonicalName
设置控制。使用UseCanonicalName Off
,服务器名称取自Host:
请求中标头的内容。用UseCanonicalName DNS
,它取自虚拟主机IP地址的反向DNS查找。前一种设置用于基于名称的动态虚拟主机,而后一种设置用于基于IP的主机。如果httpd因为没有Host:
头而无法计算出服务器名称,或者DNS查找失败,那么将ServerName
使用配置为的值
。
要确定的另一件事是文档根目录(DocumentRoot
通过DOCUMENT_ROOT
环境变量使用CGI脚本进行配置并可供其使用
)。在正常配置中,核心模块在将URI映射到文件名时会使用此方法,但是当服务器配置为进行动态虚拟托管时,该工作必须由另一个模块(mod_vhost_alias
或
mod_rewrite
)接管,而另一个模块具有不同的处理方式做映射。这两个模块都不负责设置DOCUMENT_ROOT
环境变量,因此,如果任何CGI或SSI文档都使用它,它们将获得误导性的价值。
此摘录使用来httpd.conf
实现上述“ 动机”部分中概述的虚拟主机安排mod_vhost_alias
。
# get the server name from the Host: header UseCanonicalName Off # this log format can be split per-virtual-host based on the first field # using the split-logfile utility. LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon CustomLog "logs/access_log" vcommon # include the server name in the filenames used to satisfy requests VirtualDocumentRoot "/www/hosts/%0/docs" VirtualScriptAlias "/www/hosts/%0/cgi-bin"
该结构通过只是把变成基于IP的虚拟主机解决方案UseCanonicalName
Off
进入UseCanonicalName DNS
。然后,从虚拟主机的IP地址派生到文件名中的服务器名称。该变量%0
引用请求的服务器名,如
Host:
标题中所示。
有关mod_vhost_alias
更多用法示例,请参阅文档。
这是针对ISP的Web托管服务器量身定制的上述系统的调整。使用%2
,我们可以选择要在文件名中使用的服务器名称的子字符串,以便在www.user.example.com
中找到
的文档
/home/user/www
。它使用一个cgi-bin
目录,而不是每个虚拟主机使用一个目录。
UseCanonicalName Off LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon CustomLog "logs/access_log" vcommon # include part of the server name in the filenames VirtualDocumentRoot "/home/%2/www" # single cgi-bin directory ScriptAlias "/cgi-bin/" "/www/std-cgi/"
文档中有更复杂的VirtualDocumentRoot
设置
示例
mod_vhost_alias
。
通过更复杂的设置,您可以使用httpd的normal
<VirtualHost>
指令来控制各种虚拟主机配置的范围。例如,通过以下设置,您可以为普通客户的主页提供一个IP地址,为商业客户提供一个IP地址。可以将其与常规<VirtualHost>
配置部分组合
,如下所示。
UseCanonicalName Off LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon <Directory "/www/commercial"> Options FollowSymLinks AllowOverride All </Directory> <Directory "/www/homepages"> Options FollowSymLinks AllowOverride None </Directory> <VirtualHost 111.22.33.44> ServerName www.commercial.example.com CustomLog "logs/access_log.commercial" vcommon VirtualDocumentRoot "/www/commercial/%0/docs" VirtualScriptAlias "/www/commercial/%0/cgi-bin" </VirtualHost> <VirtualHost 111.22.33.45> ServerName www.homepages.example.com CustomLog "logs/access_log.homepages" vcommon VirtualDocumentRoot "/www/homepages/%0/docs" ScriptAlias "/cgi-bin/" "/www/std-cgi/" </VirtualHost>
如果第一个虚拟主机块并没有包括
ServerName
指令,相关IP的反向DNS将被使用。如果这不是您希望使用的服务器名称,ServerName
none.example.com
则可以添加虚假条目(例如)来解决此问题。
建议进行配置更改,以将第一个示例转换为基于IP的虚拟主机设置,从而导致设置效率低下。每个请求都需要一个新的DNS查找。为了避免这种开销,可以将文件系统安排为与IP地址相对应,而不是与主机名相对应,从而消除了DNS查找的需要。日志记录也必须进行调整以适合此系统。
# get the server name from the reverse DNS of the IP address UseCanonicalName DNS # include the IP address in the logs so they may be split LogFormat "%A %h %l %u %t \"%r\" %s %b" vcommon CustomLog "logs/access_log" vcommon # include the IP address in the filenames VirtualDocumentRootIP "/www/hosts/%0/docs" VirtualScriptAliasIP "/www/hosts/%0/cgi-bin"
也可以mod_rewrite
使用简单的RewriteRule
指令或使用更复杂的技术(例如,在外部存储vhost定义并通过访问它们)来完成大规模虚拟主机
RewriteMap
。这些技术在重写文档中进行了讨论。
动态生成的虚拟主机的另一个选项是
mod_macro
,您可以使用它创建一个虚拟主机模板,并为多个主机名调用它。模块文档的“ 用法”部分提供了一个示例。