Примеры VirtualHost
В этом документе рассматриваются часто задаваемые вопросы о настройке виртуальных хостов. Речь идёт о сценариях, в которых несколько веб-сайтов работают на одном сервере через виртуальные хосты на основе имён или виртуальные хосты на основе IP-адресов.
Работа нескольких веб-сайтов на основе имён с одним IP-адресом.
Вашему серверу соответствуют несколько имён узлов, которые разрешаются в один адрес, и вы хотите по-разному отвечать для www.example.com и www.example.org.
Примечание
Создание конфигураций виртуальных хостов на сервере Apache не приводит к автоматическому созданию записей DNS для этих имён узлов. Вы должны добавить эти имена в DNS, чтобы они разрешались в ваш IP-адрес, иначе никто другой не сможет увидеть ваш веб-сайт. Для локального тестирования можно добавить записи в файл hosts, но они будут работать только на компьютере с этими записями hosts.
# Ensure that Apache listens on port 80
Listen 80
<VirtualHost *:80>
DocumentRoot "/www/example1"
ServerName www.example.com
# Other directives here
</VirtualHost>
<VirtualHost *:80>
DocumentRoot "/www/example2"
ServerName www.example.org
# Other directives here
</VirtualHost> Звёздочки соответствуют всем адресам, поэтому основной сервер не обрабатывает запросы. Поскольку виртуальный хост с ServerName www.example.com первым указан в файле конфигурации, он имеет наивысший приоритет и может рассматриваться как сервер по умолчанию или основной. Это означает, что запрос, не соответствующий ни одной из указанных директив ServerName, будет обработан этим первым <VirtualHost>.
Приведённая выше конфигурация подходит почти для всех случаев размещения виртуальных хостов на основе имён. Фактически она не подойдёт только в том случае, если вам нужно предоставлять разное содержимое в зависимости от IP-адресов или портов.
Примечание
Вместо * можно указать конкретный IP-адрес системы. Такие виртуальные хосты будут использоваться только для HTTP-запросов, полученных через соединение с указанным IP-адресом.
Однако на системах, где IP-адрес нельзя предсказать, также удобно использовать * — например, если у вас динамический IP-адрес, предоставленный интернет-провайдером, и вы используете какой-либо вариант динамического DNS. Поскольку * соответствует любому IP-адресу, эта конфигурация будет работать без изменений при каждой смене IP-адреса.
Хосты на основе имён с несколькими IP-адресами.
Примечание
Любой из рассматриваемых здесь методов можно расширить на любое количество IP-адресов.
У сервера два IP-адреса. На одном (172.20.30.40) мы будем обслуживать «основной» сервер, server.example.com, а на другом (172.20.30.50) — два или более виртуальных хоста.
Listen 80
# This is the "main" server running on 172.20.30.40
ServerName server.example.com
DocumentRoot "/www/mainserver"
<VirtualHost 172.20.30.50>
DocumentRoot "/www/example1"
ServerName www.example.com
# Other directives here ...
</VirtualHost>
<VirtualHost 172.20.30.50>
DocumentRoot "/www/example2"
ServerName www.example.org
# Other directives here ...
</VirtualHost> Любой запрос к адресу, отличному от 172.20.30.50, будет обслуживаться основным сервером. Запрос к 172.20.30.50 с неизвестным именем узла или без заголовка Host: будет обслуживаться из www.example.com.
Предоставление одного и того же содержимого по разным IP-адресам (например, внутреннему и внешнему).
У сервера два IP-адреса (192.168.1.1 и 172.20.30.40). Компьютер находится между внутренней сетью (интрасетью) и внешней сетью (интернетом). За пределами сети имя server.example.com разрешается во внешний адрес (172.20.30.40), а внутри сети это же имя разрешается во внутренний адрес (192.168.1.1).
Сервер можно настроить так, чтобы он отвечал на внутренние и внешние запросы одинаковым содержимым, используя только одну секцию <VirtualHost>.
<VirtualHost 192.168.1.1 172.20.30.40>
DocumentRoot "/www/server1"
ServerName server.example.com
ServerAlias server
</VirtualHost> Теперь запросы из обеих сетей будут обслуживаться одним и тем же <VirtualHost>.
Примечание:
Во внутренней сети можно просто использовать имя server вместо полного доменного имени узла server.example.com.
Также обратите внимание: в приведённом выше примере список IP-адресов можно заменить на *, чтобы сервер одинаково отвечал на всех адресах.
Работа разных сайтов на разных портах.
Несколько доменов указывают на один IP-адрес, и вы также хотите обслуживать несколько портов. В примере ниже показано, что сопоставление имён происходит после определения наиболее подходящей комбинации IP-адреса и порта.
Listen 80
Listen 8080
<VirtualHost 172.20.30.40:80>
ServerName www.example.com
DocumentRoot "/www/domain-80"
</VirtualHost>
<VirtualHost 172.20.30.40:8080>
ServerName www.example.com
DocumentRoot "/www/domain-8080"
</VirtualHost>
<VirtualHost 172.20.30.40:80>
ServerName www.example.org
DocumentRoot "/www/otherdomain-80"
</VirtualHost>
<VirtualHost 172.20.30.40:8080>
ServerName www.example.org
DocumentRoot "/www/otherdomain-8080"
</VirtualHost> Виртуальный хостинг на основе IP-адресов
У сервера два IP-адреса (172.20.30.40 и 172.20.30.50), которые разрешаются соответственно в имена www.example.com и www.example.org.
Listen 80
<VirtualHost 172.20.30.40>
DocumentRoot "/www/example1"
ServerName www.example.com
</VirtualHost>
<VirtualHost 172.20.30.50>
DocumentRoot "/www/example2"
ServerName www.example.org
</VirtualHost> Запросы к адресам, не указанным ни в одной из директив <VirtualHost> (например, localhost), будут направлены на основной сервер, если он есть.
Смешанный виртуальный хостинг на основе портов и IP-адресов
У сервера два IP-адреса (172.20.30.40 и 172.20.30.50), которые разрешаются соответственно в имена www.example.com и www.example.org. В обоих случаях мы хотим запускать хосты на портах 80 и 8080.
Listen 172.20.30.40:80
Listen 172.20.30.40:8080
Listen 172.20.30.50:80
Listen 172.20.30.50:8080
<VirtualHost 172.20.30.40:80>
DocumentRoot "/www/example1-80"
ServerName www.example.com
</VirtualHost>
<VirtualHost 172.20.30.40:8080>
DocumentRoot "/www/example1-8080"
ServerName www.example.com
</VirtualHost>
<VirtualHost 172.20.30.50:80>
DocumentRoot "/www/example2-80"
ServerName www.example.org
</VirtualHost>
<VirtualHost 172.20.30.50:8080>
DocumentRoot "/www/example2-8080"
ServerName www.example.org
</VirtualHost> Смешанный виртуальный хостинг на основе имён и IP-адресов
Любой адрес, указанный в аргументе виртуального хоста и не встречающийся в других виртуальных хостах, представляет собой виртуальный хост, использующий только IP-адрес.
Listen 80
<VirtualHost 172.20.30.40>
DocumentRoot "/www/example1"
ServerName www.example.com
</VirtualHost>
<VirtualHost 172.20.30.40>
DocumentRoot "/www/example2"
ServerName www.example.org
</VirtualHost>
<VirtualHost 172.20.30.40>
DocumentRoot "/www/example3"
ServerName www.example.net
</VirtualHost>
# IP-based
<VirtualHost 172.20.30.50>
DocumentRoot "/www/example4"
ServerName www.example.edu
</VirtualHost>
<VirtualHost 172.20.30.60>
DocumentRoot "/www/example5"
ServerName www.example.gov
</VirtualHost> Совместное использование Virtual_host и mod_proxy
Следующий пример позволяет внешнему серверу перенаправлять запросы к виртуальному хосту на сервер, работающий на другом компьютере. В примере виртуальный хост с тем же именем настроен на компьютере по адресу 192.168.111.2. Директива ProxyPreserveHost On используется для передачи нужного имени узла на сервер, если мы перенаправляем несколько имён узлов на один компьютер.
<VirtualHost *:*>
ProxyPreserveHost On
ProxyPass "/" "http://192.168.111.2/"
ProxyPassReverse "/" "http://192.168.111.2/"
ServerName hostname.example.com
</VirtualHost> Использование виртуальных хостов _default_
Виртуальные хосты _default_ для всех портов
Перехват всех запросов к любому неуказанному IP-адресу и порту, то есть к комбинации адреса и порта, не используемой другими виртуальными хостами.
<VirtualHost _default_:*>
DocumentRoot "/www/default"
</VirtualHost> Использование такого виртуального хоста по умолчанию с подстановочным портом фактически предотвращает передачу любых запросов основному серверу.
Виртуальный хост по умолчанию никогда не обрабатывает запрос, отправленный на адрес и порт, используемые виртуальными хостами на основе имён. Если запрос содержит неизвестный заголовок Host: или не содержит его вовсе, он всегда обслуживается основным виртуальным хостом на основе имён (виртуальным хостом для этого адреса и порта, первым указанным в файле конфигурации).
Для перенаправления любого запроса на одну информационную страницу (или сценарий) можно использовать AliasMatch или RewriteRule.
Виртуальные хосты _default_ для разных портов
То же, что и в конфигурации 1, но сервер прослушивает несколько портов, и для порта 80 мы хотим использовать второй виртуальный хост _default_.
<VirtualHost _default_:80>
DocumentRoot "/www/default80"
# ...
</VirtualHost>
<VirtualHost _default_:*>
DocumentRoot "/www/default"
# ...
</VirtualHost> Виртуальный хост по умолчанию для порта 80 (который должен быть указан перед любым виртуальным хостом по умолчанию с подстановочным портом) перехватывает все запросы, отправленные на неуказанный IP-адрес. Основной сервер никогда не используется для обработки запросов.
Виртуальные хосты _default_ для одного порта
Нам нужен виртуальный хост по умолчанию для порта 80, но не нужны другие виртуальные хосты по умолчанию.
<VirtualHost _default_:80>
DocumentRoot "/www/default"
...
</VirtualHost> Запрос к неуказанному адресу на порту 80 обслуживается виртуальным хостом по умолчанию. Любой другой запрос к неуказанному адресу и порту обслуживается основным сервером.
Любое использование * в объявлении виртуального хоста имеет более высокий приоритет, чем _default_.
Перенос виртуального хоста на основе имён на виртуальный хост на основе IP-адреса
Виртуальному хосту на основе имён с именем узла www.example.org (из примера виртуального хостинга на основе имён, конфигурация 2) следует выделить собственный IP-адрес. Чтобы избежать проблем с серверами имён или прокси-серверами, которые сохранили в кэше старый IP-адрес виртуального хоста на основе имён, на время переноса мы хотим предоставить оба варианта.
Решение простое: достаточно добавить новый IP-адрес (172.20.30.50) в директиву VirtualHost.
Listen 80
ServerName www.example.com
DocumentRoot "/www/example1"
<VirtualHost 172.20.30.40 172.20.30.50>
DocumentRoot "/www/example2"
ServerName www.example.org
# ...
</VirtualHost>
<VirtualHost 172.20.30.40>
DocumentRoot "/www/example3"
ServerName www.example.net
ServerAlias *.example.net
# ...
</VirtualHost> Теперь доступ к виртуальному хосту возможен через новый адрес (как к виртуальному хосту на основе IP-адреса) и через старый адрес (как к виртуальному хосту на основе имени).
Использование директивы ServerPath
У нас есть сервер с двумя виртуальными хостами на основе имён. Чтобы выбрать правильный виртуальный хост, клиент должен отправить правильный заголовок Host:. Старые клиенты HTTP/1.0 не отправляют такой заголовок, и Apache не может определить, к какому виртуальному хосту хотел обратиться клиент (поэтому запрос обслуживается основным виртуальным хостом). Чтобы обеспечить максимальную обратную совместимость, мы создаём основной виртуальный хост, который возвращает одну страницу со ссылками, содержащими префикс URL виртуальных хостов на основе имён.
<VirtualHost 172.20.30.40>
# primary vhost
DocumentRoot "/www/subdomain"
RewriteEngine On
RewriteRule "." "/www/subdomain/index.html"
# ...
</VirtualHost>
<VirtualHost 172.20.30.40>
DocumentRoot "/www/subdomain/sub1"
ServerName www.sub1.domain.tld
ServerPath "/sub1/"
RewriteEngine On
RewriteRule "^(/sub1/.*)" "/www/subdomain$1"
# ...
</VirtualHost>
<VirtualHost 172.20.30.40>
DocumentRoot "/www/subdomain/sub2"
ServerName www.sub2.domain.tld
ServerPath "/sub2/"
RewriteEngine On
RewriteRule "^(/sub2/.*)" "/www/subdomain$1"
# ...
</VirtualHost> Из-за директивы ServerPath запрос к URL http://www.sub1.domain.tld/sub1/ всегда обслуживается виртуальным хостом sub1.
Запрос к URL http://www.sub1.domain.tld/ обслуживается виртуальным хостом sub1, только если клиент отправил правильный заголовок Host:. Если заголовок Host: не отправлен, клиент получает информационную страницу основного узла.
Обратите внимание на одну особенность: запрос к http://www.sub2.domain.tld/sub1/ также обслуживается виртуальным хостом sub1, даже если клиент не отправил заголовок Host:.
Директивы RewriteRule используются для того, чтобы клиент, отправивший правильный заголовок Host:, мог использовать оба варианта URL, то есть с префиксом URL или без него.
© 2018 The Apache Software Foundation
Licensed under the Apache License, Version 2.0.
https://httpd.apache.org/docs/2.4/en/vhosts/examples.html