Http 请求:Scheme 和 Host 属性不一致

HttpRequest: inconsistent Scheme & Host properties

我的 ASP.NET Core 3.1 应用程序在 Kubernetes 中运行。入口(负载均衡器)终止 SSL 并通过纯 HTTP 与 pod 对话。

假设可以在 https://my-app.com:443, and talks to the pod (where my app is running) at http://10.0.0.1:80 到达入口。

处理请求时,中间件管道会看到 HttpRequest object,其中包含以下内容:

这很奇怪:

在处理请求的任何时候都没有请求到达 http://my-app.com. It's either https://my-app.com or http://10.0.0.1。组合不一致。

其他详情

深入挖掘,HttpRequest object 具有以下 headers(以及其他)显示反向代理的作用:

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-SchemeX-Forwarded-Host headers 是否存在(通过检查 HttpRequest.Headers),如果存在,则使用它们。但是,在中间件管道中转到原始 HTTP headers 有点奇怪。

Q1: Is this expected, and if so, what is the rationale?

我会说是的,这是预期的行为。

HttpRequest object 的 'Host.Value=my-app.com' 反映了客户端(网络浏览器,curl,...)发起的请求 header 字段,例如:

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 - arbitrary request header field; the last part of a variable name is the field name converted to lower case with dashes replaced by underscores

所描述的行为无论如何都不是 ASP.NET Core 3.0 独有的,您会看到包含 key/value 对自定义 header 的未知字典,由 nginx 控制器根据 nginx ingress 明确设置当前配置,仅此而已。

您可以使用以下命令自行检查当前 nginx 控制器的配置:

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

Q2: What's the best way to get at the original URL (https://my-app.com)?

我会尝试使用 Configuration 片段构建它,这是通过引入另一个自定义 header,您可以在其中连接值。