Spec-Zone.ru › Apache HTTP Server

Динамически настраиваемый массовый виртуальный хостинг

В этом документе описано, как эффективно обслуживать произвольное количество виртуальных хостов с помощью 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> механизмом, который будет формировать их динамически. У этого подхода есть несколько преимуществ:

  1. Ваш файл конфигурации становится меньше, поэтому Apache запускается быстрее и использует меньше памяти. Возможно, что важнее, небольшую конфигурацию проще поддерживать, и в ней меньше места для ошибок.
  2. Чтобы добавить виртуальные хосты, достаточно создать соответствующие каталоги в файловой системе и записи в DNS — перенастраивать или перезапускать Apache не нужно.

Главный недостаток состоит в том, что для каждого виртуального хоста нельзя задать отдельный файл журнала. Однако при большом количестве виртуальных хостов это может быть не лучшей идеей в любом случае из-за необходимого количества файловых дескрипторов. Лучше записывать журнал в канал или FIFO и настроить процесс на другом конце так, чтобы он распределял записи по отдельным файлам для каждого виртуального хоста. Пример такого процесса можно найти в утилите split-logfile.

Общие сведения

Виртуальный хост определяется двумя параметрами: его IP-адресом и содержимым заголовка Host: в HTTP-запросе. Используемый здесь метод динамического массового виртуального хостинга основан на автоматической вставке этой информации в путь к файлу, который используется для обработки запроса. Проще всего это сделать с помощью mod_vhost_alias в Apache httpd. Также можно использовать mod_rewrite.

Оба этих модуля по умолчанию отключены. Чтобы использовать этот метод, необходимо включить один из них при настройке и сборке Apache httpd.

Чтобы динамический виртуальный хост работал как обычный, из запроса нужно определить несколько параметров. Самый важный из них — имя сервера, которое сервер использует, например, для создания ссылок на собственные ресурсы. Оно задаётся директивой ServerName и доступно CGI-программам через переменную окружения SERVER_NAME. Фактическое значение во время работы определяется настройкой UseCanonicalName. При использовании UseCanonicalName Off имя сервера берётся из содержимого заголовка Host: запроса. При использовании UseCanonicalName DNS оно определяется посредством обратного DNS-поиска IP-адреса виртуального хоста. Первый вариант используется для динамического виртуального хостинга на основе имён, второй — для хостинга на основе IP-адресов. Если httpd не может определить имя сервера, потому что заголовок Host: отсутствует или поиск в DNS завершается неудачей, вместо него используется значение, заданное директивой ServerName.

Ещё один параметр, который нужно определить, — корневой каталог документов (задаётся директивой DocumentRoot и доступен CGI-сценариям через переменную окружения DOCUMENT_ROOT). В обычной конфигурации основной модуль использует его для преобразования URI в имена файлов. Но если сервер настроен на динамический виртуальный хостинг, эту задачу должен выполнять другой модуль (mod_vhost_alias или mod_rewrite), использующий иной способ преобразования. Ни один из этих модулей не отвечает за установку переменной окружения DOCUMENT_ROOT, поэтому CGI-программы и документы SSI, которые её используют, получат вводящее в заблуждение значение.

Динамические виртуальные хосты с mod_vhost_alias

Этот фрагмент из 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.

Упрощённые динамические виртуальные хосты

Это адаптация описанной выше системы для сервера веб-хостинга интернет-провайдера. С помощью %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 <VirtualHost>, чтобы управлять областью действия различных конфигураций виртуального хостинга. Например, можно выделить один 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>

Примечание

Если первый блок VirtualHost не содержит директиву ServerName, вместо неё будет использоваться результат обратного DNS-поиска для соответствующего IP-адреса. Если это не то имя сервера, которое вы хотите использовать, можно добавить фиктивную запись (например, ServerName none.example.com), чтобы обойти такое поведение.

Более эффективный виртуальный хостинг на основе IP-адресов

Изменения конфигурации, предлагаемые для преобразования первого примера в конфигурацию виртуального хостинга на основе 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

Массовый виртуальный хостинг можно также реализовать с помощью mod_rewrite: используя простые директивы RewriteRule или более сложные методы, например хранение определений виртуальных хостов во внешнем источнике и доступ к ним через RewriteMap. Эти методы описаны в документации по rewrite.

Массовые виртуальные хосты с mod_macro

Ещё один способ динамически создавать виртуальные хосты — использовать mod_macro. С его помощью можно создать шаблон виртуального хоста и применять его для нескольких имён хостов. Пример приведён в разделе Использование документации модуля.

© 2018 The Apache Software Foundation
Licensed under the Apache License, Version 2.0.
https://httpd.apache.org/docs/2.4/en/vhosts/mass.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API