Nginx закрывает соединение

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

Я использую стандартный пакет nginx на Debian Bookworm. Обычно я использую только HTTPS-соединения для этого сервиса, и все работает нормально. По умолчанию для HTTP-порта 80 установлен редирект на протокол HTTPS.

server {
  listen 80 default_server;
  listen [::]:80 default_server;
  server_tokens off;

  return 301 https://$host$request_uri;

  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log error;
}

server {
  listen 80;
  listen [::]:80;
  server_name xyz;
  server_tokens off;

  location / {
    root /var/www/html/;
  }

  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log error;
}

// vhosts с конфигурациями listen 443 здесь опущены, они работают

У меня есть IoT-клиент, который не поддерживает HTTPS, и я настроил его на использование HTTP и добавил VHost для этого домена, чтобы он не перенаправлял запрос на HTTPS. Но этот запрос никогда не обрабатывается. Используя curl, я получаю такой ответ:

# curl -v http://localhost/
*   Попытка 127.0.0.1:80...
* Подключено к localhost (127.0.0.1) порт 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.88.1
> Accept: */*
> 
* Получен HTTP/0.9, когда это не разрешено
* Закрытие соединения 0
curl: (1) Получен HTTP/0.9, когда это не разрешено

В журналах journald, а также в журналах доступа или ошибок nginx отсутствуют сообщения.

Затем я попробовал “хардкорный” telnet на порт 80 и получил более странный результат:

# telnet localhost 80
Попытка ::1...
Подключено к localhost.
Эскейп-символ '^>'.
GET / HTTP/1.1
Соединение закрыто удаленным хостом.

Таким образом, сразу после первой строки Nginx закрывает соединение (ответ HTTP/0.9 приходит от самого curl).

Поскольку я не мог установить заголовок Host: в запросе, этот запрос никогда не проверяет никакую конфигурацию виртуального хоста.

У меня нет идеи, что не так. Сервер должен хотя бы дождаться заголовка Host перед закрытием соединения. Файл /etc/nginx/nginx.conf не изменен.

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

Анализ проблемы: закрытие соединения Nginx

При использовании сервера Nginx на Debian Bookworm с необработанными HTTP-запросами, мы сталкиваемся с проблемой закрытия соединения. Рассмотрим более детально, что происходит и как это можно исправить.

Описание проблемы

Указанный конфигурационный файл Nginx содержит два блока server, которые обрабатывают запросы на HTTP (порт 80). Первый блок перенаправляет все запросы на HTTPS с помощью return 301, что приводит к тому, что все запросы попадают в переадресацию. Второй блок определяет виртуальный хост на тот же порт 80, но не настроен для перенаправления.

Когда вы пытаетесь ввести в действие ваш IoT-клиент, который не поддерживает HTTPS, вы получаете сообщение об ошибке:

* Received HTTP/0.9 when not allowed
* Closing connection 0

Это говорит о том, что запрос не был корректно обработан сервером.

Возможные причины

  1. Отсутствие заголовка "Host": Во время работы через telnet, когда вы отправляете запрос без заголовка "Host", сервер может не распознать его как допустимый HTTP-запрос. Nginx ожидает, что все HTTP-запросы будут иметь заголовок "Host", который указывает на имя сервера. Без этого заголовка Nginx может завершить соединение, так как не может определить, какому виртуальному хосту следует направить запрос.

  2. Настройки конфигурации: Ваш конфигурационный файл выглядит корректным, но наличие блока по умолчанию для порта 80 может вызывать путаницу. Если ваш IoT-клиент не включает заголовок "Host", запрос будет проигнорирован или, как в этом случае, соединение будет закрыто.

Рекомендации по исправлению

  1. Отладка через telnet: Чтобы правильно протестировать с помощью telnet, вы можете вручную добавить заголовок "Host" в запрос, например:

    GET / HTTP/1.1
    Host: localhost

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

  2. Упрощение конфигурации: Если ваш IoT-клиент не поддерживает HTTPS, рассмотрите возможность упрощения конфигурации Nginx. Один из вариантов — убрать блоки, которые создают конфликт. Например, перенаправление может быть удалено в том случае, если клиент никогда не должен быть перенаправлен на HTTPS.

  3. Дополнительная конфигурация виртуального хоста: Убедитесь, что у вас есть отдельная конфигурация для виртуального хоста, который обрабатывает запросы от IoT-клиента. Она должна иметь параметр server_name, который соответствует запросам от клиента, а также обработку для необходимых путей.

  4. Логи: Проверьте настройки логирования. Убедитесь, что уровень журналирования достаточно подробный, чтобы фиксировать запросы и ошибки. Использование уровня "debug" может оказаться полезным.

Заключение

Проблема, связанная с закрытием соединения в Nginx, часто возникает из-за отсутствия необходимого заголовка "Host" или конфигурационных несоответствий. Следуя предложенным рекомендациям, вы сможете устранить проблему и добиться правильной обработки запросов от вашего IoT-клиента. Убедитесь, что ваш сервер Nginx настроен в соответствии с требованиями используемых клиентских приложений и соблюдены все условия, чтобы избежать ненужных разрывов соединений.

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

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