Eswlnk Blog Eswlnk Blog
  • 资源
    • 精彩视频
    • 破解专区
      • WHMCS
      • WordPress主题
      • WordPress插件
    • 其他分享
    • 极惠VPS
    • PDF资源
  • 关于我
    • 论文阅读
    • 关于本站
    • 通知
    • 左邻右舍
    • 玩物志趣
    • 日志
    • 专题
  • 热议话题
    • 游戏资讯
  • 红黑
    • 渗透分析
    • 攻防对抗
    • 代码发布
  • 自主研发
    • 知识库
    • 插件
      • ToolBox
      • HotSpot AI 热点创作
    • 区块
    • 快乐屋
    • 卡密
  • 乱步
    • 文章榜单
    • 热门标签
  • 问答中心反馈
  • 注册
  • 登录
首页 › 代码发布 › 「代码发布」Nginx 防火墙模块开发总结

「代码发布」Nginx 防火墙模块开发总结

Eswlnk的头像
Eswlnk
2022-08-12 14:08:01
「代码发布」Nginx 防火墙模块开发总结-Eswlnk Blog
智能摘要 AI
本文作者分享了开发一个Nginx防火墙模块的经历。最初因网站频繁被扫描导致性能下降,作者尝试多种解决方案后决定自建模块。该模块用C语言开发,旨在提供基础防护功能,包括IP、URL、参数等检测及CC防御,并支持集成reCAPTCHA和hCAPTCHA进行人机验证。设计注重性能与可读性,采用LRU缓存和前缀树优化,有效提升了检测效率。项目遵循语义化版本控制和Changelog规范,便于用户跟踪更新。模块已集成ModSecurity规则,进一步增强了安全性。尽管项目曾短暂登上GitHub趋势榜,但整体稳定且无重大改动计划。

为什么要写这篇文章?

我起初并没有写这篇文章的意思,因为无论是从难度还是代码复杂度来说这个项目在我写过的项目里只能算中等,但是它却有一个特点,就是我的第一个专门开发出来供他人使用并且希望被他人使用的项目。先前的项目要不然不能公开,要不然个人属性非常强,不适合他人使用。所以这篇文章主要是以纪念为目的的。

为什么要开启这个项目?

那段时间我的站点有时会打不开,起初以为是网络问题,后来越来越严重,进入后台才发现数据库 IO 拉满了。看了看 nginx 的日志才发现站点被疯扫,于是打算做点什么。

我先从网上搜索到了一些基础的拦截扫站的规则,直接 copy 到 nginx.conf 里就能用,但是这些规则都特别多,而且杂,直接丢到配置文件里会大大降低配置的可读性,所以当初就被否了。

后来我拉黑了一些 IP,不过这也就一时起作用,过段时间换了 IP 继续来扫。补救措施是用 whois 找到 IP 地址快直接全部拉黑。但是这导致了一些误伤,于是这个方案也被否了。

然后我找到了 ngx_lua_waf,用了一段觉得还行,但是也发现了一些缺陷,最明显的就是拉黑 IP 的时候只能拉黑单个 IP,而不能拉黑一个地址块。但是这个模块大概已经停止维护了,不能指望作者更新了。

然后在 Github 上看了几个防火墙模块,要不然功能不全,要不然使用复杂,于是萌生了自己写模块的想法。

为什么用 C 语言开发?

主要是因为这样可以不用安装 lua_nginx_module,其次是因为 C 的执行效率理论上要高于 lua,因为 lua 需要启动一个 VM。

不过我主要考虑的是安装是否方便,性能倒不是那么看重,因为 lua_nginx_module 身经百战,性能完全可以保证。

不过用 C 语言开发必然增加开发难度,最重要的是要自己控制内存,这类 Web 服务器上的模块一旦内存泄露、段错误啥的那麻烦就大了,不过我还是有信心不出大问题的。

设计原则

只实现基础的防护,即 IP 检测、Url 检测、Get 参数检测、Cookie 检测、Post 检测、Referer 检测和 CC 防御。不会引入更复杂的功能,比如根据某个 IP 的行为进行综合判断是否拦截。

在保证代码良好可读性的情况下提高性能。

语义化版本

说实话我之前还真没把这个当回事,但是当我打算把这个项目给别人用的时候我发现版本号似乎也能传递一些比较重要的信息,所以开发这个项目的时候我是一直遵守这个标准的。

简单来说语义化版本将版本号分为 X.Y.Z。

  • 当你做了不向下兼容的更改之后 X 要递增。
  • 当你做了向下兼容的功能性新增的时候 Y 要递增。
  • 当你做了向下兼容的修正时 Z 要递增。

这样版本号就可以向用户传递对应的信息,这无疑是十分有用的,最明显的就是当用户看到 X 递增的时候就会十分谨慎,因为贸然更新可能会导致现有的程序出现不兼容的情况。

Change Log

作为一个打算给他人使用的项目,一个清晰的 Change Log 就是很必要的了,它可以将每次更新的内容展示出来,方便他人了解也方便自己记录。

格式上基本遵循:https://keepachangelog.com/zh-CN/1.0.0/

「代码发布」Nginx 防火墙模块开发总结-Eswlnk Blog
效果图

从效果上来看应该还算是清晰准确的 Change Log。

开发文档

项目写到后期就不得不写开发文档了,首先是方便了自己,其次也是方便别人。可以从头开始写效率太低了,强烈推荐 doxygen。这个工具可以通过代码内的注释自动生成文档,这样为源代码写注释的同时还能生成开发文档,十分方便。

下面是对应的注释以及生成的开发文档。

「代码发布」Nginx 防火墙模块开发总结-Eswlnk Blog
注释内容

开发文档简单,清晰,还能自动生成函数调用图和被调用图等一系列图。如果觉得丑还能自定义 CSS,不过对于我这个前端困难户来说就不搞了。

性能优化

性能优化的主要工作就是降低请求检查花费的时间。

缓存

Url 检查、Get 参数检查、Post 检查、Cookie 检查和 Referer 检查都需要执行正则匹配,暂时没发现什么合适的方法去优化,只能一个一个地去检查。时间复杂度为 $\text{O}(nm)$,$n$ 为需要测试的正则条数,$m$ 为执行正则匹配的时间。

不过由于本模块只会在 nginx 启动时读取规则,运行时规则不会改变,所以对于同一个 URL 无论检测多少次结果都不会变,于是本模块会缓存检查的结果,每次检查前先读取缓存,如果命中则直接取出结果,反之则走流程检查。除了 IP 检查和 Post 检查以外所有的检查都使用了缓存机制。

缓存淘汰策略为 LRU。当缓存的内存不足时会引起频繁的淘汰,增加内存碎片。于是本模块会周期性地按照 LRU 的策略淘汰掉一定比例的缓存。

前缀树优化

IP 检查很有搞头。本模块使用了一种经过修改的前缀树来改进 IP 检查的性能,见下图。

「代码发布」Nginx 防火墙模块开发总结-Eswlnk Blog
本模块所使用的前缀树

从图示就可以看出此结构可以方便地处理单个 IP 的检查和 IP 地址块的检查。

前缀树的查找时间为 $\text{O}(h)$,其中 $h$ 为树的高度。对于 IPV4 来说一共有 32 位,那么树高最多 32,IPV6 对应的树高最多为 128。那么查找时间复杂度为 $\text{O}(1)$,也就是说执行 IP 检查的时间基本上不会受到 IP 黑白名单规模的影响。

测试

经过比较极限的测试,QPS 降低了约 4%,详情见性能测试。

我上 Trending 了!

2021 年 4 月 8 日晚上我发现我的项目出现在了 Github Trending(C 语言) 下,截图纪念一下。

「代码发布」Nginx 防火墙模块开发总结-Eswlnk Blog

希望不要明天起来就没了,多撑几天吧。

第二天晚更新:博主已经凉了,散了吧。

验证码

这里的验证码特指用于人机验证的验证码,比如滑块解锁等,也就是我们通常所说的 CAPTCHA,比较有名的就是 reCAPTCHA。

「代码发布」Nginx 防火墙模块开发总结-Eswlnk Blog
reCAPTCHA

目前已经集成了 reCAPTCHA 的全部种类的验证码以及 hCAPTCHA。本来想着集成一下腾讯云的验证码,但是发现集成起来好麻烦,远没有前两种简单,就一直搁置到现在。

验证码的集成也带来了不小的好处,比如 CC 防护不再只能简单地拉黑了。有了验证码后就可以将 CC 防护的阈值降低一些,超出时弹出验证码,通过验证则放行,反之则拉黑一段时间。同时,根据某个用户的建议,现在当触发任何的拦截时,就会对该 IP 启用验证码,当且仅当通过验证时才会放行,否则无法进行任何访问。

集成 ModSecurity

ModSecurity 是一个广泛使用的开源的 WAF 引擎,并且在网络上有现成的安全规则可以套用,所以本模块也继承了 ModSecurity 的引擎,可以加载 ModSecurity 的规则。

(ModSecurity 的内存泄漏问题官方什么时候修一下)

后续计划

本项目已经完成了性能优化,后续应该不会有大的改动,不过如果有合适的需求就另说了。有了新的进展我也会更新本文。

ESWINK , 版权所有丨如未注明 , 均为原创

原文标题:「代码发布」Nginx 防火墙模块开发总结

「代码发布」Nginx 防火墙模块开发总结-Eswlnk Blog
本站默认网盘访问密码:1166
本站默认网盘访问密码:1166
Nginx防火墙随笔项目分享
0
0
Eswlnk的头像
Eswlnk
一个有点倒霉的研究牲站长
赞赏
WordPress小技巧之从搜索结果中排除页面
上一篇
「代码发布」又拍云&老薛主机(CPanel)流量监控
下一篇

评论 (0)

请登录以参与评论
现在登录
    发表评论

猜你喜欢

  • 「日志记录」逆向必应翻译网页版API实现免费调用
  • 「代码分享」第三方平台VIP视频解析API接口
  • 「至臻原创」某系统网站登录功能监测
  • 「开发日志」在Vue3中如何为路由Query参数标注类型
  • 「其他分享」分享一个在Tun模式下可用的脚本
Eswlnk的头像

Eswlnk

一个有点倒霉的研究牲站长
1108
文章
319
评论
679
获赞

随便看看

「主题改造」Typecho使用highlight.js代码高亮实现代码行号
2024-04-04 17:03:41
页面优化:使用JS脚本实现页面链接预加载
2022-05-01 2:16:04
JAVA如何自定义Mysql连接池
2022-06-27 13:27:20

文章目录

专题展示

WordPress53

工程实践37

热门标签

360 AI API CDN java linux Nginx PDF PHP python SEO Windows WordPress 云服务器 云服务器知识 代码 免费 安全 安卓 工具 开发日志 微信 微软 手机 插件 攻防 攻防对抗 教程 日志 渗透分析 源码 漏洞 电脑 破解 系统 编程 网站优化 网络 网络安全 脚本 苹果 谷歌 软件 运维 逆向
  • 首页
  • 知识库
  • 地图
Copyright © 2023-2025 Eswlnk Blog. Designed by XiaoWu.
本站CDN由 壹盾安全 提供高防CDN安全防护服务
蜀ICP备20002650号-10
页面生成用时 0.656 秒   |  SQL查询 35 次
本站勉强运行:
友情链接: Eswlnk Blog 网站渗透 倦意博客 特资啦!个人资源分享站 祭夜博客 iBAAO壹宝头条
  • WordPress142
  • 网络安全64
  • 漏洞52
  • 软件52
  • 安全48
现在登录
  • 资源
    • 精彩视频
    • 破解专区
      • WHMCS
      • WordPress主题
      • WordPress插件
    • 其他分享
    • 极惠VPS
    • PDF资源
  • 关于我
    • 论文阅读
    • 关于本站
    • 通知
    • 左邻右舍
    • 玩物志趣
    • 日志
    • 专题
  • 热议话题
    • 游戏资讯
  • 红黑
    • 渗透分析
    • 攻防对抗
    • 代码发布
  • 自主研发
    • 知识库
    • 插件
      • ToolBox
      • HotSpot AI 热点创作
    • 区块
    • 快乐屋
    • 卡密
  • 乱步
    • 文章榜单
    • 热门标签
  • 问答中心反馈