如何通过代理转发 http 2 协议版本?
how to forward http 2 protocol version via proxy?
我有一个简单的 rails 应用程序
(browser) -> (nginx latest; proxy_pass) -> rails (latest)
如何配置 nginx 以通知 rails nginx 通过不同的 header IE: my_"http_version = 2.0" 收到了 HTTP/2 请求? proxy_pass 通过 HTTP 1.1 与 rails 通信,我想知道原始请求是否为 http/2。
谢谢!
proxy_set_header X-Forwarded-ProtoVersion $server_protocol;
注:X-Forwarded-ProtoVersion是虚构的变量名。不知道标准的是什么
这类似于 X-Forwarded-For
和 X-Forwarded-Proto
headers 的用途,但没有 standard header 用于将 HTTP 协议版本传达给后端.我推荐使用这个:
proxy_set_header X-Forwarded-Proto-Version $http2;
$http2
变量来自 ngx_http_v2_module,我假设您正在使用 Nginx 到服务器 HTTP/2。
$http2
和 $server_protocol
之间的区别在于 $http2
更像一个布尔值,如果使用 HTTP/1 协议则显示为空白。 $server_protocol
将包含 "HTTP/1.1" 或 "HTTP/2.0" 等值,因此根据您的需要,它也是一个不错的选择。
我可以告诉你我们做了什么,但你可能会觉得很奇怪。 如果您不关心连续信任和查看多个代理,您可能可以像其他答案描述的那样使用更简单的方法。
首先,我们的应用程序必须支持查看 运行 并由客户维护的代理。在我们的应用服务器上,我们始终需要记住,请求可能会通过多个代理,对于某些客户,我们实际上必须支持该用例,以便应用可以看到多个代理以获取原始 headers.
为了在我们的应用程序中支持上游代理,我们有一个请求过滤器来分析 X-Forwarded-For
header 值以及远程主机 IP。然后我们将所有 X-Forwarded-*
代理 header 值和 "unwind" 拆开,只有当我们确定它们是由 header 配置已按合同建立的受信任代理添加时(这些将是我们应用程序中的特定 pre-configured IP)。这个处理非常复杂,所以我就说这么多。但是,我们得到:
- 代表所有 "trustworthy" 远程 IP 的 IP 列表
在链中。
- 最"trustworthy"原始header值,
它将被应用程序用于 URL 生成等
在我们的应用程序中,我们专门为 HTTP/2 做的唯一工作是优化(例如,不要连接 JS 文件),但是代理链中的任何 HTTP/1.x 连接都会成为性能瓶颈. 所以我们只关心整个请求链是否从头到尾都是HTTP/2。因此,我们要求所有支持 HTTP/2 的上游代理实现我们发明的特殊 header,我们称之为 H2-IP
.
如果任何上游代理收到 HTTP/2 请求,我们要求代理 将远程主机附加 到 H2-IP
header。然后,在服务器端,我们将遍历由我们可信赖的配置代理(上面的#1)传递的可信赖远程 IP 列表,并确保每个 IP 也都列在 H2-IP header.
例如:
- 受信任的代理 IP (pre-configured):11.22.33.44、9.8.7.6、10.20.30.40、127.0.0.1、45.235.235.200
- 远程主机:10.20.30.40
- 是HTTP/2吗?是
- X-Forwarded-For header: 23.45.67.78, 11.22.33.44
- X-Forwarded-Host header: malicious.user.injected.value, app.customer.com, internalproxy.mycompany.com
- X-Forwarded-Proto header: http, https, https
- H2-IP header: 23.45.67.78, 11.22.33.44
在这个例子中,发现远程主机 (10.20.30.40) 是一个受信任的代理,我们通过合同知道这个代理将发送所有三个 X-Forwarded-(For|Host|Proto) header秒。因此,我们从每个 header 中提取最后一个值,使用这些未提取的值作为受信任的请求数据,然后我们对每个 X-Forwarded-For IP 重复该过程,直到我们得到一个不是受信任的代理。所以这是我们最终得到的数据:
- 原远程主机:23.45.67.78
- 原始主机header:app.customer.com (注意:我们丢弃了一个不受信任的值)
- 原方案:https (注意:我们丢弃了一个不受信任的值)
- 可信IP链:23.45.67.78 -> 11.22.33.44 -> 10.20.30.40 -> 应用
- HTTP/2 远程 IP:23.45.67.78、11.22.33.44、10.20.30.40
因此,由于整个可信 IP 链是 HTTP/2 远程 IP 的子集,我们知道此请求从头到尾都是 HTTP/2。
如果您不关心连续信任和查看多个代理,您可能可以像其他答案描述的那样使用更简单的方法。
我有一个简单的 rails 应用程序
(browser) -> (nginx latest; proxy_pass) -> rails (latest)
如何配置 nginx 以通知 rails nginx 通过不同的 header IE: my_"http_version = 2.0" 收到了 HTTP/2 请求? proxy_pass 通过 HTTP 1.1 与 rails 通信,我想知道原始请求是否为 http/2。
谢谢!
proxy_set_header X-Forwarded-ProtoVersion $server_protocol;
注:X-Forwarded-ProtoVersion是虚构的变量名。不知道标准的是什么
这类似于 X-Forwarded-For
和 X-Forwarded-Proto
headers 的用途,但没有 standard header 用于将 HTTP 协议版本传达给后端.我推荐使用这个:
proxy_set_header X-Forwarded-Proto-Version $http2;
$http2
变量来自 ngx_http_v2_module,我假设您正在使用 Nginx 到服务器 HTTP/2。
$http2
和 $server_protocol
之间的区别在于 $http2
更像一个布尔值,如果使用 HTTP/1 协议则显示为空白。 $server_protocol
将包含 "HTTP/1.1" 或 "HTTP/2.0" 等值,因此根据您的需要,它也是一个不错的选择。
我可以告诉你我们做了什么,但你可能会觉得很奇怪。 如果您不关心连续信任和查看多个代理,您可能可以像其他答案描述的那样使用更简单的方法。
首先,我们的应用程序必须支持查看 运行 并由客户维护的代理。在我们的应用服务器上,我们始终需要记住,请求可能会通过多个代理,对于某些客户,我们实际上必须支持该用例,以便应用可以看到多个代理以获取原始 headers.
为了在我们的应用程序中支持上游代理,我们有一个请求过滤器来分析 X-Forwarded-For
header 值以及远程主机 IP。然后我们将所有 X-Forwarded-*
代理 header 值和 "unwind" 拆开,只有当我们确定它们是由 header 配置已按合同建立的受信任代理添加时(这些将是我们应用程序中的特定 pre-configured IP)。这个处理非常复杂,所以我就说这么多。但是,我们得到:
- 代表所有 "trustworthy" 远程 IP 的 IP 列表 在链中。
- 最"trustworthy"原始header值, 它将被应用程序用于 URL 生成等
在我们的应用程序中,我们专门为 HTTP/2 做的唯一工作是优化(例如,不要连接 JS 文件),但是代理链中的任何 HTTP/1.x 连接都会成为性能瓶颈. 所以我们只关心整个请求链是否从头到尾都是HTTP/2。因此,我们要求所有支持 HTTP/2 的上游代理实现我们发明的特殊 header,我们称之为 H2-IP
.
如果任何上游代理收到 HTTP/2 请求,我们要求代理 将远程主机附加 到 H2-IP
header。然后,在服务器端,我们将遍历由我们可信赖的配置代理(上面的#1)传递的可信赖远程 IP 列表,并确保每个 IP 也都列在 H2-IP header.
例如:
- 受信任的代理 IP (pre-configured):11.22.33.44、9.8.7.6、10.20.30.40、127.0.0.1、45.235.235.200
- 远程主机:10.20.30.40
- 是HTTP/2吗?是
- X-Forwarded-For header: 23.45.67.78, 11.22.33.44
- X-Forwarded-Host header: malicious.user.injected.value, app.customer.com, internalproxy.mycompany.com
- X-Forwarded-Proto header: http, https, https
- H2-IP header: 23.45.67.78, 11.22.33.44
在这个例子中,发现远程主机 (10.20.30.40) 是一个受信任的代理,我们通过合同知道这个代理将发送所有三个 X-Forwarded-(For|Host|Proto) header秒。因此,我们从每个 header 中提取最后一个值,使用这些未提取的值作为受信任的请求数据,然后我们对每个 X-Forwarded-For IP 重复该过程,直到我们得到一个不是受信任的代理。所以这是我们最终得到的数据:
- 原远程主机:23.45.67.78
- 原始主机header:app.customer.com (注意:我们丢弃了一个不受信任的值)
- 原方案:https (注意:我们丢弃了一个不受信任的值)
- 可信IP链:23.45.67.78 -> 11.22.33.44 -> 10.20.30.40 -> 应用
- HTTP/2 远程 IP:23.45.67.78、11.22.33.44、10.20.30.40
因此,由于整个可信 IP 链是 HTTP/2 远程 IP 的子集,我们知道此请求从头到尾都是 HTTP/2。
如果您不关心连续信任和查看多个代理,您可能可以像其他答案描述的那样使用更简单的方法。