一、啥是多层代理IP传递问题

在咱们做开发或者运维的时候,经常会碰到多层代理的情况。啥叫多层代理呢?简单来说,就是一个请求要经过好几个代理服务器才能到达目标服务器。比如说,用户的请求先到了 CDN 服务器,CDN 服务器再把请求转发给负载均衡器,负载均衡器又把请求转发给真正的应用服务器。

这时候就会出现一个问题,应用服务器拿到的请求 IP 地址,是最后一个代理服务器的 IP 地址,而不是用户的真实 IP 地址。这就麻烦了,因为很多时候我们需要知道用户的真实 IP 地址,比如做访问控制、统计分析啥的。这就是多层代理的 IP 传递问题。

举个例子吧,假如有个网站,用户通过 CDN 访问。网站的应用服务器想记录每个用户的 IP 地址来分析用户的来源。但是因为经过了 CDN 代理,应用服务器拿到的都是 CDN 服务器的 IP 地址,根本不知道用户的真实 IP,这样统计出来的数据就没啥用了。

二、Nginx 的 proxy_protocol 是啥

Nginx 是一款很强大的 Web 服务器和反向代理服务器。而 proxy_protocol 是 Nginx 提供的一个功能,它可以解决多层代理的 IP 传递问题。

简单来讲,proxy_protocol 允许代理服务器在转发请求的时候,把客户端的真实 IP 地址和端口号等信息放在一个特殊的头部里传递给下一个服务器。这样,目标服务器就能拿到客户端的真实 IP 地址了。

比如说,CDN 服务器在把请求转发给负载均衡器的时候,就可以使用 proxy_protocol 把用户的真实 IP 地址和端口号放在请求头部,负载均衡器再把这个请求转发给应用服务器,应用服务器就可以从这个特殊头部里获取到用户的真实 IP 地址。

三、proxy_protocol 配置示例(Nginx 技术栈)

下面我们来看看具体的配置示例。

1. 后端服务器配置

假设我们有一个后端的 Web 服务器,使用 Nginx 作为 Web 服务器,我们要让它支持 proxy_protocol。

# 开启 proxy_protocol 监听
server {
    listen 80 proxy_protocol;  # 监听 80 端口,开启 proxy_protocol
    server_name example.com;

    location / {
        # 获取客户端真实 IP 地址
        set_real_ip_from 0.0.0.0/0;  # 设置允许的代理服务器 IP 范围,这里设置为所有 IP,实际使用中要根据情况修改
        real_ip_header proxy_protocol;  # 指定从 proxy_protocol 头部获取真实 IP 地址

        root /var/www/html;
        index index.html;
    }
}

在这个配置里,listen 80 proxy_protocol; 表示监听 80 端口,并且开启 proxy_protocol 功能。set_real_ip_from 0.0.0.0/0; 是设置允许的代理服务器 IP 范围,这里设置为所有 IP,实际使用中要根据情况修改。real_ip_header proxy_protocol; 是指定从 proxy_protocol 头部获取真实 IP 地址。

2. 代理服务器配置

现在我们有一个代理服务器,也要使用 Nginx,把请求转发给后端服务器,并且使用 proxy_protocol 传递客户端的真实 IP 地址。

# 代理服务器配置
server {
    listen 80;
    server_name proxy.example.com;

    location / {
        proxy_pass http://backend_server_ip:80;  # 转发请求到后端服务器
        proxy_protocol on;  # 开启 proxy_protocol
    }
}

在这个配置里,proxy_pass http://backend_server_ip:80; 是把请求转发到后端服务器的 80 端口。proxy_protocol on; 是开启 proxy_protocol 功能,这样在转发请求的时候,就会把客户端的真实 IP 地址和端口号放在 proxy_protocol 头部传递给后端服务器。

四、应用场景

1. 网站访问统计

很多网站都需要统计用户的访问信息,比如用户的 IP 地址、访问时间、访问页面等。通过使用 proxy_protocol 传递真实的用户 IP 地址,网站的统计系统就能准确地统计出每个用户的访问信息,从而为网站的运营和优化提供数据支持。

2. 访问控制

有些网站会根据用户的 IP 地址进行访问控制,比如只允许特定地区的用户访问。如果没有使用 proxy_protocol,网站拿到的是代理服务器的 IP 地址,就无法准确地进行访问控制。使用 proxy_protocol 后,网站就能拿到用户的真实 IP 地址,从而实现精准的访问控制。

3. 安全审计

在进行安全审计的时候,需要知道每个请求的真实来源。通过 proxy_protocol 传递真实的用户 IP 地址,安全审计系统就能准确地追踪每个请求的来源,从而及时发现和处理安全问题。

五、技术优缺点

优点

  • 准确传递真实 IP:这是最主要的优点,通过 proxy_protocol 可以确保目标服务器拿到客户端的真实 IP 地址,解决了多层代理的 IP 传递问题。
  • 兼容性好:proxy_protocol 是一个通用的协议,很多代理服务器和 Web 服务器都支持这个协议,比如 Nginx、HAProxy 等。
  • 配置简单:在 Nginx 里配置 proxy_protocol 很简单,只需要添加几行配置代码就可以了。

缺点

  • 增加网络开销:使用 proxy_protocol 会在请求头部添加额外的信息,这会增加网络传输的开销,尤其是在高并发的情况下,可能会对性能产生一定的影响。
  • 需要代理服务器支持:要使用 proxy_protocol,所有的代理服务器都必须支持这个协议,否则就无法正常传递真实的 IP 地址。

六、注意事项

1. 代理服务器配置

在使用 proxy_protocol 时,所有的代理服务器都必须正确配置。如果有一个代理服务器没有开启 proxy_protocol 功能,就会导致真实的 IP 地址无法传递到目标服务器。

2. 安全性

因为 proxy_protocol 头部包含了客户端的真实 IP 地址和端口号等信息,所以要注意保护这些信息的安全。可以通过设置允许的代理服务器 IP 范围,只允许信任的代理服务器传递 proxy_protocol 头部。

3. 性能优化

在高并发的情况下,使用 proxy_protocol 可能会对性能产生一定的影响。可以通过优化服务器配置、使用负载均衡等方式来提高性能。

七、文章总结

多层代理的 IP 传递问题是开发和运维中经常会碰到的问题,而 Nginx 的 proxy_protocol 功能可以很好地解决这个问题。通过在代理服务器和目标服务器上进行简单的配置,就可以让目标服务器拿到客户端的真实 IP 地址。

proxy_protocol 有很多应用场景,比如网站访问统计、访问控制、安全审计等。它的优点是准确传递真实 IP、兼容性好、配置简单,缺点是增加网络开销、需要代理服务器支持。在使用 proxy_protocol 时,要注意代理服务器的配置、信息的安全和性能优化等问题。