Пункт 38. Динамические виртуальные хосты с mod_rewrite
Этот документ дополняет mod_rewrite
справочную документацию. В нем описывается, как можно использовать mod_rewrite
для создания динамически настраиваемых виртуальных хостов.
mod_rewrite — не лучший способ настройки виртуальных хостов. Вы должны сначала рассмотреть альтернативы, прежде чем прибегать к mod_rewrite. См. также статью «Как избежать mod_rewrite document.
Виртуальные хосты для произвольных имен хостов
- Описание:
-
Мы хотим автоматически создавать виртуальный хост для каждого имени хоста, которое разрешается в нашем домене, без необходимости создавать новые разделы VirtualHost.
В этом рецепте мы предполагаем, что будем использовать имя хоста
для каждого пользователя и предоставлять их контент из файлов
. www.SITE.example.com
/home/SITE/www
- Решение:
-
RewriteEngine включен
RewriteMap нижний регистр int:tolower
RewriteCond "${нижний регистр:%{ HTTP_HOST }}" "^www\. ([^.]+) \.example\.com$"
Правило перезаписи "^(.*)" "/home/ %1 /www$1"
- Обсуждение
-
Вам нужно будет позаботиться о разрешении DNS — Apache не обрабатывает разрешение имен. Вам потребуется либо создать записи CNAME для каждого имени хоста, либо запись с подстановочными знаками DNS. Создание записей DNS выходит за рамки этого документа.
Внутренняя tolower
директива RewriteMap используется для обеспечения того, чтобы все используемые имена хостов были в нижнем регистре, чтобы не было двусмысленности в структуре каталогов, которую необходимо создать.
Скобки, используемые в a, RewriteCond
фиксируются в обратных ссылках %1
, %2
и т. д., а скобки, используемые в, RewriteRule
фиксируются в обратных ссылках $1
, $2
и т. д.
Как и многие методы, обсуждаемые в этом документе, mod_rewrite действительно не лучший способ выполнить эту задачу. Вместо этого вам следует рассмотреть возможность использования mod_vhost_alias
вместо этого, так как он гораздо изящнее будет обрабатывать все, кроме обслуживания статических файлов, таких как любой динамический контент и разрешение псевдонимов.
Использование динамических виртуальных хостов mod_rewrite
Этот отрывок из apache2.conf
делает то же самое, что и первый пример. Первая половина очень похожа на соответствующую часть выше, за исключением некоторых изменений, необходимых для обратной совместимости и правильной работы
mod_rewrite
части; вторая половина настраивается mod_rewrite
для выполнения фактической работы.
Поскольку mod_rewrite
запускается перед другими модулями преобразования URI (например, mod_alias
), mod_rewrite
необходимо явно указать игнорировать любые URL-адреса, которые будут обрабатываться этими модулями. И, поскольку в противном случае эти правила обходили бы любые ScriptAlias
директивы, мы должны были
mod_rewrite
явно ввести эти отображения.
# получить имя сервера из заголовка Host:
UseCanonicalName Выкл.
# разделяемые журналы
LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
CustomLog "logs/access_log" vcommon
<Каталог "/www/hosts">
# Здесь необходим ExecCGI, потому что мы не можем принудительно
# Выполнение CGI так же, как это делает ScriptAlias
Опции FollowSymLinks ExecCGI
</Каталог>
RewriteEngine включен
# имя сервера, полученное из заголовка Host:, может быть любым
RewriteMap нижний регистр int:tolower
## сначала работаем с обычными документами:
# разрешить работу псевдониму "/icons/" - повторить для других псевдонимов
RewriteCond "%{REQUEST_URI}" "!^/icons/"
# разрешить работу CGI
RewriteCond "%{REQUEST_URI}" "!^/cgi-bin/"
# делать волшебство
RewriteRule "^/(.*)$" "/www/hosts/${нижний регистр:%{ИМЯ_СЕРВЕРА}}/docs/$1"
## а теперь разберемся с CGI - нам нужно форсировать обработчик
RewriteCond "%{REQUEST_URI}" "^/cgi-bin/"
RewriteRule "^/(.*)$" "/www/hosts/${нижний регистр:%{ИМЯ_СЕРВЕРА}}/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
Должно apache2.conf
содержать следующее:
RewriteEngine включен
RewriteMap нижний регистр int:tolower
# определяем файл карты
RewriteMap vhost "txt:/www/conf/vhost.map"
# работаем с псевдонимами, как указано выше
RewriteCond "%{REQUEST_URI}" "!^/icons/"
RewriteCond "%{REQUEST_URI}" "!^/cgi-bin/"
RewriteCond "${нижний регистр:%{ИМЯ_СЕРВЕРА}}" "^(.+)$"
# это делает переназначение на основе файлов
RewriteCond "${vhost:%1}" "^(/.*)$"
Правило перезаписи "^/(.*)$" "%1/docs/$1"
RewriteCond "%{REQUEST_URI}" "^/cgi-bin/"
RewriteCond "${нижний регистр:%{ИМЯ_СЕРВЕРА}}" "^(.+)$"
RewriteCond "${vhost:%1}" "^(/.*)$"
RewriteRule "^/cgi-bin/(.*)$" "%1/cgi-bin/$1" [H=cgi-script]