如何通过代理转发http 2协议版本?

时间:2016-01-17 14:12:37

标签: http nginx configuration

我有一个简单的rails应用程序

(browser) -> (nginx latest; proxy_pass) -> rails (latest)

如何配置nginx以通知rails nginx通过不同的标头IE收到HTTP / 2请求:my_“http_version = 2.0”? proxy_pass通过HTTP 1.1与rails通信,我想知道原始请求是否为http / 2。

谢谢!

3 个答案:

答案 0 :(得分:5)

这类似于X-Forwarded-ForX-Forwarded-Proto标头的用途,但没有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",根据您的需要,它也可能是一个不错的选择。

答案 1 :(得分:1)

我可以告诉你我们做了什么,但你可能会发现它很奇怪。 如果您不关心信任并连续查看多个代理,您可能会像其他答案描述的那样采用更简单的方法。

首先,我们的应用程序必须支持查看由客户运行和维护的代理。在我们的应用服务器上,我们始终需要记住,请求可能会通过多个代理,而对于某些客户,我们实际上必须支持该用例,以便应用可以通过多个代理查看原始标头。

为了支持我们应用中的上游代理,我们有一个请求过滤器来分析X-Forwarded-For标头值以及远程主机IP。然后,我们将所有X-Forwarded-*代理标头值拆开并“解开”它们,前提是我们确定它们是由已通过合同建立标头配置的可信代理添加的(这些将是我们应用程序中特定的预配置IP) )。这个处理非常复杂,所以我会说它。但是,我们得到了:

  1. 代表所有“值得信赖的”远程IP的IP列表 在链中。
  2. 最“值得信赖的”原始标头值, 这将由应用程序用于生成URL等。
  3. 在我们的应用程序中,我们专门为HTTP / 2做的唯一工作是优化(例如,不连接JS文件),但代理链中的任何HTTP / 1.x连接都会阻碍性能。 因此我们只关心整个请求链是否从头到尾是HTTP / 2 。因此,我们已经要求所有支持HTTP / 2的上游代理实现我们发明的特殊标头,我们称之为H2-IP

    如果任何上游代理收到HTTP / 2请求,我们要求代理远程主机附加到H2-IP标头。然后,在服务器端,我们将遍历可靠的已配置代理(上面的#1)传递的可信任远程IP列表,并确保每个代理也列在H2-IP头中。

    例如:

    • 可信代理IP(预配置):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标题:23.45.67.78,11.22.33.44
    • X-Forwarded-Host标头:malicious.user.injected.value,app.customer.com,internalproxy.mycompany.com
    • X-Forwarded-Proto标题:http,https,https
    • H2-IP标题:23.45.67.78,11.22.33.44

    在此示例中,发现远程主机(10.20.30.40)是受信任的代理,我们通过合同知道此代理将发送所有三个X-Forwarded-(For | Host | Proto)标头。因此,我们从每个标头中取出最后一个值,使用那些未被剥离的值作为可信请求数据,然后我们为每个X-Forwarded-For IP重复该过程,直到我们找到一个不受信任的代理。以下是我们最终得到的数据:

    • 原始远程主机: 23.45.67.78
    • 原始主机标题: 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.

    如果您不关心信任并连续查看多个代理,您可以采用比其他答案描述的更简单的方法。

答案 2 :(得分:0)

proxy_set_header X-Forwarded-ProtoVersion $ server_protocol;

注意:X-Forwarded-ProtoVersion是一个组成变量的名称。我不知道标准是什么。