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,其中包含以下内容:
Scheme == "http"
Host.Value == "my-app.com"
IsHttps == False
这很奇怪:
- 根据
Scheme
(和 IsHttps
)判断,似乎 HttpRequest
object 描述了从入口到 pod 的转发请求,那个去通过纯 HTTP。但是,在那种情况下,为什么 Host.Value
不等于 10.0.0.1
?
- 反之亦然:如果
HttpRequest
试图变得聪明并代表原始请求,即入口请求,为什么它不显示 "https"
和 "my-app.com"
?
在处理请求的任何时候都没有请求到达 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-Scheme
和 X-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,您可以在其中连接值。
我的 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,其中包含以下内容:
Scheme == "http"
Host.Value == "my-app.com"
IsHttps == False
这很奇怪:
- 根据
Scheme
(和IsHttps
)判断,似乎HttpRequest
object 描述了从入口到 pod 的转发请求,那个去通过纯 HTTP。但是,在那种情况下,为什么Host.Value
不等于10.0.0.1
? - 反之亦然:如果
HttpRequest
试图变得聪明并代表原始请求,即入口请求,为什么它不显示"https"
和"my-app.com"
?
在处理请求的任何时候都没有请求到达 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-Scheme
和 X-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,您可以在其中连接值。