ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Gin 怎么配置 SetTrustedProxies 与 TrustedPlatform 让 ClientIP 返回真实客户端 IP

Gin 怎么配置 SetTrustedProxies 与 TrustedPlatform 让 ClientIP 返回真实客户端 IP Gin 怎么配置 SetTrustedProxies 与 TrustedPlatform 让 ClientIP 返回真实客户端 IP【免费下载链接】ginGin is a high-performance HTTP web framework written in Go. It provides a Martini-like API but with significantly better performance—up to 40 times faster—thanks to httprouter. Gin is designed for building REST APIs, web applications, and microservices.项目地址: https://gitcode.com/GitHub_Trending/gi/ginGin 服务放在反向代理或 CDN 后面时c.ClientIP()应该返回真实客户端 IP而不是代理的地址。但 Gin 默认信任所有代理TrustedProxies功能默认开启且默认信任全部来源这意味着任何人都可以伪造X-Forwarded-For头。这篇文档给出两条互补的配置路径用Engine.SetTrustedProxies()限定哪些直接连接来源的 IP 头可以被信任自建代理场景以及在接入 CDN 时用Engine.TrustedPlatform直接读取 CDN 写入的专用头。前提是一个已引入 Gin 的 Go 项目。ClientIP() 的判定链先看 context.go 中ClientIP()的注释和实现它按以下顺序决定返回值TrustedPlatform非空且请求中存在该名称的头 → 直接返回该头的值否则从Request.RemoteAddr解析直接连接 IPRemoteIP()若直接连接 IP 落在SetTrustedProxies()设置的信任列表内且ForwardedByClientIP为truegin.go 中New()的默认值就是true则解析Engine.RemoteIPHeaders中定义的头默认[X-Forwarded-For, X-Real-IP]头不合法、或直接连接 IP 不受信任 → 返回直接连接 IP。其中第 3 步的具体规则在 gin.go 的validateHeader中实现X-Forwarded-For按逗号拆分后从后往前检查返回第一个不在信任列表中的 IP如果所有 IP 都在信任列表里返回头中的第一个 IP遇到无法解析的条目则停止并判定该头无效。起步检查默认配置会打印警告Gin 的默认信任列表是0.0.0.0/0与::/0gin.go 中New()的初始值即信任全部代理。docs/doc.md 明确标注this is NOT safe。Run、RunTLS、RunUnix、RunFd、RunQUIC、RunListener这些启动入口都会检查信任列表是否覆盖全部 IP若是则打印[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.因此启动时是否出现这条警告可以作为一条现成的核对信号配置正确后它不应再出现。步骤一用 SetTrustedProxies 限定可信代理按 docs/doc.md 的 Dont trust all proxies 一节在gin.Engine上调用SetTrustedProxies()参数支持 IPv4 地址、IPv4 CIDR、IPv6 地址、IPv6 CIDR。文档给出的示例192.168.1.2替换为你自己的代理地址func main() { router : gin.Default() router.SetTrustedProxies([]string{192.168.1.2}) router.GET(/, func(c *gin.Context) { // If the client is 192.168.1.2, use the X-Forwarded-For // header to deduce the original client IP from the trust- // worthy parts of that header. // Otherwise, simply return the direct client IP fmt.Printf(ClientIP: %s\n, c.ClientIP()) }) router.Run() }router.Run()未指定端口时默认监听:8080除非设置了PORT环境变量文档路由章节有说明。几个直接影响执行的细节返回值是error必须检查。gin_test.go 的TestPrepareTrustedCIRDsWith展示了哪些输入合法192.168.1.33合法单个 IP 会被解析为/322002:0000:0000:1234:abcd:ffff:c0a8:0101合法IPv6 单地址解析为/128::/0、192.168.0.0/16等组合合法而192.168.1.33/33、192.168.1.256、gggg:0000:0000:1234:abcd:ffff:c0a8:0101这类无效值会返回 error。完全不使用代理时用router.SetTrustedProxies(nil)禁用该功能此时Context.ClientIP()直接返回直接连接地址避免不必要的计算——这是 docs/doc.md 给出的做法文档原文说明其目的是 avoid some unnecessary computation。列表为空切片[]string{}与nil效果不同nil是关闭功能空切片是没有任何可信代理。两者的结果都是ClientIP()回退到直接连接 IP见 context_test.go 中两条相邻的测试断言但文档明确描述的是nil这一种优先使用文档说明的写法。步骤二接入 CDN 时改用 TrustedPlatformdocs/doc.md 的 Notice 指出Engine.TrustedPlatform可以跳过 TrustedProxies 检查它的优先级高于 TrustedProxies。设置后ClientIP()会解析对应的头并直接返回其中的 IP。gin.go 中预定义了三个平台常量对应各自读取的头常量读取的请求头gin.PlatformGoogleAppEngineX-Appengine-Remote-Addrgin.PlatformCloudflareCF-Connecting-IPgin.PlatformFlyIOFly-Client-IP文档示例192.168.1.2一节的同款结构此处为 CDN 分支func main() { router : gin.Default() // Use predefined header gin.PlatformXXX // Google App Engine router.TrustedPlatform gin.PlatformGoogleAppEngine // Cloudflare router.TrustedPlatform gin.PlatformCloudflare // Fly.io router.TrustedPlatform gin.PlatformFlyIO // Or, you can set your own trusted request header. But be sure your CDN // prevents users from passing this header! For example, if your CDN puts // the client IP in X-CDN-Client-IP: router.TrustedPlatform X-CDN-Client-IP router.GET(/, func(c *gin.Context) { // If you set TrustedPlatform, ClientIP() will resolve the // corresponding header and return IP directly fmt.Printf(ClientIP: %s\n, c.ClientIP()) }) router.Run() }注意文档的警告如果用自己的头名如X-CDN-Client-IP必须确认你的 CDN 会阻止用户直接传入该头否则客户端仍可伪造。另外当请求中该头为空时ClientIP()不会报错而是回落到 TrustedProxies 判定路径context_test.go 中有对应断言TrustedPlatform指向一个不存在的头时返回直接连接 IP。验证配置是否生效1. 启动检查运行服务确认[WARNING] You trusted all proxies, this is NOT safe.不再出现在启动日志中。2. 请求检查按步骤一/二的示例程序运行用curl http://localhost:8080/发请求观察 handler 打印的ClientIP:输出是否符合预期。context_test.go 的ClientIP测试用例给出了一组可参照的行为数据以下为测试用例中的示例值不是生产环境的固定预期RemoteAddr为40.40.40.40:42123X-Forwarded-For为20.20.20.20, 30.30.30.30信任列表只含40.40.40.40→ClientIP()返回30.30.30.30从后往前第一个不受信任的 IP信任列表包含40.40.40.40、30.30.30.30、20.20.20.20全部受信任→ 返回头中第一个 IP20.20.20.20信任列表用 CIDR40.40.25.25/1630.30.30.30时直接连接40.40.40.40命中该 CIDR同样返回20.20.20.20直接连接不受信任 → 返回直接连接 IP40.40.40.40X-Forwarded-For内容不是合法 IP如 blah → 回退返回直接连接 IP。3. 错误检查SetTrustedProxies返回非 nil 的error说明列表里有无法解析的地址或 CIDR需要修正输入格式见上一步的合法/非法示例。限制与已废弃项默认信任所有代理是不安全状态docs/doc.md 原文标注this is NOT safe不配置SetTrustedProxies或接入 CDN 前的状态都应视为待修正项。Engine.AppEngine字段已废弃gin.go 中的注释要求改用TrustedPlatform并取值gin.PlatformGoogleAppEngine。旧标志仍然生效读取X-Appengine-Remote-Addr头但每次请求都会打印一条 deprecation 日志context.go 中ClientIP()的实现。需要更换读头顺序时可调整Engine.RemoteIPHeaders默认为[X-Forwarded-For, X-Real-IP]ClientIP()按该列表顺序逐个尝试取第一个能解析出有效 IP 的头。配置完成后核对点就是两个启动日志无 trust-all 警告handler 打印的ClientIP:与代理链中的真实来源一致。更多细节可回到 docs/doc.md 的 Dont trust all proxies 一节。【免费下载链接】ginGin is a high-performance HTTP web framework written in Go. It provides a Martini-like API but with significantly better performance—up to 40 times faster—thanks to httprouter. Gin is designed for building REST APIs, web applications, and microservices.项目地址: https://gitcode.com/GitHub_Trending/gi/gin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表