Виртуальные хосты

Тема дорожной карты · Nginx

Виртуальные хосты позволяют одному экземпляру веб-сервера Nginx обслуживать несколько веб-сайтов или приложений одновременно, направляя входящие запросы в разные блоки server на основе HTTP-заголовка Host, IP-адреса или номера порта. В Nginx виртуальные хосты реализованы как блоки server в nginx.conf или в отдельных файлах, подключаемых из /etc/nginx/conf.d/ или /etc/nginx/sites-enabled/; каждый содержит директиву server_name, задающую домены, которые обслуживает этот блок. Именное виртуальное хостирование — наиболее распространённая форма — позволяет многим доменам делить один IP-адрес: Nginx сопоставляет заголовок Host с соответствующим server_name и отдаёт контент из соответствующей директории root или проксирует запрос на соответствующий upstream-бэкенд. IP-based виртуальное хостирование использует отдельные директивы listen с явными IP-адресами, тогда как хостирование на основе порта разграничивает сайты по прослушиваемым TCP-портам; оба варианта также нативно поддерживаются Nginx. Управление виртуальными хостами как отдельными подключаемыми файлами конфигурации (по одному файлу на сайт) — устоявшаяся операционная практика, упрощающая включение и отключение сайтов, применение проверки nginx -t для каждого файла конфигурации и nginx -s reload для активации изменений без прерывания работы других виртуальных хостов.

Как это работает

Виртуальные хосты (server-блоки в терминологии nginx) позволяют одному nginx обслуживать много хостнеймов + сайтов. server { listen 80; server_name app.example.com; ... }; server_name матчится с Host:-заголовком; default-сервер обрабатывает несовпавшие хостнеймы. Wildcard (*.example.com) или regex (~^(?<sub>.+)\.example\.com$). HTTPS: listen 443 ssl http2 + ssl_certificate + ssl_certificate_key. Default-сервер критичен для безопасности (отвергайте неизвестные хостнеймы).

Когда применять

Всегда определяйте default-сервер, возвращающий 444 (или 421) для несовпавших хостнеймов — предотвращает Host-header инъекции / SSRF-зондирование. Один server-блок на файл в /etc/nginx/conf.d/. if ($host = "example.com") — осторожно (if в nginx имеет edge cases — предпочитайте отдельные server-блоки). Всегда явно listen; полагание на дефолты путает.

Типичные ошибки

Ловушки Виртуальные хосты: нет default-сервера — первый server в конфиге становится дефолтным (сюрприз); тот же listen-порт без разного server_name (выигрывает только первый); server_name _; как catch-all без понимания, что он матчит всё; if ($http_host = ...) performance + edge cases ("if is evil" — см. официальную wiki).

Связанные понятия

Полезные ресурсы