Пункт 31. Примеры виртуального хоста
Этот документ пытается ответить на часто задаваемые вопросы о настройке виртуальных хостов. Эти сценарии включают в себя несколько веб-сайтов, работающих на одном сервере через виртуальные хосты на основе имени или IP.
Запуск нескольких веб-сайтов на основе имен на одном IP-адресе.
Ваш сервер имеет несколько имен хостов, которые разрешаются в один адрес, и вы хотите по-разному реагировать на www.example.com
и www.example.org
.
Примечание
Создание конфигураций виртуального хоста на вашем сервере Apache не приводит к волшебным образом созданию записей DNS для этих имен хостов. У вас
должны быть имена в DNS, разрешающие ваш IP-адрес, иначе никто другой не сможет увидеть ваш веб-сайт. Вы можете поместить записи в свой hosts
файл для локального тестирования, но это будет работать только с машины с этими
hosts
записями.
# Убедитесь, что Apache прослушивает порт 80
Слушай 80
<Виртуальный хост *:80>
DocumentRoot "/www/example1"
Имя сервера www.example.com
# Другие директивы здесь
</ виртуальный хост>
<Виртуальный хост *:80>
DocumentRoot "/www/example2"
Имя сервера www.example.org
# Другие директивы здесь
</ виртуальный хост>
Звездочки соответствуют всем адресам, поэтому главный сервер не обслуживает запросы. Из-за того, что виртуальный хост с
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
) мы будем обслуживать два или более виртуальных хоста.
Слушай 80
# Это "основной" сервер, работающий по адресу 172.20.30.40.
имя_сервера server.example.com
DocumentRoot "/www/mainserver"
<Виртуальный хост 172.20.30.50>
DocumentRoot "/www/example1"
Имя сервера www.example.com
# Другие директивы здесь...
</ виртуальный хост>
<Виртуальный хост 172.20.30.50>
DocumentRoot "/www/example2"
Имя сервера www.example.org
# Другие директивы здесь...
</ виртуальный хост>
Любой запрос на адрес, отличный от 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>
разделом.
<Виртуальный хост 192.168.1.1 172.20.30.40>
DocumentRoot "/www/server1"
имя_сервера server.example.com
ServerAlias сервер
</ виртуальный хост>
Теперь запросы из обеих сетей будут обслуживаться из одного и того же
<VirtualHost>
.
Примечание:
Во внутренней сети можно просто использовать имя, server
а не полное имя хоста
server.example.com
.
Также обратите внимание, что в приведенном выше примере вы можете заменить список IP-адресов на *
, что заставит сервер отвечать одинаково на все адреса.
Запуск разных сайтов на разных портах.
У вас есть несколько доменов, подключенных к одному и тому же IP, и вы также хотите обслуживать несколько портов. В приведенном ниже примере показано, что сопоставление имен происходит после определения наиболее подходящей комбинации IP-адреса и порта.
Слушай 80
Слушай 8080
<Виртуальный хост 172.20.30.40:80>
Имя сервера www.example.com
DocumentRoot "/www/домен-80"
</ виртуальный хост>
<Виртуальный хост 172.20.30.40:8080>
Имя сервера www.example.com
DocumentRoot "/www/домен-8080"
</ виртуальный хост>
<Виртуальный хост 172.20.30.40:80>
Имя сервера www.example.org
DocumentRoot "/www/otherdomain-80"
</ виртуальный хост>
<Виртуальный хост 172.20.30.40:8080>
Имя сервера www.example.org
DocumentRoot "/www/otherdomain-8080"
</ виртуальный хост>
Виртуальный хостинг на базе IP
Сервер имеет два IP-адреса ( 172.20.30.40
и
172.20.30.50
), которые разрешаются в имена
www.example.com
и www.example.org
соответственно.
Слушай 80
<Виртуальный хост 172.20.30.40>
DocumentRoot "/www/example1"
Имя сервера www.example.com
</ виртуальный хост>
<Виртуальный хост 172.20.30.50>
DocumentRoot "/www/example2"
Имя сервера www.example.org
</ виртуальный хост>
Запросы на любой адрес, не указанный ни в одной из директив
<VirtualHost>
(такой
localhost
, например, как ), будут идти на основной сервер, если он есть.
Смешанные виртуальные хосты на основе портов и IP-адресов
Серверная машина имеет два IP-адреса ( 172.20.30.40
и
172.20.30.50
), которые разрешаются в имена
www.example.com
и www.example.org
соответственно. В каждом случае мы хотим запускать хосты на портах 80 и 8080.
Слушай 172.20.30.40:80
Прослушать 172.20.30.40:8080
Слушай 172.20.30.50:80
Прослушать 172.20.30.50:8080
<Виртуальный хост 172.20.30.40:80>
DocumentRoot "/www/example1-80"
Имя сервера www.example.com
</ виртуальный хост>
<Виртуальный хост 172.20.30.40:8080>
DocumentRoot "/www/example1-8080"
Имя сервера www.example.com
</ виртуальный хост>
<Виртуальный хост 172.20.30.50:80>
DocumentRoot "/www/example2-80"
Имя сервера www.example.org
</ виртуальный хост>
<Виртуальный хост 172.20.30.50:8080>
DocumentRoot "/www/example2-8080"
Имя сервера www.example.org
</ виртуальный хост>
Смешанные виртуальные хосты на основе имени и IP
Любой адрес, упомянутый в аргументе виртуального хоста, который никогда не появляется в другом виртуальном хосте, является виртуальным хостом строго на основе IP.
Слушай 80
<Виртуальный хост 172.20.30.40>
DocumentRoot "/www/example1"
Имя сервера www.example.com
</ виртуальный хост>
<Виртуальный хост 172.20.30.40>
DocumentRoot "/www/example2"
Имя сервера www.example.org
</ виртуальный хост>
<Виртуальный хост 172.20.30.40>
DocumentRoot "/www/example3"
Имя сервера www.example.net
</ виртуальный хост>
# на базе IP
<Виртуальный хост 172.20.30.50>
DocumentRoot "/www/example4"
Имя сервера www.example.edu
</ виртуальный хост>
<Виртуальный хост 172.20.30.60>
DocumentRoot "/www/example5"
Имя сервера www.example.gov
</ виртуальный хост>
Использование Virtual_host
и mod_proxy вместе
В следующем примере внешний компьютер позволяет проксировать виртуальный хост на сервер, работающий на другом компьютере. В примере виртуальный хост с таким же именем настроен на машине по адресу 192.168.111.2
. Директива ProxyPreserveHost
On
используется для передачи желаемого имени хоста, если мы проксируем несколько имен хостов на одну машину.
<Виртуальный хост *:*>
ProxyPreserveHost включен
ProxyPass "/" "http://192.168.111.2/"
ProxyPassReverse "/" "http://192.168.111.2/"
имя_сервера имя_хоста.example.com
</ виртуальный хост>
Использование _default_
виртуальных хостов
_default_
vhosts для всех портов
Перехватывать каждый запрос к любому неуказанному IP-адресу и порту, т. е . комбинации адрес/порт, которая не используется ни для какого другого виртуального хоста.
<Виртуальный хост _default_:*>
DocumentRoot "/www/по умолчанию"
</ виртуальный хост>
Использование такого виртуального хоста по умолчанию с подстановочным портом эффективно предотвращает отправку любого запроса на главный сервер.
Виртуальный хост по умолчанию никогда не обслуживает запрос, отправленный на адрес/порт, который используется для виртуальных хостов на основе имени. Если запрос содержит неизвестный заголовок или Host:
заголовок отсутствует, он всегда обслуживается с основного виртуального хоста на основе имени (виртуальный хост для этого адреса/порта отображается первым в файле конфигурации).
Вы можете использовать AliasMatch
или
RewriteRule
переписать любой запрос на одну информационную страницу (или скрипт).
_default_
vhosts для разных портов
То же, что и в настройке 1, но сервер прослушивает несколько портов, и мы хотим использовать второй _default_
виртуальный хост для порта 80.
<Виртуальный хост _default_:80>
DocumentRoot "/www/default80"
# ...
</ виртуальный хост>
<Виртуальный хост _default_:*>
DocumentRoot "/www/по умолчанию"
# ...
</ виртуальный хост>
Виртуальный хост по умолчанию для порта 80 (который должен стоять перед любым виртуальным хостом по умолчанию с подстановочным номером порта) перехватывает все запросы, отправленные на неуказанный IP-адрес. Основной сервер никогда не используется для обслуживания запроса.
_default_
vhosts для одного порта
Мы хотим иметь виртуальный хост по умолчанию для порта 80, но не другие виртуальные хосты по умолчанию.
<Виртуальный хост _default_:80>
DocumentRoot "/www/по умолчанию"
...
</ виртуальный хост>
Запрос на неуказанный адрес на порту 80 обслуживается с виртуального хоста по умолчанию. Любой другой запрос на неопределенный адрес и порт обслуживается с основного сервера.
Любое использование *
в объявлении виртуального хоста будет иметь более высокий приоритет, чем _default_
.
Миграция виртуального хоста на основе имени на виртуальный хост на основе IP
Виртуальный хост на основе имени с именем хоста
www.example.org
(из нашего примера на основе имени, настройка 2) должен получить свой собственный IP-адрес. Чтобы избежать проблем с серверами имен или прокси-серверами, которые кэшировали старый IP-адрес для виртуального хоста на основе имени, мы хотим предоставить оба варианта на этапе миграции.
Решение простое, потому что мы можем просто добавить новый IP-адрес ( 172.20.30.50
) в VirtualHost
директиву.
Слушай 80
Имя сервера www.example.com
DocumentRoot "/www/example1"
<Виртуальный хост 172.20.30.40 172.20.30.50>
DocumentRoot "/www/example2"
Имя сервера www.example.org
# ...
</ виртуальный хост>
<Виртуальный хост 172.20.30.40>
DocumentRoot "/www/example3"
Имя сервера www.example.net
Псевдоним сервера *.example.net
# ...
</ виртуальный хост>
Теперь к виртуальному хосту можно получить доступ через новый адрес (как виртуальный хост на основе IP) и через старый адрес (как виртуальный хост на основе имени).
Использование ServerPath
директивы
У нас есть сервер с двумя виртуальными хостами на основе имен. Чтобы сопоставить правильный виртуальный хост, клиент должен отправить правильный Host:
заголовок. Старые клиенты HTTP/1.0 не отправляют такой заголовок, и Apache понятия не имеет, к какому виртуальному хосту пытался подключиться клиент (и обслуживает запрос с основного виртуального хоста). Чтобы обеспечить максимальную обратную совместимость, мы создаем первичный виртуальный хост, который возвращает одну страницу, содержащую ссылки с префиксом URL на виртуальные хосты на основе имени.
<Виртуальный хост 172.20.30.40>
# основной виртуальный хост
DocumentRoot "/www/поддомен"
RewriteEngine включен
Правило перезаписи "." "/www/субдомен/index.html"
# ...
</ виртуальный хост>
<Виртуальный хост 172.20.30.40>
DocumentRoot "/www/subdomain/sub1"
Имя сервера www.sub1.domain.tld
Путь к серверу "/sub1/"
RewriteEngine включен
RewriteRule "^(/sub1/.*)" "/www/subdomain$1"
# ...
</ виртуальный хост>
<Виртуальный хост 172.20.30.40>
DocumentRoot "/www/subdomain/sub2"
Имя сервера www.sub2.domain.tld
Путь к серверу "/sub2/"
RewriteEngine включен
Правило перезаписи "^(/sub2/.*)" "/www/subdomain$1"
# ...
</ виртуальный хост>
В соответствии с ServerPath
директивой запрос на URL-адрес
всегда http://www.sub1.domain.tld/sub1/
обслуживается с sub1-vhost. Запрос к URL-адресу
обслуживается только с sub1-vhost, если клиент отправил правильный
заголовок. Если заголовок не отправляется, клиент получает информационную страницу с основного хоста.
http://www.sub1.domain.tld/
Host:
Host:
Обратите внимание, что есть одна странность: запрос
http://www.sub2.domain.tld/sub1/
также обслуживается с sub1-vhost, если клиент не отправил Host:
заголовок.
Директивы RewriteRule
используются для того, чтобы клиент, отправивший правильный
Host:
заголовок, мог использовать оба варианта URL, т . е . с префиксом URL или без него.