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