Elastic Load Balancing 非终止 SSL 连接上的代理协议

Posted

技术标签:

【中文标题】Elastic Load Balancing 非终止 SSL 连接上的代理协议【英文标题】:Proxy Protocol on Elastic Load Balancing non-terminated SSL connection 【发布时间】:2014-03-31 12:56:02 【问题描述】:

由于我们不打算更改的原因,我们的应用程序需要处理 SSL 连接,而不是 ELB。使用代理协议的目的是通过 SSL 连接获取客户端的 IP 地址。

http://aws.typepad.com/aws/2013/07/elastic-load-balancing-adds-support-for-proxy-protocol.html?ref_=9 表示“或者,如果您正在发送 HTTPS 请求并且不想终止负载均衡器上的 SSL 连接,则可以使用它。有关更多信息,请访问Elastic Load Balancing Guide。”

不幸的是,链接到的指南似乎并没有真正详细说明这一点,并且代理协议的基本文档 (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/enable-proxy-protocol.html) 在我们的环境中按照描述进行配置时失败。

谁有这方面的步骤或链接?

【问题讨论】:

【参考方案1】:

在您的服务器协商 SSL 之前,代理协议(版本 1)在连接开始时将单行注入数据流。您不会“通过” SSL 连接获得此信息;您在 SSL 握手之前获得信息。您的服务器必须实现此功能并进行专门配置,以便它可以接受和理解它。对于 IPv4 连接,它看起来像这样:

PROXY TCP4 source-ip dest-ip source-port dest-port\r\n

协议的标准在这里:

http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt

ELB 文档中的其他信息:

http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/TerminologyandKeyConcepts.html#proxy-protocol


关于 Apache 支持,至少在 AWS 宣布支持代理协议时...

Apache 和 nginx 目前都不支持 ELB 插入的代理协议头

——http://aws.typepad.com/aws/2013/07/elastic-load-balancing-adds-support-for-proxy-protocol.html?ref_=9

当然,这可能会发生变化,但我没有成功通过谷歌搜索任何 Apache 对代理协议的支持。当然,由于 Apache 是开源的,你大概可以在其中破解它,尽管我不熟悉 Apache 源代码。

意识到你不想改变你现在正在做的事情,我仍然建议根据你不想改变的动机,可能仍然有一个相对简单的解决方案。这是一个变化,但不涉及 ELB 上的 SSL。在 ELB 后面运行 HAProxy 来终止 Apache 前面的 SSL 怎么样?由于 HAProxy 1.5 可以终止 SSL 并且 appears to be able to 将 ELB 中的代理协议字符串转换为 X-Forwarded-For 标头,并生成 X-SSL 标头以向您的应用程序提供有关客户端 SSL 证书的信息(也许这就是您终止 SSL 的动机在应用服务器上而不是在 ELB 上?)...所以这可能是一个替代方案。

否则,除非 Apache 将来实现支持,否则我没有建议,或者我们可以找到一些文档表明他们已经有了。

【讨论】:

感谢您的回答。我想我真正的问题是是否可以修改 Apache 以容纳额外的字符串,如果可以,如何? @conrad10781 我不确定,但我在答案中添加了一些额外的信息,希望它至少有用。 仅供参考,nginx 现在支持代理协议:nginx.org/en/docs/http/ngx_http_realip_module.html【参考方案2】:

对于允许您的应用程序服务器终止 TLS 连接的较新的Network Load Balancers,您仍然可以获得客户端的真实 IP 地址,并避免在 ELB 和 Web 服务器配置中配置代理协议的所有工作只需 configuring the target groups to use the servers' instance ids 而不是他们的 IP 地址。无论您使用哪个 Web 服务器,客户端的真实 IP 都会显示在日志中,无需翻译。

只是跟进 Michael - sqlbot 的回答,讨论 AWS support for proxy protocol on EC2 instances behind classic TCP elastic load balancers,实现代理协议的 Apache 模块是 mod_remoteip。启用它并正确更新配置将纠正记录用户 IP 地址而不是弹性负载均衡器 IP 的问题。

要在弹性负载均衡器上启用代理协议,您可以使用aws documentation 中描述的这些 aws cli 命令:

aws elb create-load-balancer-policy --load-balancer-name my-elb-name --policy-name my-elb-name-ProxyProtocol-policy --policy-type-name ProxyProtocolPolicyType --policy-attributes AttributeName=ProxyProtocol,AttributeValue=true
aws elb set-load-balancer-policies-for-backend-server --load-balancer-name my-elb-name --instance-port 443 --policy-names my-elb-name-ProxyProtocol-policy
aws elb set-load-balancer-policies-for-backend-server --load-balancer-name my-elb-name --instance-port 80 --policy-names my-elb-name-ProxyProtocol-policy

要在 apache、服务器范围或 VirtualHost 上下文中启用代理协议,请遵循 mod_remoteip documentation,如下所示:

<IfModule mod_remoteip.c>
  RemoteIPProxyProtocol On
  RemoteIPHeader X-Forwarded-For
  # The IPs or IP range of your ELB:
  RemoteIPInternalProxy 192.168.1.0/24
  # The IPs of hosts that may need to connect directly to the web server, bypassing the ELB (if applicable):
  RemoteIPProxyProtocolExceptions 127.0.0.1
</IfModule>

您需要更新 LogFormat 以使用 %a 而不是 %h 的任何定义(例如 httpd.conf),否则负载平衡器 IP 地址仍会出现。

【讨论】:

以上是关于Elastic Load Balancing 非终止 SSL 连接上的代理协议的主要内容,如果未能解决你的问题,请参考以下文章

AWS Cloudformation Elastic Load Balancing 账户 ID

Elastic Load Balancing 非终止 SSL 连接上的代理协议

AWS Elastic Load Balancing 和 Auto Scaling 之间的区别

Aws Elastic Load Balancing 安全组不允许入站调用

如何知道我是不是需要使用 AWS Elasticache 和 AWS Elastic Load Balancing?

gRPC Load Balancing