基于OpenrestyTengine的安全网关WAFx 实现 | xxx基于OpenrestyTengine的安全网关WAFx 实现 – xxx
菜单

基于OpenrestyTengine的安全网关WAFx 实现

四月 2, 2024 - FreeBuf

前言

因在过去的工作中,使用了一些WAF,并对此产生了比较浓厚的兴趣,结合当时工作的需要开始写 WAF ;来到新公司之后,看到公司 WAF / 网关百花齐放,应用非常广泛、日常的 QPS 都超过当时自研 WAF 一个月的量了。抛砖引玉,我还是想分享下我的一些微不足道的经验,更希望各位看官提出宝贵意见。

完全开放源代码的项目:openstar

企业版功能增强、有web管理控制台的、不开放源代码的:文档空间

抢先看

Kcon黑客大会 · 兵器谱 演示视频

录入了一些比较好玩的玩法和真实防护的场景(域名都是配置本地 host 进行演示)

1:安全需求 CSP 防护头

实时生效配置,无需修改 nginx;

方便的动态替换响应内容

2:运维需求 跨域配置

后台配置实时生效,避免经常修改 nginx 配置文件

3:安全应急 – 联动钉钉/飞书

以 CSP 策略告警方式,快速告警到钉钉/飞书

4:安全防护(HW对抗场景) – 后台另类隐身

演示通过浏览器插件(证书双向认证也可以)对抗中的小把戏

5:4层流量的 hook 演示

对 DNS 请求通过 4层的插件进行了快速的 hook 实现

openstar-Enterprise kcon 兵器谱视频_哔哩哔哩_bilibili

一、技术选型

方案A:我看到 Openresty 在 Nginx 的基础上集成了很多优良的模块,特别是将 Lua 嵌入了,让我看到了可行性

方案B:还有完全使用c/c++这样完全自研的,这条路线对我来说,因为不会,所以就 PASS 了。

方案C:类似 ModSecurity 在 Apache、IIS的解决方案,在业内应用的虽然不是特别多,因性能上的瓶颈,我给 PASS 了。

最终因为很容易使用方案A写出 demo,让我写出了男人的自信!就她了~

PS : ,特别感谢 春哥 (Openresty的作者)~

二、防护引擎

WAF的规则防护引擎的选择是非常重要的,是否合理、是否有生命力……..他将决定在时间的长河中,是否能经受住考验,不被淘汰;

少林派:字符串匹配的方式(等于、包含、正则….),这是基础的引擎能力。

武当派:语义解析能力(有基于AST语法树补充的、有基于数字特征的),特别是对 SQL注入、XSS理论上是有非常好的防护效果,提高拦截准确率、降低误报率。

逍遥派:基于域名和其请求学习,在生成规则的;基于大数据统计分析的(异步偏后场分析)… 这种武功能产生更多的价值,在数据安全、API安全有得天独厚的优势。

少林派的基础武功,必须得有,武当派的这个我评估了下,短时间我是学不会(留下了悔恨的泪水,只怪当初没好好读书),逍遥派的这一套我很认同。综合权衡后,加入少林派,联姻逍遥派(在N年前吧,因为 Nginx mirror 模块还没出来的时候,我只能用纯 Lua 通过订阅的规则将请求 & 响应流量写入到 Log 中,让逍遥派的同学去折腾吧)。

三、部署位置

防护的引擎在哪个位置工作,这也是需要仔细评估和斟酌的;

串联:这个是必不可少的,必要要在这条路上设置关键点,是轻量还是重量的我们在考虑。

并联:这个技术路线基本上是学习4层防护,将流量请求流量copy到分析引擎,让后用2层、3层等回注的方式进行拦截。

伪并联:首先是在串联的位置上部署了拦截模块,再将请求流量copy到分析引擎,单位时间内把把结果发给拦截模块,让拦截模块执行相关操作。

纯并联的方式,有些技术难点,我解决不了,只好作罢,那就定下用串联的方式吧,我这里还可以打个埋伏,计划是使用 resty-http 实现伪串了,毕竟写C我也不会(性能影响大,放弃了)。

四、落地实战

Nginx代理

用户接入域名,如何还需要运维同学改 nginx 配置文件,从效率上我们肯定是不能接受的,所有当时讨论实现了 2 套方案,最终决策使用 nginx 原生文件配置的功能,而不使用无文件落盘的纯动态代理方案(想要参考的同学可以看这里 动态代理方案

就是通过WEB界面管理域名,这个需要解决多集群文件同步的问题需要注意~

大概就是这样,当然你也可以直接在线编辑 nginx 配置文件(这个功能我们只让运维同学操作)~

基于OpenrestyTengine的安全网关WAFx 实现

输入

分析我的输入是什么?用户的请求

先说用户的请求,有4层的、还有7层的,这些都是我们的输入,我们是都要?还是根据业务优先级先做好一个,在搞下一个?

确定:我们的业务流量当前 90% 都是 http的,开搞!HTTP 请求都有什么?

后面有时间了,我也把 4 层的模块加了进来,^_^

基于OpenrestyTengine的安全网关WAFx 实现

这些就是我们的输入,明确了。整理一下

基于OpenrestyTengine的安全网关WAFx 实现

处理

少林武功上,用户的 HTTP 请求中有这么的元素(method/uri…..),我想要每一个都可以进行匹配,多个元素可以组合匹配,元素匹配之间还可以有运算逻辑~

解决匹配方式的多样化

根据研发自嗨的想法,我先做加法,能想到字符串匹配方式先有

基于OpenrestyTengine的安全网关WAFx 实现
元素这么多,我们匹配是不是有优先级呀?

是的,最早我是计划参考防火墙,就是一组规则,从上到下顺序执行,匹配那个就执行设置对应动作,朋友反馈这样不太好,让用户完全管理规则的顺序,风险有点高,我就只好基于经验主义,设置了一个执行顺序

基于OpenrestyTengine的安全网关WAFx 实现

还有 Log 阶段的事,这里就没有放进来了,流程变复杂了,现在我也没有好的优化方向了,难,难,难!

多元素匹配 & 运算逻辑

按照这个思路,我已绞尽脑汁,完成了一个纯规则实现的,支持固定的运算逻辑(小算子占位符 + 表达式引擎应该更好,当时的我还不知道这个呢,再次留下悔恨的泪水);看效果

基于OpenrestyTengine的安全网关WAFx 实现

这里的运算顺序是固定了($n 表示每一条匹配规则)

$1 AND $2 AND $3 OR $4 AND $5 OR $6

解释一下:

$1 AND $2 AND ($3 OR $4) AND ($5 OR $6)

高级DIY需求

当现有的匹配引擎无法支持用户的匹配需求时,我们还可以直接写 Lua 代码,完成自己的 diy 需求和天马行空的想法

实现方式简单的说下,就是启动的时候把插件暴露的函数注册到全局环境中,代码任意地方都可以使用,luajit 原生性能(当然也可以实现动态加载方式 loadstring 方式,这个代码维护成本比较高,我就直接去掉了)

基于OpenrestyTengine的安全网关WAFx 实现

在项目这么已经写了 十几个正式业务需求的插件,大家可以参考相关插件编写代码,写出自己的插件(配合匹配规则使用)。

脱敏插件:通用方式把响应内容的手机号识别,并将中间的数字替换为 *

扫描器检测插件:在 log 阶段,同步匹配 ip ,响应头的状态码,进行扫描器简单识别(需求来源:扫描器会在短时间里,请求很多uri,根据经验很多页面是 404 / 403 等,插件就是去统计这些信息,触发了就拦截/告警到钉钉等等),执行的动作看你怎么写了

签名检查插件:网站另类隐身场景使用、和移动APP联动使用等等…

跨域插件:运维的需求,运维同学添加允许跨域的源时,比较麻烦,调试 + 重启 Nginx ;我们就给些了个通用跨域插件,图形化简单配置下就OK,实时生效,方便调试和管理,运维同学当时那是没少感谢~

联动顶象验证码插件:业务需求,用户一些活动上线后,没来的即搞技术上的风控,想要快速的接入验证码,我们就写了个插件,快速帮助实现的验证码功能。

插件的玩法非常有意思,等你来完 ….

输出

有朋友就着急了,我想要的拦截呢、加白呢、修改请求头、修改响应头、修改响应内容,流量copy呢 …..

别慌来了,这些都有(修改响应内容前面的插件大家也看到了,插件可以实现)

我就简单的做了分类,普通的匹配规则执行的动作支持(allow、deny、log);

高级规则增加了(rehtml/debug/refile/func)

基于OpenrestyTengine的安全网关WAFx 实现

放行(allow)

这个比较简单,就是命中了规则咋就 bypass 了,比如 uri 过滤时,我们把很多静态文件的特征的匹配了,都放行后面的规则。

日志(log)

对命中的请求,记录下日志,当然记录日志的格式也是可以配置的,里面的变量基本上都支持(body这样大的我是不支持的)

拦截(deny)

可以根据域名设置不同的拦截页面和响应状态码

基于OpenrestyTengine的安全网关WAFx 实现

调试(debug)

这个功能就是为了适配逍遥派武功开发的,根据匹配命中的规则,对命中的所有请求把 request & response 内容都记录到 log 中,让他们去消费;顺便给了他们一个 ak – sk,用于调用我们的接口,执行拦截动作

注:比如在他前面的执行流程已经执行了 allow 操作,我们是不会记录日志的,比如静态文件;还有默认 body 取值是 10240 长度,当然这个参数也是可以配置的,毕竟响应 body 太大,我们也不便记录。

响应HTML(rehtml)

这个功能就是快速配置一个页面的响应内容,将页面直接返回了,场景应用也非常多,比如管理后台仅允许白名单IP访问,非白名单就直接响应个维护页面;还有开发时,我们做调试用,真的是谁用谁知道…

响应文件(refile)

这个功能和上面的响应 Html 功能有点重合,主要是响应的内容太大时,我们就用文件这种方式(响应文件类型也是可以配置的)。

插件函数(func)

这里就是为了满足高级用户,他们diy的需求,有很多玩法,实在是让我脑洞大开,值得大家好好玩一下。

五、写在最后

因为该项目从原型图、架构设计、后端开发都是一人在做(前端开发是找一些同学帮忙做的,感谢了 亲们),难免会有错误和不合理的地方,还是抛砖引玉,希望可以交流,给我在提出更多的意见和建议。

# waf技术 # Openresty # WAF产品 # API网关
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022

Notice: Undefined variable: canUpdate in /var/www/html/wordpress/wp-content/plugins/wp-autopost-pro/wp-autopost-function.php on line 51