Nginx совпадение неверного блока – Ipv4 и IPv6

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

Я перевел свой экземпляр AWS на публичный IPv6 адрес, чтобы избежать сборов за публичный IPv4, введенных некоторое время назад. У меня есть около шести доменов, размещенных на сервере EC2 с Nginx, с CloudFlare в качестве DNS и CDN. CloudFlare подключается к моему исходному серверу только по IPv6 и делает домены доступными как по IPv4, так и по IPv6.

Вебсайты корректно работают по https, но я заметил странное поведение с http-запросами. Когда я делал http-запрос к одному домену, он возвращал сайт другого из моих доменов. Мне потребовалось довольно много времени, чтобы выяснить, почему.

Например – я делаю curl example.com и получаю редирект на example2.com

curl -v http://example.com
< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.18.0 (Ubuntu)
< Content-Type: text/html
< Connection: keep-alive
< Location: https://example2.com

Вот конфиг Nginx – рассмотрите его как псевдокод, он может не пройти “nginx -t”.

server {
  listen 80;
  server_name example.com;
  return 301 https://example.com$request_uri;  
}

server {
  server_name example.com;
  listen [::]:443 ssl http2;

  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
  ssl_dhparam /etc/nginx/ssl/dhparams.pem;

  root     /var/www/example/;
}

server {
  listen [::]:80;
  server_name example2.com;
  return 301 https://example2.com$request_uri;  
}

server {
  server_name example2.com;
  listen [::]:443 ssl http2;

  ssl_certificate /etc/letsencrypt/live/example2.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example2.com/privkey.pem;
  ssl_dhparam /etc/nginx/ssl/dhparams.pem;

  root     /var/www/example2/;
}

Когда я изучил руководство по сопоставлению Nginx Location на Digital Ocean, я наконец-то разобрался в проблеме. Nginx сначала осуществляет сопоставление по порту прослушивания и протоколу, только если на этом порту прослушивания больше одного блока, тогда он сопоставляет по server_name.

Когда я перешел на IPv6, я обновил все https-серверы для прослушивания как на IPv4, так и на IPv6, но я пропустил обновление большинства доменов для http-редиректов на прослушивание IPv6. Как только я заставил серверы-редиректы прослушивать IPv6 наряду с IPv4, все начало работать как ожидалось.

Ключевые шаги в решении проблемы были:

  • Использование другого сервера Linux с измененным файлом hosts, чтобы он указывал непосредственно на исходный сервер, а не на CloudFlare (не уверен, имело ли это большое значение)
  • “curl -v http://example.com
  • Чтение цифрового руководства – хотя оно не упоминает IPv6, это очень помогло

Вот рабочая псевдокод конфигурация

server {
  # ЭТА СТРОКА БЫЛА ПРОБЛЕМОЙ
  listen [::]:80;
  server_name example.com;
  return 301 https://example.com$request_uri;  
}

server {
  server_name example.com;
  listen [::]:443 ssl http2;

  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
  ssl_dhparam /etc/nginx/ssl/dhparams.pem;

  root     /var/www/example/;
}

server {
  listen [::]:80;
  server_name example2.com;
  return 301 https://example2.com$request_uri;  
}

server {
  server_name example2.com;
  listen [::]:443 ssl http2;

  ssl_certificate /etc/letsencrypt/live/example2.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example2.com/privkey.pem;
  ssl_dhparam /etc/nginx/ssl/dhparams.pem;

  root     /var/www/example2/;
}

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

Решение проблемы несоответствия блоков Nginx для IPv4 и IPv6

Проблема, с которой вы столкнулись, связана с работой Nginx в многопоточной среде, когда сервер обслуживает трафик как по IPv4, так и по IPv6. Давайте подробно разберем основные аспекты и шаги, которые помогут вам понять и исправить вашу конфигурацию сервера.

Понимание конфигурации Nginx

Nginx использует алгоритм выбора блоков сервера, опираясь на два базовых критерия: сначала по порту и протоколу, а затем по имени сервера. Это значит, что в случае одновременного наличия нескольких блоков для одного и того же порта, Nginx будет сопоставлять их на основе заданного server_name.

Проблема: пропущенные настройки

Вы правильно отметили, что основная проблема заключалась в том, что не все блоки редиректа для HTTP-трафика были настроены на прослушивание IPv6. Это привело к тому, что при отправке HTTP-запросов, например, на example.com, Nginx неправильно обрабатывал запрос и перенаправлял его на другой домен, такой как example2.com.

Шаги к решению

  1. Проверка конфигурации Nginx:
    Убедитесь, что все блоки для перенаправлений на HTTP (порт 80) настроены для прослушивания как IPv4, так и IPv6. Ваша доработанная конфигурация продемонстрировала, как это можно исправить:

    server {
      listen 80;
      listen [::]:80;
      server_name example.com;
      return 301 https://example.com$request_uri;  
    }
    
    server {
      listen 80;
      listen [::]:80;
      server_name example2.com;
      return 301 https://example2.com$request_uri;  
    }
  2. Тестирование конфигурации:
    Используйте curl для проверки поведения вашего сервера после внесения изменений. Например:

    curl -v http://example.com

    Это поможет вам убедиться, что HTTP-запросы обрабатываются корректно.

  3. Использование локального сервера для тестирования:
    Размещение отдельного сервера, который с помощью измененного файла hosts будет направлять запросы непосредственно на ваш основной сервер, позволяет вам избежать возможных проблем кэширования на уровне CDN, таких как CloudFlare.

  4. Документация и дополнительные ресурсы:
    Как вы уже знаете, полезно всегда обращаться к официальной документации и руководствам. Даже если не все аспекты, такие как IPv6, подробно охвачены, это может дать понимание общей работы системы.

Заключение

Ваша ситуация подчеркивает важность детальной проверки конфигураций серверов, особенно в условиях работы с несколькими доменами и сетевыми протоколами. Исправив настройки прослушивания для HTTP-блоков, вы обеспечили корректное перенаправление для обоих доменов.

При дальнейшем мониторинге и тестировании работы вашего веб-сервера, не забудьте обратить внимание на логи Nginx для выявления возможных дополнительных проблем. Корректные и продуманные настройки сервера не только улучшат пользовательский опыт, но и помогут избежать лишних затрат.

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

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