Назад | Перейти на главную страницу

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

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

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 фильтрует заголовок, но только для этого конкретного клиента.

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

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

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

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

Обратите внимание, что это влияет только на сертификаты TLS, которые вы получите от сервера! Теоретически (см. Пункт 2 ниже) nginx по-прежнему будет использовать Host: заголовок, чтобы определить, какой из виртуальных хостов является правильным и какую конфигурацию использовать.

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

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

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

Надеюсь, поможет