Виртуальный хост Apache по умолчанию. _default_ и catch-all в Apache

При настройке виртуальных хостов Apache может возникнуть вопрос, что произойдёт, если на сервер придёт запрос, не предназначенный ни для одного из хостов? Пример такого запроса — обращение к веб-серверу по IP без указания имени хоста. Или обращение к серверу с неверным (отсутствующем на сервере) именем хоста.

Это не вызовет ошибку в Apache — веб сервер покажет содержимое хоста по умолчанию. Чтобы понимать, что именно будет показано и как изменить хост по умолчанию в Apache, будет рассказано в этой инструкции.

Если на веб-сервере всего один хост (виртуальный хост), то он и будет хостом по умолчанию.

Если хостов два и более, то будут работать следующие правила:

  • если запрошен существующий хост, то именно он и будет показан
  • если запрошен НЕ существующий хост, то будет показан ПЕРВЫЙ встретившийся в конфигурационных файлах хост

То есть при использовании виртуальных хостов на основе имени (name-based virtual hosts) хостом по умолчанию становится первый загруженный хост. Например, у веб-сервера следующий конфигурационный файл:

NameVirtualHost *:80

<VirtualHost *:80>
  ServerName domain-one.com
  # Другие опции и директивы ..
</VirtualHost>

<VirtualHost *:80>
  ServerName domain-two.com
  # Другие опции и директивы ..
</VirtualHost>

Если запрошен домен domain-one.com, то будет показано его содержимое. Если запрошен домен domain-two.com, то будет показано его содержимое. Если запрошен любой другой хост, который не существует на сервере, то будет показано содержимое domain-one.com.

Обычно на сервере не один монолитный конфигурационный файл, а несколько конфигурационных файлов для каждого хоста, организованные следующие образом:

/etc/apache2
|-- sites_available  (настоящие конфигурационные файлы)
`-- sites_enabled    (символические ссылки на файлы в sites_available)

В этом случае, чтобы сделать так, чтобы первой загружалась конфигурация конкретного виртуального хоста, переименуйте символическую ссылку в что-то, что будет идти первой при сортировке, к примеру 00-default.

Интуитивно может казаться, что если не установить ServerName в настройках виртуального хоста, то такой хост должен стать хостом по умолчанию. Но это неправильно — само по себе не указание значения ServerName в настройке хоста является неверным. Если хост без ServerName не идёт первым в загрузке, то Apache никогда не будет его использовать, поскольку хостом по умолчанию всё равно будет тот, который загружен первым.

Некоторые предлагают для установки виртуального хоста по умолчанию использовать

ServerAlias *

это может работать, но несёт ряд последствий. Действительно, такая конструкция будет соответствовать всему что угодно, но это может переписать заданные после неё другие виртуальные хосты. Может быть это решение и будет работать, если поместить хост с ServerAlias * в самый конец, чтобы он не мог переписать значения других виртуальных хостов. Но это решение просто более сложное по сравнению с предложенным ранее: нужно добавить директиву и нужно изменить порядок хостов, в то время как в первоначально предложенном варианте достаточно только изменить порядок хостов.

_default_ в Apache

Вместо указания звёздочки (*), которая соответствует любому IP адресу, можно указать слово _default_. Судя по всему, функции звёздочки и _default_ очень похожие или идентичные. В примерах конфигураций со словом _default_ для виртуальных хостов не используется директива ServerName (что для обычных хостов является некорректным). Дело в том, что в Apache 2.2 было более жёсткое разграничение виртуальны хостов на основе имени и виртуальны хостов на основе IP. Для Apache 2.2 значение * и _default_ было различным и они применялись в различных контекстах.

Начиная с Apache 2.4 всё стало намного проще:

  • Символ *, выполняет роль подстановочного символа и соответствует любому IP адресу.
  • Строка _default_ в настоящее время является псевдонимом (полным аналогом) *

_default_ для всех портов

Чтобы перехватить каждый запрос на IP адрес и порт, комбинация которых не используется в других виртуальных хостах, нужно записать так:

<VirtualHost _default_:*>
    DocumentRoot "/www/default"
</VirtualHost>

_default_ для различных портов

Как и предыдущий пример 1, но сделаны различные дефолтные виртуальные хосты для порта 80 и всех других портов:

<VirtualHost _default_:80>
    DocumentRoot "/www/default80"
    # ...
</VirtualHost>

<VirtualHost _default_:*>
    DocumentRoot "/www/default"
    # ...
</VirtualHost>

Любое использование * в декларации виртуальных хостов будет иметь более высокий приоритет чем _default_.

Документация по _default_: https://httpd.apache.org/docs/trunk/vhosts/examples.html#default

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *