当前位置: 首页 > 知识库问答 >
问题:

AWS 负载均衡/电子负载均衡 HTTP/2 支持

蒋向笛
2023-03-14

目标是在一个简单的堆栈中包含 HTTP/2 支持:在多个 EC2 实例中部署的 Web 应用程序是启用了 PROXY 协议策略 (SSL:443 ➝ TCP:80) 的传输级 CLB,以便卸载 SSL/TLS 并平衡传入的 HTTPS 流量。

PROXY协议的几个原因:(1)地理定位逻辑的执行;(2)执行简单的访问控制规则;(3)日志记录。所有这些功能都需要访问可靠的(即不可轻易伪造的)客户端IP地址。在 AWS 中,PROXY 协议的唯一替代方案是切换到应用程序级平衡,并使用 XFF 标头提取客户端的远程 IP 地址。然而,这是不可接受的:任何人都可以简单地更改其IP地址,只需在传入的HTTPS请求中注入一个假的XFF标头即可。AFAIK、AWS 克隆银行/ELB 不会注入包含客户端远程 IP 的标头(例如,类似于 Akamai 中的真客户端 IP 标头)。

因此,如何将H2支持添加到堆栈中?经过一些研究,所有可能的选项看起来都不令人满意:

>

  • 当前体系结构无效,因为SSL/TLS在CLB中终止,但CLB不提供任何选项来通过ALPN宣布H2支持。

    使用CLB的替代方法是停止使用SSL/TLS卸载功能,并将其移动到EC2实例(即TCP:443➝ TCP:443)。这样,可以在SSL/TLS握手期间宣布H2支持,但此选项需要升级EC2实例以支持额外的SSL/TSL工作负载。类似备选方案:

    • TCP:443 ➝ SSL:443:类似于 TCP:443 ➝ TCP:443,但允许使用可信公钥证书列表进行后端身份验证。
    • SSL:443 ➝ SSL:443:类似于 TCP:443 ➝ SSL:443 的端到端加密。不是一个真正的选项:(1)这种组合不支持 PROXY协议(使用XFF也不是一个选项,因为这是传输级平衡);和 (2) 客户端 SSL/TLS 握手在 CLB 中执行,因此 H2 不会公布。

    另一种选择是用 ELB(HTTPS ➝ HTTP)替换CLB。弹性负载均衡支持 H2。但是(1)我们需要依靠XFF来提取客户端IP地址(已经解释了为什么这是一个问题);和 (2) ELB 和 EC2 实例之间的流量将为 H1 (我们希望让未加密的 H2 流量到达 EC2 实例)。换句话说,这不是一种选择。

    综上所述,所有选项都有问题。IMHO理想的解决方案是保留原来的CLB(SSL:443 TCP:80;平衡SSL/TLS卸载代理协议)并允许在CLB启用策略以通过ALPN宣布H2支持。然而,恐怕这在AWS中是不可能的。CLB TCP:443方法的任何替代方案?

  • 共有1个答案

    云京
    2023-03-14

    这个答案并没有提供一个绝妙的解决方案,因为可能没有,但我相信您对AWS应用型负载均衡(ALB,也称为ELB/2.0)的理解存在差距。

    任何人都可以通过简单地在传入的HTTPS请求中注入一个假的XFF报头来轻易改变其IP地址。AFAIK、AWS clb/elb不注入包含客户端远程IP的报头

    这两种说法都不正确。

    客户端的远程IP是< code>X-Forwarded-For中最右边的IP地址,由平衡器发送给实例。这是不能被欺骗的。如果客户机在XFF中包含一个或多个地址,那么根据处理HTTP头的规则(从左到右,从第一个到最后一个),它们被平衡器规范化为一个头,并且出现在实际客户机IP的左侧。

    示例请求:我在请求中注入了两个伪造的< code>X-Forwarded-For头,一个有2个值,一个有1个值...以下是curl发送的内容:

    $ curl -v http://cx-xxxxxxxx-xxxx-xxxxxxxxxx.us-east-1.elb.amazonaws.com/test/dump/headers \
           -H 'X-Forwarded-For: 192.168.254.252, 10.10.10.10' \
           -H 'X-Forwarded-For: 172.16.16.16'
    * Hostname was NOT found in DNS cache
    *   Trying 52.x.x.x...
    * Connected to cx-xxxxxxxx-xxxx-xxxxxxxxxx.us-east-1.elb.amazonaws.com (52.x.x.x) port 80 (#0)
    > GET /test/dump/headers HTTP/1.1
    > User-Agent: curl/7.35.0
    > Host: cx-xxxxxxxx-xxxx-xxxxxxxxxx.us-east-1.elb.amazonaws.com
    > Accept: */*
    > X-Forwarded-For: 192.168.254.252, 10.10.10.10
    > X-Forwarded-For: 172.16.16.16
    >
    < HTTP/1.1 200 OK
    

    但我的实例显示:

    GET /test/dump/headers HTTP/1.1
    X-Forwarded-For: 192.168.254.252, 10.10.10.10, 172.16.16.16, 203.0.113.1
    X-Forwarded-Proto: http
    X-Forwarded-Port: 80
    Host: cx-xxxxxxxx-xxxx-xxxxxxxxxx.us-east-1.elb.amazonaws.com
    X-Amzn-Trace-Id: Root=1-58d0704b-557517de784f5exxxxxxxxxx
    User-Agent: curl/7.35.0
    Accept: */*
    

    我发送的头已经被平衡器规范化,并且< code>X-Forwarded-For中最右边的值已经被平衡器添加——它是我运行curl的机器的IP地址,它建立了传入的连接。

    这就是ALB的工作原理。如果客户机提供了任何XFF,那么它们当然是不受信任的(尽管您仍然应该记录或保存它们,因为如果客户机使用的代理正确标识了客户机,那么它们可能会很有用),但右侧的最后一个地址始终是从外部建立到您的ALB连接的外部机器的地址。

    您总是以这种方式解释< code>X-Forwarded-For: -从头的底部,向上,然后从右到左,因为这是任何行为正常的代理(在本例中是ALB)处理它们的方式-通过将其客户端的IP地址(从其网络堆栈中报告)附加到右侧(或通过在任何其他头之后添加额外的< code>X-Forwarded-For头-这两种方式在语义上都是有效的,但ALB不使用后一种方法)。解析时,当你遇到第一个不是你自己的地址时,你就停下来——那是你唯一可以信任的地址。

    此外,如果客户端在使用超文本传输协议连接时注入X-Forwarded-Proto: https——试图欺骗已经与平衡器建立了安全连接,而实际上他们并没有建立这样的连接——ALB会丢弃它。实例只看到真相:X-Forwarded-Proto:超文本传输协议

    此外,您可能会忽略这样一个事实,即在使用HTTP/1.1连接到实例时,平衡器还会做一些非常有用的事情:

    您可以将HTTP/2与HTTPS侦听器一起使用。您可以使用一个HTTP/2连接并行发送多达128个请求。负载均衡器将这些请求转换为单个HTTP/1.1请求,并使用循环路由算法将它们分布在目标组中的健康目标上。

    http://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html

    据我估计,这种能力将负载平衡的概念提升到了一个全新的水平。

    ¹我运行curl的机器的IP地址。敏锐的观察者会注意到,这实际上是RFC-5737中的一个IP地址,但它被报告给实例作为我在家的IP地址。我没有改变实例所看到的请求标头,除非是出于清理目的。否则,这里的原始顺序和内容都被精确地保存了下来。

     类似资料:
    • 负载均衡(Load balancing)是一种计算机网络技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最佳化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。 使用带有负载均衡的多个服务器组件,取代单一的组件,可以通过冗余提高可靠性。负载均衡服务通常是由专用软体和硬件来完成。 负载均衡最重要的一个应用是利用多台服务器提供单一服务,这种方案有

    • 负载均衡包括负载均衡实例、访问控制及证书。 实例 负载均衡实例是一个运行的负载均衡服务,通过设置的虚拟IP接收流量并将其转发分配给后端服务器。 访问控制 访问控制用于设置访问负载均衡的IP白名单或IP黑名单。 证书 当在负载均衡实例上配置HTTPS监听转发来自HTTPS协议的请求时,需要配置证书。

    • 一个简单的负载均衡的示例,把www.domain.com均衡到本机不同的端口,也可以改为均衡到不同的地址上。> http { : upstream myproject { : server 127.0.0.1:8000 weight=3; : server 127.0.0.1:8001; : server 127.0.0.1:8002; : server 127.0.0.1:8003; : }

    • SOFARPC 提供多种负载均衡算法,目前支持以下五种: 类型 名称 描述 random 随机算法 默认负载均衡算法。 localPref 本地优先算法 优先发现是否本机发布了该服务,如果没有再采用随机算法。 roundRobin 轮询算法 方法级别的轮询,各个方法间各自轮询,互不影响。 consistentHash 一致性hash算法 同样的方法级别的请求会路由到同样的节点。 weightRou

    • 本节将会讨论常见的分布式系统负载均衡手段。 6.5.1 常见的负载均衡思路 如果我们不考虑均衡的话,现在有n个服务节点,我们完成业务流程实际上只需要从这n个中挑出其中的一个。有几种思路: 按顺序挑: 例如上次选了第一台,那么这次就选第二台,下次第三台,如果已经到了最后一台,那么下一次从第一台开始。这种情况下我们可以把服务节点信息都存储在数组中,每次请求完成下游之后,将一个索引后移即可。在移到尽头时

    • 当过滤器需要获取到上游群集中的主机连接时,群集管理器使用负载平衡策略来确定选择哪个主机。负载平衡策略是可插入的,并且在配置中以每个上游集群为单位进行指定。请注意,如果没有为群集配置积极的健康检查策略,则所有上游群集成员都被视为健康。 支持的负载平衡策略 轮训 这是一个简单的策略,每个健康的上游主机按循环顺序选择。 权重最小请求 请求最少的负载均衡器使用O(1)算法来选择两个随机的健康主机,并选择活