HttpRequest: несовместимые свойства схемы и хоста - PullRequest
0 голосов
/ 30 января 2020

My ASP. NET Приложение Core 3.1 работает в Kubernetes. Вход (балансировщик нагрузки) завершает SSL и общается с модулем по обычному HTTP.

Допустим, вход достижим в https://my-app.com: 443 и говорит с модулем (где мой приложение работает) в http://10.0.0.1: 80 .

При обработке запроса конвейер промежуточного программного обеспечения видит объект HttpRequest со следующим:

  • Scheme == "http"
  • Host.Value == "my-app.com"
  • IsHttps == False

Это странно:

  • Судить SchemeIsHttps), кажется, объект HttpRequest описывает перенаправленный запрос от входа к модулю, который переходит по обычному HTTP. Однако, почему Host.Value не равно 10.0.0.1 в этом случае?
  • Или наоборот: если HttpRequest пытается быть умным и представлять исходный запрос, тот, что поступил, почему разве он не показывает "https" вместе с "my-app.com"?

Ни в какой точке обработки запроса нет запроса, поступающего на http://my-app.com. Это либо https://my-app.com, либо http://10.0.0.1. Комбинация несовместима.

Другие детали

Копая глубже, объект HttpRequest имеет следующие заголовки (среди прочих), которые показывают обратное проксирование в действии:

Host: my-app.com
Referer: https://my-app.com/swagger/index.html
X-Real-IP: 10.0.0.1
X-Forwarded-For: 10.0.0.1
X-Forwarded-Host: my-app.com
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Scheme: https

Полагаю, HttpRequest использует их для получения исходного хоста (my-app.com, а не 10.0.0.1), но он не делает то же самое для исходной схемы (https, а не http).

Q1 : Ожидается ли это, и если да, каково обоснование?

Q2 : Каков наилучший способ получить оригинал? URL (https://my-app.com)? Лучшее, что я нашел на данный момент, это проверить, присутствуют ли заголовки X-Scheme и X-Forwarded-Host (проверяя HttpRequest.Headers), и если да, то используйте их. Однако, немного странно иметь go для необработанных заголовков HTTP в конвейере промежуточного программного обеспечения.

1 Ответ

1 голос
/ 19 февраля 2020

В1: Ожидается ли это, и если да, каково обоснование?

Я бы сказал, да, это ожидаемое поведение.

Объект 'Host.Value=my-app.com' из HttpRequest отражает поле заголовка запроса, созданное клиентом (веб-браузер, curl, ...), например:

curl --insecure -H 'Host: my-app.com' https://<FRONTEND_FOR_INGRESS-MOST_OFTEN_LB-IP>

, которое установлено * [1] в блоке местоположения для этого сервера 'my-app.com' внутри сгенерированного nginx.conf файла:

                    ...
                    set $best_http_host                     $http_host;
                    # [1] - Set Host value 
                    proxy_set_header Host                   $best_http_host;
                    ...
                    # Pass the extracted client certificate to the backend
                    ...
                    proxy_set_header                        Connection        $connection_upgrade;             
                    proxy_set_header X-Request-ID           $req_id;
                    proxy_set_header X-Real-IP              $remote_addr;
                    proxy_set_header X-Forwarded-For        $remote_addr;
                    proxy_set_header X-Forwarded-Host       $best_http_host;
                    ...  

, тогда как переменная ' http_host ' создается на основе следующих основных функций "ngx_http_core_module":

$ http_name - поле произвольного заголовка запроса; последняя часть имени переменной - это имя поля, преобразованное в нижний регистр с черточками, замененными подчеркиванием

Таким образом, описанное поведение в любом случае не уникально для ASP. NET Core 3.0, вы видите неизвестное Словарь, содержащий пары ключ / значение пользовательских заголовков, установленных явно nginx контроллером, в соответствии с nginx входной текущей конфигурацией, вот и все.

Вы можете проверить текущую конфигурацию nginx контроллера самостоятельно, выполнив следующую команду :

kubectl exec -it po/<nginx-ingress-controller-pod-name> -n <ingress-controller-namespace> -- cat /etc/nginx/nginx.conf

Q2: Какой лучший способ получить исходный URL (https://my-app.com)?

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

...