nginx фильтрует заголовки с точкой в ​​имени заголовка, даже после включения ignore_invalid_headers

Клиент (разработанный третьей стороной) отправляет запрос с такими заголовками, как foo.meta-digest (обратите внимание на "точку" "в названии заголовка). Мой обратный прокси-сервер nginx удаляет эти заголовки из запроса, даже если я добавил ignore_invalid_headers off; (см. http://nginx.org/r/ignore_invalid_headers ) в блок server {...} для этого виртуального хоста:

upstream backend {
   keepalive 128;
   keepalive_requests 1000;
   keepalive_timeout 120s;
   server 127.0.0.1:32000 max_fails=0 fail_timeout=10;
}

server {

   listen 443 ssl http2;
   server_name foo.com;
   root /var/www/empty;
   ssl_certificate /etc/nginx/certs/foo.com.crt;
   ssl_certificate_key /etc/nginx/certs/foo.com.key;

   ignore_invalid_headers off;

   location / {
       proxy_pass http://backend;
       proxy_set_header        Host              $http_host;
       proxy_set_header        X-Real-IP         $remote_addr;
       proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header        X-Forwarded-Proto $scheme;
       proxy_set_header        Connection      "";
   }
}

Я не могу воспроизвести эту проблему с любым другим клиентом, кроме этого конкретного, и у меня нет доступа к исходному коду этого клиента, это проприетарное программное обеспечение .

Если я отправлю тот же запрос с помощью curl или любого другого веб-клиента, все заголовки, включая те, в названии которых есть «точка», будут переданы на бэкэнд должным образом.

Я попытался даже запустить атаку mitm против хоста nginx и перехватил сетевой трафик от клиента. Клиент определенно отправляет заголовок foo.meta-digest , как и ожидалось. Каким-то образом nginx фильтрует заголовок, но только для этого конкретного клиента.

Что еще я могу сделать для устранения этой проблемы?

1
задан 6 December 2019 в 13:39
1 ответ

Просто имел подобную проблему, и я только зафиксировал ее путем добавления ignore_invalid_headers off также к серверу по умолчанию

, клиент в моем случае делал два странных (и плохая практика) вещи:

1) Это соединялось в TLSv1.2, но без [1 117] использование SNI расширения.
Это используется клиентом для предоставления (в открытом тексте) доменного имени, с которым он соединяется, так, чтобы сервер смог использовать правильный сертификат для права vhost.
Без этого, клиент всегда получает сертификат для значения по умолчанию vhost.
..., который прикрепил клиент, так, чтобы это было принято даже при том, что это было недопустимо для домена.

Примечание, что это только влияет на сертификаты TLS, которые Вы получите от сервера! В теории (см. точку 2 позже) nginx будет все еще использовать Host: заголовок для определения, который является корректным vhost, и который conf использовать.

Примечание, что, если Вы не прикрепляете сертификат в клиентском приложении, и если Вы не уверены в сертификате, это - очень небезопасная вещь сделать. Вы открыли бы себя для нападений на MITM.
кроме того, SNI был разработан как 12 лет назад, и это необходимо для виртуального хостинга.

2) Nginx будет использовать Host: Заголовок для знания который vhost конфигурация применяться.
, Как можно предположить, так как я сказал Вам добавлять ignore_invalid_headers в сервере по умолчанию, это не работает над особым случаем:
RFC7230, разделите 5.4 , говорит, что Host заголовок ДОЛЖЕН быть первой вещью, которую Вы отправляете.
В моем случае (и проуспешно Ваш) это не было.
заголовки перед эти Host Заголовки таким образом анализируются, поскольку в конфигурации сервера по умолчанию, затем nginx находит Host и переключается на корректный vhost.

Странная, почти нестандартная, определенно плохая практика, но не технически неправильно.

Hope это помогает

3
ответ дан 31 December 2019 в 12:07

Теги

Похожие вопросы