如何为 AutoScale 实例使用 AWS 负载均衡器代理协议?

Posted

技术标签:

【中文标题】如何为 AutoScale 实例使用 AWS 负载均衡器代理协议?【英文标题】:How to use AWS LoadBalancer ProxyProtocol for AutoScale instances? 【发布时间】:2015-12-12 23:28:23 【问题描述】:

我安装了带有 ELB 的 AWS AutoScale。一般来说,部署在 AutoScale 的 EC2 实例上的 API 成功地从负载均衡器获取请求,并且对客户端的响应正常。但是,现在我开发了一个需要客户端 IP 地址的新 API。在当前设置中,Loadbalancer 会更改源 IP 地址。

我已经浏览了这个文档http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/enable-proxy-protocol.html,我知道使用代理协议是可能的

我已使用此 AWS CLI 命令创建了策略

aws elb create-load-balancer-policy --load-balancer-name LB-autoscale --policy-name my-ProxyProtocol-policy --policy-type-name ProxyProtocolPolicyType --policy-attributes AttributeName=ProxyProtocol,AttributeValue=true

问题:如何为 AutoScale 组自动创建的后端 EC2 服务器设置此负载均衡器策略?所以每当自动缩放组启动一个新的 EC2 实例时,应该为该实例启用 proxyProtocol,并且部署在该实例上的 API 应该获取 Client 的原始 IP。

【问题讨论】:

【参考方案1】:

应该为该实例启用代理协议

您提出的问题的问题是您没有“在实例上”启用代理协议。

实例上运行的网络服务器软件必须理解代理协议,并且必须配置软件以使用它。

例如在nginx web服务器中,而不是这个...

server 
    listen 80;
...

...你会用这个...

server 
    listen 80 proxy_protocol;
...

...$proxy_protocol_addr 内置变量将包含客户端 IP,您可以使用它来设置标头以将地址传递给下游服务。

根据标准,如果服务需要代理协议前导码,则需要拒绝任何不包含它的请求。

必须将接收器配置为仅接收本文中描述的协议 规范并且不得尝试猜测协议头是否存在 与否。

http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt

这意味着配置为使用代理协议的兼容服务在没有它的情况下无法工作,而配置为不使用它(或不知道/不兼容)的服务最多应该忽略它,并且最常见的是完全失败,因为负载将是意外的。

因此,如果没有您的堆栈支持,代理协议将无法为您工作。它不是由实例或任何 AWS 组件在您这边处理的。

另一方面,对于 Web 服务 API,您通常不需要它。

HTTP 模式下的弹性负载均衡器会在每个请求中注入一个 X-Forwarded-For 标头,其中包含客户端的 IP 地址。大多数应用程序似乎都使用这种机制。

如果传入的请求已经有这样的标头,客户端 IP 地址将附加到末尾,值以逗号分隔。当您的代码找到多个值时,应该只信任最右边的值,并且应该将其左侧的值视为“仅供参考”——它们可能是准确的,并且可能是伪造的……但最后一个不能被篡改。

【讨论】:

以上是关于如何为 AutoScale 实例使用 AWS 负载均衡器代理协议?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 ECS 添加带有应用程序负载均衡器的 AWS API 网关?

如何为我的 Elastic Beanstalk Java 应用程序启用 HTTPS?

当您的实例位于 ELB 之后时,您如何为 AWS 建立维护页面?

如何为 AWS RDS 实例设置数据库时区 [重复]

Celery:AWS ECS Autoscale 缩减事件(如何不破坏长时间运行的任务?)

AWS:如何为 Auto Scaling 组计算 CPU 利用率