Node.js(net模块)代理如何将客户端真实IP转发到远端主机
代理服务透传客户端原始IP实现方案
你当前使用的是普通四层TCP转发逻辑,代理服务器与远端主机建连时默认使用自身出口IP作为源地址,因此远端只能获取到代理服务器的IP。要实现客户端IP透传,可根据你的场景选择以下三类方案:
方案1:TPROXY透明代理(IP层完全透传)
该方案可以实现IP层的源IP完全透传,远端主机在网络层直接看到客户端的原始IP,完全感知不到代理存在。
- 适用前提:
- 代理服务器为Linux系统,内核开启TPROXY支持
- 你拥有代理服务器的路由、iptables配置权限
- 远端主机的回程流量必须经过代理服务器
- 配置步骤:
- 配置iptables规则和路由表,标记需要透传的流量,将回程流量路由到代理服务器
- 代码中新增对应逻辑
- 代码修改示例:
const clientIP = data.remoteAddress const clientPort = data.remotePort // 开启IP透明选项 socket.setOption('IP_TRANSPARENT', 1) // 绑定到客户端原始IP端口 socket.bind({ address: clientIP, port: clientPort }, () => { socket.connect(parseInt(destport), destip, function () { socket.on('data', (proxy_client_data) => { data.write(proxy_client_data) }) data.on('data', (client_proxy_data)=> { socket.write(client_proxy_data) }) }) })
- 局限性:仅适合内网部署、或代理服务器拥有自治域IP路由权限的场景,公网部署时运营商通常会拦截源IP非本网段的出站包。
方案2:PROXY协议透传(四层通用方案)
该方案是目前反向代理场景最常用的透传方案,无需修改内核配置,仅需要代理和远端服务同时支持PROXY协议即可。
- 实现逻辑:代理在转发真实业务数据前,先向远端发送一段包含客户端源IP、源端口、代理IP、代理端口信息的协议头,远端服务解析该头即可获取原始客户端IP。
- 适用前提:远端服务支持PROXY协议解析(Nginx、HAProxy、Apache等主流服务均原生支持,自定义服务可以引入对应解析库)
- 代码修改示例:
const clientIP = data.remoteAddress const clientPort = data.remotePort const proxyIP = socket.localAddress socket.connect(parseInt(destport), destip, function () { // 先写入PROXY v1协议头,TCP4场景格式为PROXY TCP4 客户端IP 代理IP 客户端端口 目标端口\r\n socket.write(`PROXY TCP4 ${clientIP} ${proxyIP} ${clientPort} ${destport}\r\n`) // 后续业务数据正常转发 socket.on('data', (proxy_client_data) => { data.write(proxy_client_data) }) data.on('data', (client_proxy_data)=> { socket.write(client_proxy_data) }) })
方案3:HTTP头部透传(仅适用七层HTTP/HTTPS场景)
如果你的代理仅处理HTTP/HTTPS流量,可以直接在请求头中新增透传字段,远端应用读取对应字段即可获取客户端IP。
- 实现逻辑:拦截HTTP请求头,新增
X-Forwarded-For、X-Real-IP字段填入客户端原始IP - 局限性:仅能在应用层获取到原始IP,网络层看到的源IP仍为代理服务器IP;HTTPS场景需要代理完成TLS解密才能修改请求头。
内容的提问来源于stack exchange,提问作者danky
相关产品推荐
相关产品推荐

