動態虛擬主機與 mod_rewrite

2019-10-16 22:02:10

本文描述了如何使用mod_rewrite建立動態組態的虛擬主機。

任意主機名的虛擬主機

我們希望為在域名解析的每個主機名自動建立虛擬主機,而無需建立新的VirtualHost部分。

在本文中,假設我們將為每個使用者使用主機名www.SITE.example.com,並從/ home/SITE/www中提供其內容。

解決辦法:

RewriteEngine on

RewriteMap    lowercase int:tolower

RewriteCond   "${lowercase:%{HTTP_HOST}}"   "^www\.([^.]+)\.example\.com$"
RewriteRule   "^(.*)" "/home/%1/www$1"

內部tolower RewriteMap指令用於確保所使用的主機名都是小寫的,因此必須建立的目錄結構中沒有歧義。

RewriteCond中使用的括號被捕獲到後向參照%1%2等,而RewriteRule中使用的括號被捕獲到後向參照$1$2等。

與本文件中討論的許多技術一樣,mod_rewrite實際上並不是完成此任務的最佳方法。相反,應該考慮使用mod_vhost_alias,因為除了提供靜態檔案(例如任何動態內容和Alias解析)之外,它還可以更加優雅地處理。

動態虛擬主機使用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]

使用單獨的虛擬主機組態檔案

這種安排使用更高階的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]