<-
Apache > HTTP 服务器 > 文档 > 版本 2.5 > Rewrite

使用 mod_rewrite 实现动态批量虚拟主机

可用语言:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

本文档是 mod_rewrite 参考文档的补充。它描述了如何使用 mod_rewrite 来创建动态配置的虚拟主机。

mod_rewrite 通常不是配置虚拟主机的最佳方式。 你应该首先考虑其他替代方案, 然后再求助于 mod_rewrite。另请参阅"如何避免使用 mod_rewrite"文档。

参见

top

任意主机名的虚拟主机

描述:

我们希望为域中解析的每个主机名自动创建虚拟主机, 而无需创建新的 VirtualHost 配置段。

在本配置方案中,我们假设对每个用户使用主机名 SITE.example.com, 并从 /home/SITE/www 提供其内容。 但是,我们希望 www.example.com 不包含在此映射中。

解决方案:
RewriteEngine on

RewriteMap    lowercase int:tolower

RewriteCond   %{HTTP_HOST} !^www\.
RewriteCond   ${lowercase:%{HTTP_HOST}}   ^([^.]+)\.example\.com$
RewriteRule   ^(.*)    /home/%1/www$1
讨论
你需要注意 DNS 解析 - Apache 不处理名称解析。你需要为每个主机名创建 CNAME 记录, 或者创建 DNS 通配符记录。创建 DNS 记录超出了本文档的范围。

内部 tolower RewriteMap 指令用于确保所使用的主机名全部为小写, 以避免目录结构中的歧义。

RewriteCond 中使用的括号会被捕获到反向引用 %1%2 等中, 而在 RewriteRule 中使用的括号会被捕获到反向引用 $1$2 等中。

第一个 RewriteCond 检查主机名是否以 www. 开头, 如果是,则跳过重写。

与本文档中讨论的许多技术一样,mod_rewrite 确实不是完成此任务的最佳方式。你应该考虑使用 mod_vhost_alias,因为它能更优雅地处理静态文件之外的任何内容, 包括动态内容和 Alias 解析。

top

使用 mod_rewrite 的动态虚拟主机

httpd.conf 摘录与第一个示例 实现相同的功能。前半部分与上面对应的部分非常相似, 只是为了向后兼容和使 mod_rewrite 部分正常工作而做了一些更改; 后半部分配置 mod_rewrite 来完成实际工作。

因为 mod_rewrite 在其他 URI 转换模块 (例如 mod_alias)之前运行, 必须告知 mod_rewrite 显式忽略那些本应由这些模块处理的 URL。 而且,由于这些规则会绕过任何 ScriptAlias 指令, 我们必须让 mod_rewrite 显式执行这些映射。

# 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]
top

使用独立的虚拟主机配置文件

此方案使用更高级的 mod_rewrite 功能, 从独立的配置文件中计算从虚拟主机到文档根目录的转换。 这提供了更大的灵活性,但需要更复杂的配置。

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]

可用语言:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn