NGINX перенаправляет неправильные поддомены

Вопрос или проблема

Я настроил свой NGINX так, чтобы он принимал только HTTPS-трафик на порту 443, и я хочу перенаправить весь не-HTTPS-трафик с порта 80 на HTTPS.

У меня также есть несколько подсайтов, которые я хочу управлять независимо.

Я собираюсь показать пример из своей конфигурации, но опущу скучные детали.

Основной веб-сайт, который должен быть доступен для обычного пользователя:

server
{
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name www.myserver.com;

    root /var/www/www.myserver.com;

    index index.php index.html index.htm;
}

Один из подсайтов:

server
{
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name subdomain.myserver.com;

    location /
    {
        proxy_pass https://127.0.0.1:8500;
    }
}

А теперь я хочу перенаправить трафик с порта 80 на HTTPS:

server
{
    listen 80;
    listen [::]:80;

    server_name subdomain.myserver.com;

    return 301 https://subdomain.myserver.com$request_uri;
}

Проблема: ВСЕ подсайты автоматически перенаправляются на “https://subdomain.myserver.com“, даже если они не соответствуют имени сервера, указанному в блоке перенаправления.

http://www.myserver.com” (для которого нет конфигурационного блока) будет перенаправлен на “https://subdomain.myserver.com“, даже если оно не соответствует server_name

Добавьте блок сервера “Catch All”, как задокументировано:

server {
    listen 80 default_server;
    server_name _;
    server_name_in_redirect off;
    location / {
        return 404;
    }
}

Еще одной возможной причиной “перенаправлений” являются заголовки HSTS. Как только клиент увидит заголовки HSTS с includeSubDomains, установленным на основном домене, он также будет пытаться получить доступ к своим подсайтам напрямую через HTTPS, не пытаясь сначала использовать HTTP.

Согласно ссылке https://nginx.org/en/docs/http/request_processing.html, приведенной в комментарии Drifter104, первое определение сервера, встретившееся в конфигурации для конкретного порта, считается по умолчанию, вот почему все подсайты перенаправлялись на первое определение сервера. Попробуйте создать конфиг /etc/nginx/conf.d/default_server.conf со следующим содержимым:

server {
    listen  80     default_server;
    server_name default.myserver.com;
    location / {
        return 404;
    }
}
server {
    listen 443 ssl default_server;
    server_name default.myserver.com;
    location / {
        return 404;
    }
}

После перезапуска nginx все домены, которые не явно указаны в конфигурации, будут показывать ошибку 404.

Ответ или решение

Проблема с перенаправлением поддоменов в NGINX

Введение

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

Основная конфигурация NGINX

Вы уже настроили два блока серверов для работы с HTTPS: один для основного сайта (www.myserver.com) и один для поддомена (subdomain.myserver.com). Это обеспечивает доступ к статикам и прокси-трафику:

server {
    listen 443 ssl;
    server_name www.myserver.com;
    root /var/www/www.myserver.com;
    index index.php index.html index.htm;
}

server {
    listen 443 ssl;
    server_name subdomain.myserver.com;
    location / {
        proxy_pass https://127.0.0.1:8500;
    }
}

Вы правильно настроили отдельный серверный блок для перенаправления HTTP-запросов на HTTPS:

server {
    listen 80;
    server_name subdomain.myserver.com;

    return 301 https://subdomain.myserver.com$request_uri;
}

Проблема с перенаправлением поддоменов

Однако вы сталкиваетесь с проблемой, когда запросы на другие поддомены (например, www.myserver.com) также перенаправляются на subdomain.myserver.com. Это происходит потому, что NGINX использует первый совпадающий блок сервера, который он находит для порта, когда конфигурация не была явно указана.

Решение: создание блока "Catch All"

Для предотвращения такого поведения необходимо добавить специальный блок "Catch All", который будет обрабатывать все запросы, не соответствующие конкретным серверным именам. Этот блок должен настроить NGINX для возврата 404 в случае отсутствия соответствия:

server {
    listen 80 default_server;
    server_name _;
    return 404;
}

server {
    listen 443 ssl default_server;
    server_name _;
    return 404;
}

Влияние заголовков HSTS

Кроме того, стоит учитывать, что если ваш основной домен использует заголовки HTTP Strict Transport Security (HSTS) с опцией includeSubDomains, то браузеры будут пытаться установить безопасное соединение с поддоменами. Это может вызвать нежелательное поведение при редиректе, так как клиент может обращаться к поддоменам по HTTPS, даже если для них нет соответствующих блоков конфигурации.

Рекомендации

  1. Обновите конфигурацию: Примените предложенные изменения и перезапустите NGINX для применения новых настроек.
  2. Проверка HSTS: Убедитесь, что заголовки HSTS не вмешиваются в работу ваших поддоменов. Если HSTS необходим, рассмотрите возможность их необходимости указывать только на определённые поддомены.
  3. Мониторинг и тестирование: После корректировки конфигурации протестируйте доступ к каждому поддомену и убедитесь, что каждый из них работает независимо.

Заключение

Правильная настройка NGINX требует внимательного подхода, особенно при управлении несколькими поддоменами. Добавление блока "Catch All" и управление заголовками HSTS помогут вам избежать нежелательных перенаправлений и обеспечить стабильную работу вашего веб-приложения.

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

Капча загружается...