Go语言Echo框架IP黑名单实现

陌雪大大_4681

陌雪大大_4681

2026-09-02

479人浏览

原创

应配置可信代理网段而非仅用c.realip():e.trustproxyfunc = func(ip net.ip) bool { return ip.isloopback() || ip.to4() != nil && (ip.to4()[0] == 10 || ip.to4()[0] == 172 && ip.to4()[1] >= 16 && ip.to4()[1]

go语言echo框架ip黑名单实现

如何在Echo中间件中获取真实客户端IP

直接用 c.RealIP() 通常拿不到真实IP,尤其在Nginx、Cloudflare或Kubernetes Ingress后。Echo默认信任 X-Forwarded-For,但必须显式配置可信代理段,否则会返回空或错误IP。

实操建议:

  • 在启动Echo实例后、注册路由前,调用 e.IPExtractor = echo.ExtractIPFromXFFHeader(仅当需要从XFF取IP时)
  • 更安全的做法是设置可信代理网段:e.TrustProxyFunc = func(ip net.IP) bool { return ip.IsLoopback() || ip.To4() != nil && (ip.To4()[0] == 10 || ip.To4()[0] == 172 && ip.To4()[1] >= 16 && ip.To4()[1]
  • 之后统一用 c.RealIP() —— 它会自动跳过不可信代理,只取最后一个可信段IP

用sync.Map实现轻量级IP黑名单检查

高频请求下用map+mutex容易成为瓶颈,sync.Map 更适合读多写少的黑名单场景(比如手动封禁、临时限流)。但注意它不支持遍历和len(),不适合需要定期清理或统计的场景。

实操建议:

  • 定义全局黑名单:var ipBlacklist = sync.Map{}
  • 检查逻辑放在中间件里:if _, ok := ipBlacklist.Load(c.RealIP()); ok { return c.String(http.StatusForbidden, "Forbidden") }
  • 添加IP(如管理接口):ipBlacklist.Store("192.168.1.100", struct{}{});删除用 ipBlacklist.Delete("192.168.1.100")
  • 避免用字符串拼接IP加端口(如 192.168.1.100:54321),c.RealIP() 返回纯IP,端口已剥离

持久化黑名单需注意时间格式与存储粒度

如果用Redis或文件存黑名单,常见坑是时间戳精度不一致导致过期失效,或把整个IP段(如 192.168.1.0/24)当成单个字符串存,后续匹配成本高。

Echo框架 5.1.0
Echo框架 5.1.0

Echo框架 5.1.0 版本源码包下载,适合关注 RealIP 行为变化、StartConfig.Listener、NewDefaultFS 和观测性中间件入口的开发团队。

下载

实操建议:

  • 存储结构推荐:key为IP字符串,value为过期Unix时间戳(秒级足够),用 redis.SetEX(ctx, "blacklist:"+ip, "1", time.Until(expireTime))
  • 匹配时先查是否存在,再查是否过期 —— 不要依赖Redis自动过期,因为 EXISTSGET 非原子,高并发下可能误放行
  • 若需CIDR支持,不要在运行时做net.ParseCIDR+IP.In(),而应在写入时预计算所有可能IP(仅适用于/24及更大子网),或改用专用库如 go-netutils

为什么不能只靠HTTP头字段做IP校验

X-Forwarded-ForX-Real-IP 等头完全由客户端或上游代理控制,未经过滤就用它们做黑名单判断,等于把封禁逻辑暴露给攻击者 —— 只要伪造一个不在黑名单里的IP头,就能绕过。

实操建议:

  • 永远以 c.RealIP() 为准,它已集成TrustProxyFunc逻辑
  • 禁止在中间件里直接读 c.Request().Header.Get("X-Forwarded-For") 做判断
  • 如果上游是Cloudflare,确保在Nginx层已用 set_real_ip_from + real_ip_header CF-Connecting-IP 设置可信源,否则 c.RealIP() 仍可能取错

真正难的不是加黑名单,而是确定“这个IP到底是谁”。代理链越长,IP可信度越低;IPv6地址长度和格式变化也会影响字符串匹配逻辑。别省略 TrustProxyFunc 配置,哪怕只是先写 return ip.IsLoopback() —— 至少比默认行为安全。

golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Go中Type关键字的用法
Go中Type关键字的用法

Go中Type关键字的用法有定义新的类型别名或者创建新的结构体类型。本专题为大家提供Go相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.06

2289

5

go怎么实现链表
go怎么实现链表

go通过定义一个节点结构体、定义一个链表结构体、定义一些方法来操作链表、实现一个方法来删除链表中的一个节点和实现一个方法来打印链表中的所有节点的方法实现链表。

2023.09.25

4467

6

go语言编程软件有哪些
go语言编程软件有哪些

go语言编程软件有Go编译器、Go开发环境、Go包管理器、Go测试框架、Go文档生成器、Go代码质量工具和Go性能分析工具等。本专题为大家提供go语言相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.13

602

5

0基础如何学go语言
0基础如何学go语言

0基础学习Go语言需要分阶段进行,从基础知识到实践项目,逐步深入。php中文网给大家带来了go语言相关的教程以及文章,欢迎大家前来学习。

2023.10.26

6205

20

Go语言实现运算符重载有哪些方法
Go语言实现运算符重载有哪些方法

Go语言不支持运算符重载,但可以通过一些方法来模拟运算符重载的效果。使用函数重载来模拟运算符重载,可以为不同的类型定义不同的函数,以实现类似运算符重载的效果,通过函数重载,可以为不同的类型实现不同的操作。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

2096

5

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

2344

5

go语言开发工具大全
go语言开发工具大全

本专题整合了go语言开发工具大全,想了解更多相关详细内容,请阅读下面的文章。

2025.06.11

5119

12

go语言引用传递
go语言引用传递

本专题整合了go语言引用传递机制,想了解更多相关内容,请阅读专题下面的文章。

2025.06.26

3297

12

go语言版本升级
go语言版本升级

本专题整合了go语言版本升级方法,想了解更多相关内容,请阅读专题下面的文章。

2025.06.27

5990

16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程