On this page
使用 mod_rewrite 的动态批量虚拟主机
本文档是对mod_rewrite reference documentation的补充。它描述了如何使用mod_rewrite创建动态配置的虚拟主机。
Warning
mod_rewrite 不是配置虚拟主机的最佳方法。在使用 mod_rewrite 之前,您应该首先考虑alternatives。另请参见“ 如何避免 mod_rewrite文档。
虚拟主机,用于任意主机名
Description:
- 我们希望为在我们域中解析的每个主机名自动创建一个虚拟主机,而不必创建新的 VirtualHost 部分。
在本食谱中,我们假设我们将为每个用户使用主机名www.SITE.example.com
,并从/home/SITE/www
中提供其内容。
- Solution:
RewriteEngine on
RewriteMap lowercase int:tolower
RewriteCond "${lowercase:%{HTTP_HOST}}" "^www\.([^.]+)\.example\.com$"
RewriteRule "^(.*)" "/home/%1/www$1"
Discussion
您将需要注意 DNS 解析-Apache 不处理名称解析。您需要为每个主机名创建 CNAME 记录,或 DNS 通配符记录。创建 DNS 记录超出了本文档的范围。
内部的tolower
RewriteMap 指令用于确保所使用的主机名全部为小写,以便在目录结构中不存在必须创建的歧义。
RewriteCond中使用的括号被捕获到反向引用%1
,%2
等中,而RewriteRule中使用的括号被捕获到反向引用$1
,$2
等中。
与本文档中讨论的许多技术一样,mod_rewrite 实际上并不是完成此任务的最佳方法。相反,您应该考虑使用mod_vhost_alias,因为它可以更优雅地处理除提供静态文件之外的任何内容,例如任何动态内容和别名解析。
使用 mod_rewrite 的动态虚拟主机
从httpd.conf
提取的内容与第一个例子相同。前半部分与上面的相应部分非常相似,除了一些变化是向后兼容和使mod_rewrite
部分正常工作所需的;后半部分配置mod_rewrite
进行实际工作。
由于mod_rewrite
在其他 URI 转换模块(例如mod_alias
)之前运行,因此必须告知mod_rewrite
显式忽略那些模块会处理的所有 URL。并且,由于这些规则否则会绕过任何ScriptAlias
指令,因此我们必须让mod_rewrite
明确制定这些 Map。
# get the server name from the Host: header
UseCanonicalName Off
# splittable logs
LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
CustomLog "logs/access_log" vcommon
<Directory "/www/hosts">
# ExecCGI is needed here because we can't force
# CGI execution in the way that ScriptAlias does
Options FollowSymLinks ExecCGI
</Directory>
RewriteEngine On
# a ServerName derived from a Host: header may be any case at all
RewriteMap lowercase int:tolower
## deal with normal documents first:
# allow Alias "/icons/" to work - repeat for other aliases
RewriteCond "%{REQUEST_URI}" "!^/icons/"
# allow CGIs to work
RewriteCond "%{REQUEST_URI}" "!^/cgi-bin/"
# do the magic
RewriteRule "^/(.*)$" "/www/hosts/${lowercase:%{SERVER_NAME}}/docs/$1"
## and now deal with CGIs - we have to force a handler
RewriteCond "%{REQUEST_URI}" "^/cgi-bin/"
RewriteRule "^/(.*)$" "/www/hosts/${lowercase:%{SERVER_NAME}}/cgi-bin/$1" [H=cgi-script]
使用单独的虚拟主机配置文件
这种安排使用更高级的mod_rewrite功能,从单独的配置文件计算出从虚拟主机到文档根目录的转换。这提供了更大的灵 Active,但是需要更复杂的配置。
vhost.map
文件应如下所示:
customer-1.example.com /www/customers/1 customer-2.example.com /www/customers/2 # ... customer-N.example.com /www/customers/N
httpd.conf
应包含以下内容:
RewriteEngine on
RewriteMap lowercase int:tolower
# define the map file
RewriteMap vhost "txt:/www/conf/vhost.map"
# deal with aliases as above
RewriteCond "%{REQUEST_URI}" "!^/icons/"
RewriteCond "%{REQUEST_URI}" "!^/cgi-bin/"
RewriteCond "${lowercase:%{SERVER_NAME}}" "^(.+)$"
# this does the file-based remap
RewriteCond "${vhost:%1}" "^(/.*)$"
RewriteRule "^/(.*)$" "%1/docs/$1"
RewriteCond "%{REQUEST_URI}" "^/cgi-bin/"
RewriteCond "${lowercase:%{SERVER_NAME}}" "^(.+)$"
RewriteCond "${vhost:%1}" "^(/.*)$"
RewriteRule "^/cgi-bin/(.*)$" "%1/cgi-bin/$1" [H=cgi-script]