通过CLB四层监听获取客户端真实IP

传统型负载均衡CLB四层监听支持后端服务器获取客户端真实IP地址。通常情况下,无需操作,后端服务器即可获取客户端真实IP地址。但当客户端使用IPv6地址访问IPv4服务时,需要在CLB监听与后端服务器同时开启Proxy Protocol,后端服务器才可获取客户端真实IP地址。

获取方法介绍

image.png

直接获取

正常情况下,CLB四层监听通过源地址透传,在后端服务器上获取的源IP即为客户端真实IP地址。

部分特殊场景下,该功能无法使用,需要通过Proxy Protocol配置,后端服务器才能获取客户端真实IP地址,参见通过Proxy Protocol功能获取

通过Proxy Protocol功能获取

Proxy Protocol是一种通信协议,用于在代理服务器和后端服务器之间传递客户端的原始网络连接信息。

通常情况下,代理服务器在转发客户端请求到后端服务器时会重写请求头部,将客户端的源IP地址和端口等信息替换为代理服务器自身的信息。这样后端服务器就无法获得客户端的真实网络连接信息。

而使用Proxy Protocol,代理服务器在转发请求时将客户端的原始网络连接信息封装在请求头部中,发送给后端服务器。后端服务器通过解析Proxy Protocol头部,就可以获得客户端的真实网络连接信息,包括源IP地址、源端口以及传输协议等。

通过使用Proxy Protocol,后端服务器可以准确获取客户端的原始网络连接信息,从而进行更准确的日志记录、访问控制、流量监控等操作。

重要
  • 注意Proxy Protocol需要代理服务器和后端服务器都支持该协议才能正常使用。如果后端服务器不具备解析Proxy Protocol协议能力,直接打开特性开关,很可能会导致后端服务解析异常,从而影响服务可用性。

  • CLB四层监听支持通过Proxy Protocol携带原始连接信息(源IP、目的IP、源端口、目的端口等)并添加到TCP或UDP数据头中,且不会丢弃或覆盖任何原有数据。

  • CLB仅支持Proxy Protocol v2版本。Proxy Protocol v2版本支持多种传输协议,如TCP和UDP,更多信息,请参见The PROXY protocol

客户端使用IPv6地址访问CLB后端的IPv4服务场景下,需要在CLB四层监听及后端服务上开启Proxy Protocol来获取客户端真实IP地址。

操作步骤

直接获取

直接获取的场景下,可直接在后端服务器中获取客户端真实IP信息。

当Nginx作为后端服务器时,您可以通过检查Nginx日志来判断是否成功获取到了客户端的真实IP地址。

Nginx日志字段默认配置示例如下:

http {
  # 默认配置
  log_format  main  '$remote_addr- $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
	#...
}

Nginx日志文件默认路径为:/var/log/nginx/access.log

每行日志中第一个IP地址即为客户端真实IP地址。

image.png

通过Proxy Protocol功能配置

前提条件

  • 您已经创建CLB实例并为该实例添加了监听。本文以TCP监听、监听端口为80举例说明,具体操作,请参见创建和管理CLB实例添加TCP监听

  • 您已经创建可用的CLB服务器组并添加了后端服务器。本文以创建了虚拟服务器组、后端协议为TCP、后端服务器为ECS、后端部署的应用端口为80举例说明,具体操作,请参见创建和管理虚拟服务器组

    说明
    • 启用Proxy Protocol之前,请确保您的后端服务器支持Proxy Protocol v2版本,否则会导致新建连接失败。

    • Nginx Plus R16及以后版本或者开源Nginx 1.13.11及以后版本支持Proxy Protocol v2版本。

    • 如果实例的多个CLB监听挂载同一组后端服务器,必须将所有实例的监听都开启Proxy Protocol功能。

步骤一:为监听开启Proxy Protocol

  1. 登录传统型负载均衡CLB控制台

  2. 在顶部菜单栏,选择实例所属的地域。

  3. 实例管理页面,找到目标实例,单击实例ID。

  4. 在实例详情页面,单击监听页签,找到目标四层监听,单击监听ID。

  5. 在监听详情页面,查看到ProxyProtocol配置字段为通过ProxyProtocol协议携带客户端源地址到后端服务器。如果未显示该字段,可单击编辑监听在配置页面中开启该功能。

    重要

    该功能不支持在线平滑迁移,切换到Proxy Protocol需要业务停服升级,请谨慎配置。

步骤二:后端服务器开启Proxy Protocol

此处以CentOS 7.9操作系统、Nginx 1.20.1 版本配置为例介绍。具体请以您实际使用的环境为准。

  1. 登录后端服务器,执行nginx -t命令查看配置文件所在路径。默认通常为 /etc/nginx/nginx.conf,具体请以实际环境为准。

  2. 修改配置文件中的Proxy Protocol内容并保存,修改点可参考下方说明。

    http {
      # 确保设置$proxy_protocol_addr
      log_format  main  '$proxy_protocol_addr - $remote_addr- $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
      # 以80监听端口为例,增加proxy_protocol字段
      server {
        listen 80   proxy_protocol;
        #...
      }
    }
    
  3. 执行sudo nginx -s reload命令,重新加载Nginx配置文件。

步骤三:验证后端服务器获取客户端真实IP

当Nginx作为后端服务器时,您可以通过检查Nginx日志来判断是否成功获取到了客户端的真实IP地址。

Nginx日志文件默认路径为:/var/log/nginx/access.log

每行日志中,$proxy_protocol_addr变量对应的IP地址即为客户端真实IP地址。

image.png

Proxy Protocol v2报文结构参考

如您未使用上述示例中的服务器,您可参考Proxy Protocol v2报文结构及The PROXY protocol进行自定义解析,具体请参考您所使用的服务器的官方资料。

  • 携带客户端IPv4地址的Proxy Protocol v2二进制头格式如下所示:IPv4

  • 携带客户端IPv6地址的Proxy Protocol v2二进制头格式如下所示:IPv6

常见问题

为什么有100开头的IP在频繁访问ECS实例

负载均衡系统除了会通过系统服务器的内网IP将来自外部的访问请求转到后端ECS实例之外,还会对ECS实例进行健康检查和可用性监控,这些访问的来源都是由负载均衡系统发起的。

负载均衡系统的地址段为100.64.0.0/10(100.64.0.0/10是阿里云保留地址,其他用户无法分配到该网段内,不会存在安全风险),所以会有很多100开头的IP地址访问ECS实例。

为了确保您对外服务的可用性,请确保您的所有服务器均对上述地址的访问配置了安全组放行规则。

ACK场景下使用负载均衡时如何获取客户端真实IP

当您在ACK集群中使用负载均衡时,获取方式相同,具体操作有部分差异,具体操作请参考ACK容器集群Pod如何获取客户端真实IP?

相关文档

不同负载均衡类型获取客户端真实IP方式有所不同: