当前位置: 首页 > 知识库问答 >
问题:

当使用Cloudflare Worker作为代理时,是否有任何方法可以传递原始客户端IP?

狄富
2023-03-14

我有一个Cloudflare Worker,它充当我的应用程序的代理。我需要这样做,因为Cloudflare使用curl或任何HTTP请求库来阻止外部请求。因此,在Cloudflare网络中,我可以绕过http://icanhazip.com/的Cloudflare验证。

问题是,当我将Cloudflare worker配置为代理并在我的请求库Python代码中使用它时,页面得到了它的真实内容,但是http://icanhazip.com/显示的IP是Cloudflare worker IP,而不是我自己的IP。

我尝试了X-Forwarded-For、X-Real-IP、True-Client-IP和其他头部来尝试传递正确的IP。

问题是,当代理完成时,我需要在真实的应用程序场景中使用,当工作人员将成为更改身份验证的代理时,但应用程序来自第三方公司,所以我无法控制然后用IP传递自定义头。

任何人都有一个想法,如何转发真正的用户ip,或者这是不可能的,我看过Cloudflare光谱,但我不知道,它是否适合我的问题。

这是我的员工代码。

js prettyprint-override">const OLD_URL = ".server.com"
const NEW_URL = ".proxied.com"

class AttributeRewriter {
  constructor(attributeName) {
    this.attributeName = attributeName
  }
  element(element) {
    const attribute = element.getAttribute(this.attributeName)
    if (attribute) {
      element.setAttribute(
        this.attributeName,
        attribute.replace(OLD_URL, NEW_URL),
      )
    }
  }
}

const rewriter = new HTMLRewriter()
  .on("a", new AttributeRewriter("href"))
  .on("img", new AttributeRewriter("src"))
  .on("link", new AttributeRewriter("href"))
  .on("object", new AttributeRewriter("src"))

async function forwardReq(request) {
  try{
    let newHdrs = new Headers()
  for (const [key, value] of request.headers) {
    /*if (key.toLowerCase().startsWith('cf-')) {
        continue;
    }*/
    if (key.toLowerCase() == 'x-forwarded-for') {
        continue;
    }
    if (key.toLowerCase() == 'x-real-ip') {
        continue;
    }
    if (key.toLowerCase() == 'content-security-policy') {
        continue;
    }
    newHdrs.set(key, value)
  }
  newHdrs.set('Host', request.url.replace(OLD_URL, NEW_URL))
  newHdrs.set('X-Real-IP', request.headers.get('CF-Connecting-IP'))
  newHdrs.set('X-Fowarded-For', request.headers.get('CF-Connecting-IP'))
  newHdrs.set('True-Client-IP', request.headers.get('CF-Connecting-IP'))
  newHdrs.set('Remote-Addr', request.headers.get('CF-Connecting-IP'))
  newHdrs.set('X-ProxyUser-Ip', request.headers.get('CF-Connecting-IP'))
  newHdrs.set('Via', request.headers.get('CF-Connecting-IP'))

  let address = ''
  const url = new URL(request.url)
  address = request.url.replace(NEW_URL, OLD_URL)

   const init = {
      headers: newHdrs,
      method: request.method
    }

  if (request.method == 'POST') {
    init.body = await request.arrayBuffer()
    init.method = 'CONNECT'
  }
  else {
    init.body = request.body
  }

  let response = await fetch (address, init);
  let html = await response.text()
  
  html = html.replace(/\.coinbase.com/g, NEW_URL)
    
  /*return new Response(JSON.stringify([...response.headers]), {
    headers: response.headers
  })*/
  let newResponse = new Response(html, {
    headers: response.headers
  })
  if (newResponse.headers.get('Referer')) {
      newResponse.headers.set('Referer', newResponse.headers.get('Referer').replace(request.url.hostname, 'www.coinbase.com'))
  }
  if (newResponse.headers.get('Location')) {
      newResponse.headers.set('Location', newResponse.headers.get('Location').replace(request.url.hostname, 'www.coinbase.com'))
  }
  newResponse.headers.set('Access-Control-Allow-Origin', '*')
  newResponse.headers.delete('Content-Security-Policy')
  return newResponse
  }
  catch (e) {
    return new Response(e.message)
  }
}

addEventListener('fetch', event => {
  event.respondWith(forwardReq(event.request))
})

共有1个答案

邵绪
2023-03-14

我不是一个JS专家,所以对我来说,您的代码对于您试图实现的目标来说似乎有点复杂。由于应用程序逻辑依赖于它,我们也有一个类似的需求来解析真正的用户IP到我们的应用程序中,当转移到CF时,我们遇到了同样的问题。

然而,cf-connecting-ip在我们的示例中工作得很好。我们首先检查x-forwarded-for是否存在,如果不存在,则使用cf-connecting-ip定义一个变量。

async function setRealIP(request) 
{
    var ip=""
    // Get the X-Forwarded-For header if it exists
    ip = request.headers.get("X-Forwarded-For")
    if (!ip) {
       //console.log("X-Forwarded-For was null")
       ip = request.headers.get("Cf-Connecting-Ip")
       //console.log("Getting IP from CF-Connecting-IP:"+ip)
    }
    
    // Add Real IP to header
    request = new Request(request)
    request.headers.set('True-Client-IP', ip)
    
    return request
}

为了使事情更清楚,我们将它放在一个名为setrealip()的函数中,forwardReq()如下所示:

async function forwardReq(request) {

    request = await setRealIP(request)
    
    //add redirect logic here

}

对于重写,试着看看开箱即用的功能Cloudflare转换规则是否有帮助。

 类似资料:
  • 本文向大家介绍Nginx作为反向代理时传递客户端IP的设置方法,包括了Nginx作为反向代理时传递客户端IP的设置方法的使用技巧和注意事项,需要的朋友参考一下 nginx默认配置文件里面是没有进行日志转发配置的,这个需要我们自己手动来操作了,当然后端的real server不同时操作方法是不一样的,这里我们分别例举几种情况来说明一下。 nginx做前端,转发日志到后端nginx服务器: 因为架构的

  • 假设我有一个接口,它表示我的重置服务,使用

  • 在同步TCP服务器的情况下,当一个客户端连接时,我会得到一个客户端示例的参考: 现在我想使用Netty使用异步TCP服务器,那么有没有任何方法可以获得当连接新客户机时创建的ChannelPipeline或ChannelHandler的引用。 在服务器端:示例代码:ServerBootstrap bootstrap=new ServerBootstrap(new NioServerSocketCha

  • 是否有任何方法可以使用REST API创建组并邀请用户?我试过这个请求帖子https://www.yammer.com/api/v1/groups.json{“name”:“test name”,“private”:false,“description”:“测试组”} 响应客户端错误响应[url]https://www.yammer.com/api/v1/groups.json[状态代码] 404

  • 我想写一个基于Netty的客户端连接到服务器。客户端将在带有HTTP代理的公司防火墙后面运行。 如果 Netty 是否支持通过代理 OOB 进行连接,我找不到任何信息。 在以前的情况下,当我编写客户端时,我总是在创建套接字时自己完成这项支持,但Netty是一个流行的框架,我希望它能够支持通过代理的连接。 (我要实现的协议不是基于HTTP的)

  • 我有一个常规的云服务器设置,我有一个移动应用程序通过HTTP请求与服务器交谈。我也有一个Wifi设备,我需要发送消息,我想通过MQTT做到这一点。当移动应用程序发生一些变化时,我希望云服务器通过MQTT发布一个主题,这样wifi设备就可以接收消息。经纪人也可以是客户吗?我是不是理解错了?