在负载均衡器或代理无法保留客户端原始 IP 地址的情况下,Proxy 协议 v2提供了一种有效的解决方案,通过在数据流中插入必要的客户端连接信息,确保后端服务能够掌握这些信息。无论是用于日志记录、监控,还是网络流量管理,Proxy协议都是一种提升安全性和可见性的好选择。
在青睐于使用负载均衡器或代理的场景中,若无法保留客户端的原始 IP 地址,系统可能会改写 IP 地址或者使用自身 IP地址进行路由。在这种情况下,广泛采用的做法包括将原始 IP 地址插入请求头(例如 X-Forwarded-For)或利用 来确保后端服务仍然可以访问到这些信息。 在第七层运行,利用 X-Forwarded-For HTTP 头将客户端 IP传递给目标。相比之下, 在第四层(TCP/UDP 层)运行,此时 Proxy 协议就展现出其优势。通过在代理头中编码所需的客户端详细信息,Proxy协议可以实现准确的日志记录、监控和网络流量管理,从而提升分布式环境下的安全性和可见性。
本文将探讨 如何与网络负载均衡器配合使用,学习其适当的使用场景,并部署一个 CloudFormation 模板,将网络负载均衡器置于 NGINX 或 HAProxy 服务器之前,使用 Proxy 协议 v2 保留客户端连接信息。
本文主要聚焦于 TCP 连接上的 Proxy 协议 v2,尽管同样支持 UDP。
Proxy 协议在 TCP 数据流的开头添加一个头部。当客户端与服务器建立 TCP 连接时,首先进行三次握手,随后数据流开始传输。Proxy 协议 v2头部将客户端连接的详细信息进行编码,并在三次握手后立即插入到数据流中,如图 1 所示。在 TLS 连接的情况下,Proxy 协议 v2 头部会在 TLS握手之前出现。

Proxy 协议 v2 与网络负载均衡器协作时,可能包含以下客户端连接信息:
字段名 | 说明 |
---|---|
源地址 | 发起连接的客户端原始 IP 地址 |
目标地址 | 接收连接的代理或负载均衡器的 IP 地址 |
源端口 | 连接发起方客户端使用的端口号 |
目标端口 | 连接指向的代理或负载均衡器一侧的端口号 |
协议 | 连接所用的网络协议(例如 TCP 或 UDP) |
版本 | 使用的 Proxy 协议版本(例如 v2) |
地址族 | 源和目标 IP 地址的地址族(例如 IPv4 或 IPv6) |
长度 | Proxy 协议头的长度 |
校验和 | 确保头部完整性的校验值 |
类型-长度-值(TLV) | 自定义数据(例如,虚拟私有云 (VPC) 终端 ID) |
这些详细信息编码在 Proxy 协议 v2头部中,由代理或负载均衡器使用,以准确传递客户端连接信息给后端服务器,从而使后端服务器能够保持对原始客户端连接的可见性。
虽然网络负载均衡器默认保留客户端 IP 地址,但某些情况可能会影响这一能力。如需详细信息,请参考我们的 。在以下情况中,网络数据包中保留客户端 IP地址可能不切实际或不可能,因此您可以使用 Proxy 协议 v2,以便您的目标应用需要了解客户端连接的详细信息。
在您启用代理协议之前,请确保您的应用能够解析 Proxy 协议 v2 头部,否则将会失败。
当目标位于网络负载均衡器 VPC 外部时,需要使用 IP 目标,这会自动停用客户端 IP 保留功能。这种情况与跨 VPC、混合云和多云架构相关。例如,网络负载均衡器可以部署用于管理位于本地的目标流量,如图 2 所示。

在网络安全和隐私方面, 是保护内部服务的广泛应用解决方案,同时允许多个消费者安全访问这些服务。它从 VPC 终端通过 AWS网络流向网络负载均衡器及其目标,形成单向流。然而,与任何安全措施一样,使用 PrivateLink 可能会带来一些权衡。当使用 PrivateLink时,客户端连接的详细信息会被隐藏,这使流量跟踪和管理变得复杂。通过 Proxy 协议 v2,不仅能够保留客户端 IP 地址,还能编码其他上下文信息,例如 VPC 终端 ID。此组合提供了 PrivateLink 流量来源的洞察,见图 3。

在此背景下,hairpinning 指客户端和目标均源自同一主机的流量,通过网络负载均衡器进行传输,如图 4所示。这种情况最有可能出现在运行容器化负载的环境中。由于处理客户端 IP 保留的方式,在通过网络负载均衡器进行 hairpinning流量时,连接可能会失败。停用客户端 IP 保留可以使得 hairpin 路由得以实现,但这会隐藏客户端 IP。您可以在此场景下使用 Proxy 协议 v2来保留客户端连接的详细信息。

接下来的部分,我们将执行以下步骤:
要开始实践演示,请访问 ,并使用 或
CloudFormation 模板来部署一个完整的网络负载均衡器和支持 Proxy 协议 v2 的目标环境。图 5 展示了 CloudFormation部署的结构。
在部署模板时,请将 ClientCIDR 参数的默认值(0.0.0.0/0)替换为您自己的 IP 地址。您可以通过访问网站 https://checkip.amazonaws.com 来查看您的公共 IP 地址。ClientCIDR参数用于安全组中,以限制对互联网可见的网络负载均衡器的访问。
请勿在生产环境中使用此 CloudFormation 模板。生产网络负载均衡器应部署在多个可用区中,并开启日志记录。

该模板设置了所有网络并部署了一个简单的 Web 应用程序,演示了如何在网络负载均衡器负载均衡流量时接收 Proxy 协议 v2 头部中的客户端详细信息。
模板执行的关键操作包括:
部署模板的过程需要几分钟,之后需要额外时间让 EC2 实例进行健康检查以激活。一旦变为可用状态,请使用模板生成的 URL(在已部署的堆栈的 输出 选项卡中获取 URL)访问一个展示客户端连接详细信息的网页。
连接后,您应该会看到一个类似于图 6 所示的网页。

现在,我们将使用协议分析器捕获并显示来自 EC2 实例命令行的 Proxy 协议 v2 头部内容。首先使用 连接到 CloudFormation模板部署的 EC2 实例。连接后,运行以下 tshark 命令以捕获和显示 Proxy 协议 v2 头部,如图 7 所示。
bash sudo tshark --disable-protocol http -VY proxy.v2.protocol==0x01

在协议分析器运行时,打开您的工作站上的网页浏览器或任何兼容 HTTP 的客户端,指向模板提供的 URL。例如,您可以选择使用 cURL,如下代码片段所示,替换 URL 为模板提供的 URL。
bash curl http://replace-me.elb.region.amazonaws.com/index.php
在 EC2 实例上,协议分析器应捕获并显示包含 Proxy 协议 v2 头部的网络数据包内容。见图 8 示例。输出省略以保持简洁。

最后,您将查看已配置为记录 Proxy 协议 v2 头部中发现的客户端 IP 地址的 Web 服务器访问日志。从 Web 服务器命令行运行如图 9 或图 10 中所示的命令。日志条目中不包含 IP 地址或包含您的网络负载均衡器 IP 地址的条目是健康检查,用于定期探测服务器,但不提供任何客户端连接详细信息。
一旦查看访问日志,从您的工作站连接到 URL 以生成新的日志条目。注意,访问日志中的源 IP 地址是来自 Proxy 协议 v2 头部所找到的地址。
图 9 和图 10 中显示的命令将在具有提升权限的情况下实时输出日志条目。确保根据您部署的 CloudFormation 模板使用正确的日志文件位置。
如果您部署了 NGINX,可以使用以下命令(输出见图 9):
bash sudo tail -f /var/log/nginx/access.log

如果您部署了 HAProxy,可以使用以下命令(输出见图 10):
bash sudo tail -f /var/log/haproxy/access.log

这次实践演示到此结束。尽管本文集中于 NGINX 和 HAProxy 作为网络负载均衡器的目标,但这些概念也适用于 Envoy、Traefik和其他类似的平台。大多数企业级代理和 Web 服务器支持 Proxy 协议 v2,但有些可能不支持。
完成后删除 CloudFormation 堆栈,以避免不必要的费用。
网络负载均衡器与 Proxy 协议 v2共同构成了一种协议无关的方法,以克服使用代理和负载均衡器时面临的保留客户端连接信息的挑战。通过在代理头中编码客户端详细信息,Proxy 协议 v2能够实现准确的日志记录、监控和网络流量管理,从而增强分布式环境中的安全性和可见性。
在本文中,我们深入探讨了 Proxy 协议 v2 的内部工作原理,探索了常见使用场景,并利用 CloudFormation模板进行了实践演示。掌握了这些知识和实践经验之后,您将更加自信地 。
![Ken Kitts](https://d2908q01vomqb2.cloudfront.net/5b384ce32d8cdef02bc3a139d4
Leave a Reply