You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Golang反向代理遭Cloudflare拦截而Nginx可正常运行?

解决Golang反向代理访问Cloudflare保护站点返回403的问题

同一主机下Nginx反向代理可正常访问Cloudflare保护的https://icanhazip.com,但Golang实现的反向代理返回403 Forbidden,核心原因是Golang默认反向代理的请求头设置与Nginx不一致,触发了Cloudflare的安全拦截规则。

问题根源

  • Nginx默认执行proxy_pass时,会自动将Host头设置为目标服务器的主机名(即icanhazip.com),同时完整转发客户端的请求头(如User-Agent)。
  • Golang的httputil.NewSingleHostReverseProxy默认会清空未显式设置的User-Agent,且你之前的自定义逻辑错误地将Host头设为代理自身的地址(127.0.0.1:8082),这两个点共同导致Cloudflare判定请求异常。

可行解决方案

需要调整Golang反向代理的请求头设置,确保传递目标服务器的Host头,并保留/设置合法的User-Agent,以下是两种实现方式:

方式一:修改Director函数

package main

import (
    "fmt"
    "log"
    "net/http"
    "net/http/httputil"
    "net/url"
)

func main() {
    testUrl, err := url.Parse("https://icanhazip.com")
    if err != nil {
        log.Fatal(err)
    }

    proxy := httputil.NewSingleHostReverseProxy(testUrl)
    originalDirector := proxy.Director

    proxy.Director = func(req *http.Request) {
        originalDirector(req)
        // 设置Host为目标服务器的主机名,与Nginx默认行为对齐
        req.Header.Set("Host", testUrl.Host)
        // 保留客户端的User-Agent,若客户端未传递则设置通用浏览器UA
        if _, ok := req.Header["User-Agent"]; !ok {
            req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
        }
    }

    server := http.Server{
        Addr:    fmt.Sprintf(":%d", 8082),
        Handler: http.HandlerFunc(proxy.ServeHTTP),
    }

    if err := server.ListenAndServe(); err != http.ErrServerClosed {
        log.Fatal(err)
    }
}

方式二:使用Rewrite自定义代理逻辑

package main

import (
    "fmt"
    "log"
    "net/http"
    "net/http/httputil"
    "net/url"
)

func main() {
    testUrl, err := url.Parse("https://icanhazip.com")
    if err != nil {
        log.Fatal(err)
    }

    proxy := &httputil.ReverseProxy{
        Rewrite: func(r *httputil.ProxyRequest) {
            r.SetURL(testUrl)
            // 设置Host为目标服务器的主机名
            r.Out.Host = testUrl.Host
            // 转发客户端的User-Agent,无UA时设置默认值
            if ua := r.In.Header.Get("User-Agent"); ua != "" {
                r.Out.Header.Set("User-Agent", ua)
            } else {
                r.Out.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
            }
            // 可选:设置X-Forwarded系列头,模拟Nginx的转发行为
            r.SetXForwarded()
        },
    }

    server := http.Server{
        Addr:    fmt.Sprintf(":%d", 8082),
        Handler: proxy,
    }

    if err := server.ListenAndServe(); err != http.ErrServerClosed {
        log.Fatal(err)
    }
}

为什么之前的方案无效

你之前尝试的两种方案均错误地将Host头设置为代理自身的地址(r.In.Host即127.0.0.1:8082),这与Nginx默认传递目标服务器Host的行为不符,导致Cloudflare识别请求异常并返回403。

内容的提问来源于stack exchange,提问作者hellopeach

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 16:20:26