导读:本期聚焦于苏沐橙创作的《CDN如何通过Proxy-Protocol将客户端真实IP和端口传递给源站?》,敬请观看详情。当业务流量经过CDN加速后,源站服务器上记录的访问IP往往会变成CDN节点的内部IP地址,这给风控拦截、日志审计以及地域限制等业务场景带来了极大的困扰。如何让源站准确获取到用户的真实IP和端口呢?Proxy-Protocol协议正是解决这一痛点的关键方案。它通过在TCP连接建立时,在HTTP请求头部之前插入一段包含源IP、目标IP及端口信息的二进制或文本数据,使得后端Nginx或HAProxy能够透明地解析出客户端的真实网络信息。本文将深入剖析Proxy-Protocol的工作机制,并详细讲解如何在主流Web服务器上配置该协议以正确接收客户端真实IP。

在构建高可用和高并发的Web架构时,CDN(内容分发网络)已经成为不可或缺的组件。它不仅能加速静态资源的分发,还能隐藏源站服务器的真实IP地址,从而有效抵御DDoS攻击。然而,这种架构也带来了一个显著的副作用:源站服务器接收到的TCP连接源IP地址全部变成了CDN节点的内部IP。对于需要进行精准地域访问控制、用户行为审计以及风控拦截的业务来说,丢失客户端真实IP是一个严重的痛点。为了解决这一问题,业界推出了Proxy-Protocol协议,它能够在不修改现有应用层协议(如HTTP、TLS)的前提下,将客户端的真实IP和端口信息透传给源站。

CDN如何通过Proxy-Protocol将客户端真实IP和端口传递给源站?

Proxy-Protocol协议的工作原理与版本差异

Proxy-Protocol是一种在网络代理和负载均衡领域广泛使用的协议,其核心目的是在代理服务器与后端服务器之间传递客户端的原始连接信息。传统的HTTP反向代理通常通过添加X-Forwarded-ForX-Real-IP等HTTP头部来实现这一目标,但这仅限于HTTP协议。当面对非HTTP协议(如数据库连接、SMTP邮件传输或纯TCP流)时,HTTP头部就无能为力了。Proxy-Protocol通过在TCP数据流的最前面插入一段额外的数据来解决这个问题,这段数据包含了客户端的源IP、源端口以及目标IP和目标端口。

该协议主要分为两个版本:版本1(v1)和版本2(v2)。版本1采用人类可读的文本格式,以PROXY字符串开头,后面紧跟TCP4或TCP6表示IPv4或IPv6,接着就是源IP、目标IP、源端口和目标端口,最后以CRLF结尾。这种格式易于调试,但会占用更多的网络带宽,且解析效率相对较低。版本2则采用了二进制格式,不仅大幅减少了头部数据的大小,提升了解析性能,还支持UDP协议和Unix域套接字。在实际的CDN配置中,通常建议优先使用版本2以获得更好的性能和兼容性。

Proxy-Protocol的工作机制非常精巧。当客户端与CDN节点建立TCP连接后,CDN节点不会立即将应用层数据(如HTTP请求)转发给源站。相反,它会先构造一个包含客户端真实网络信息的Proxy-Protocol头部,并将其作为TCP流的第一个数据包发送给源站。源站服务器在接收到连接后,首先读取并解析这个特殊的头部,剥离出真实IP和端口,然后再将后续的数据流交给上层的应用服务(如Nginx、HAProxy)进行处理。这种机制对应用层是完全透明的,不需要修改现有的业务代码。

Nginx源站接收并解析真实IP的配置实践

Nginx作为最流行的Web服务器之一,对Proxy-Protocol提供了良好的原生支持。要让Nginx正确解析CDN传递过来的真实IP,需要在配置文件中进行相应的设置。首先,在server块或http块的listen指令中添加proxy_protocol参数,告知Nginx该监听端口将接收带有Proxy-Protocol头部的连接。同时,需要使用set_real_ip_from指令将CDN节点的IP地址段设置为受信任的来源,这样Nginx才会尝试从Proxy-Protocol头部中提取真实IP并覆盖连接的源IP。

下面是一个典型的Nginx配置示例。在这个示例中,我们不仅开启了proxy_protocol,还使用了real_ip_header指令来指定从哪个字段获取真实IP。对于Proxy-Protocol,Nginx会自动解析头部,因此只需配置信任的代理IP段即可。需要注意的是,如果CDN节点和源站之间是通过HTTPS(TLS)连接的,还需要在listen指令中同时加上ssl和proxy_protocol参数,并正确配置证书。

http {
    # 设置信任的CDN回源IP段,请根据实际CDN服务商提供的IP段进行替换
    set_real_ip_from 192.168.1.0/24;
    set_real_ip_from 10.0.0.0/8;
    
    # 告诉Nginx从Proxy-Protocol头部获取真实IP
    real_ip_header proxy_protocol;
    
    server {
        # 监听443端口,开启SSL和Proxy-Protocol支持
        listen 443 ssl proxy_protocol;
        server_name www.ipipp.com;
        
        # SSL证书配置
        ssl_certificate     /etc/nginx/ssl/server.crt;
        ssl_certificate_key /etc/nginx/ssl/server.key;
        
        location / {
            proxy_pass http://backend_server;
            # 将解析出的真实IP传递给后端应用
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}

在配置过程中,有一个常见的误区需要特别注意:如果CDN端开启了Proxy-Protocol而源站Nginx没有配置相应的接收参数,或者源站配置了接收参数但CDN端没有发送,都会导致连接握手失败或HTTP请求解析报错。因为Nginx会把Proxy-Protocol的头部数据当作普通的HTTP请求数据来解析,从而返回400 Bad Request错误。因此,在上线前必须确保两端配置的一致性,并且建议在CDN控制台配置回源IP段白名单,防止恶意用户直接绕过CDN伪造Proxy-Protocol头部攻击源站。

HAProxy与四层负载均衡场景下的应用

在更复杂的网络架构中,源站前端往往会部署一层四层负载均衡器(L4 Load Balancer),如HAProxy或LVS。四层负载均衡基于IP和端口进行转发,无法像七层负载均衡那样修改HTTP头部。在这种场景下,Proxy-Protocol的优势更加明显,因为它工作在传输层之上、应用层之下,非常适合在四层代理链路中透传客户端信息。

以HAProxy为例,它既可以作为发送Proxy-Protocol头部的客户端,也可以作为接收和解析该头部的服务端。当HAProxy作为前端负载均衡器接收来自CDN的流量时,需要在backend配置中开启accept-proxy参数,使其能够解析CDN发送过来的Proxy-Protocol头部。随后,当HAProxy将流量转发给后端的Nginx应用服务器时,它又可以再次通过send-proxy参数将解析出的真实IP信息以Proxy-Protocol格式发送给后端,从而形成一条完整的真实IP透传链路。

frontend cdn_incoming
    bind *:80
    # 接收来自CDN的Proxy-Protocol头部
    accept-proxy
    default_backend nginx_servers

backend nginx_servers
    balance roundrobin
    server nginx1 192.168.2.10:80 check
    server nginx2 192.168.2.11:80 check
    # 向后端Nginx发送Proxy-Protocol头部
    send-proxy

在多层代理架构中,Proxy-Protocol的链式传递需要特别注意性能损耗和兼容性问题。每一次代理节点的解析和重新封装都会消耗一定的CPU资源。虽然版本2的二进制格式已经极大地优化了解析效率,但在极高并发的场景下,仍然需要评估服务器的处理能力。此外,并非所有的四层负载均衡设备和云服务商都支持Proxy-Protocol,因此在设计架构时需要确认链路中所有节点都具备处理该协议的能力。如果中间某一层不支持,可能会导致连接中断,此时需要考虑退回到传统的HTTP层透传方案,或者在不支持的节点上终止Proxy-Protocol并转换为其他传递方式。

CDNProxy-Protocol源站配置修改时间:2026-08-28 21:52:48

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。