You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
uuWAF/docs/api
Safe3 690d20f77f
v1.9.3
2 years ago
..
README.md v1.9.3 2 years ago
_sidebar.md v1.2 2 years ago

README.md

🍓 全局配置

init_by_lua_block

  • 类型: table

  • 默认值: { host = "127.0.0.1", port = 3306, user = "root", password = "safe3.waf" }

  • 用法:

    local conf = { host = "127.0.0.1", port = 3306, user = "root", password = "safe3.waf" }
    

    local conf变量位于/uuwaf/conf/uuwaf.conf中用于配置waf要读取配置的mysql数据库连接的ip、端口号、用户名和密码。

🍇 规则

?>这里对规则所用到的一些变量和相关函数进行说明更多规则编写方法请大家参照WAF管理后台中的规则管理当中的众多实际例子。规则模板见https://github.com/Safe3/uuWAF/blob/main/rules/anti-cc.lua 一条防cc攻击的安全规则。欢迎各位贡献安全规则详情见https://waf.uusec.com/#/guide/contribute

规则示例

--[[
规则名称: anti cc
过滤阶段: 请求阶段
危险等级: 中危
规则描述: 当一分钟访问/api/路径频率超过360次则在5分钟内拦截该ip访问
--]]


if not waf.startWith(waf.toLower(waf.uri), "/api/") then
    return false
end

local sh = ngx.shared.ipCache
local ccIp = 'cc-' .. waf.ip
local c, f = sh:get(ccIp)
if not c then
    sh:set(ccIp, 1, 60, 1)           -- 设置1分钟也就是60秒访问计数时间
else
    if f == 2 then
        return waf.block(true)       -- 重置TCP连接不记录日志
    end
    sh:incr(ccIp, 1)
    if c + 1 >= 360 then             -- 频率超过360次
        sh:set(ccIp, c + 1, 300, 2)  -- 设置5分钟也就是300秒拦截时间
        return true, ccIp, true      -- 返回参数第一个true为是否检测到第二个参数ccIp为日志记录内容第三个参数true表示拦截false表示只记录不拦截
    end
end

return false

规则变量

请求阶段变量

waf.ip
  • 类型: string
  • 默认值: 客户端访问ip
  • 用法: 只读用于获取客户端访问ip可以在WAF后台站点管理中配置客户端ip来源获取方式为Socket或X-Forwarded-For中的倒序第n个ip。
waf.host
  • 类型: string
  • 默认值: 客户端访问host头
  • 用法: 只读。
waf.requestLine
  • 类型: string
  • 默认值: 原始的request line数据
  • 用法: 只读。
waf.uri
  • 类型: string
  • 默认值: 解码处理过的URI不带参数
  • 用法: 只读。
waf.method
  • 类型: string
  • 默认值: 请求方法
  • 用法: 只读。
waf.reqUri
  • 类型: string
  • 默认值: 原始URI带参数
  • 用法: 只读。
waf.userAgent
  • 类型: string
  • 默认值: 客户端请求的User-Agent头数据
  • 用法: 只读。
waf.referer
  • 类型: string
  • 默认值: 客户端请求的Referer头数据
  • 用法: 只读。
waf.reqContentType
  • 类型: string
  • 默认值: 客户端请求的Content-Type头数据
  • 用法: 只读。
waf.XFF
  • 类型: string
  • 默认值: 客户端请求的X-Forwarded-For头数据
  • 用法: 只读。
waf.origin
  • 类型: string
  • 默认值: 客户端请求的Origin头数据
  • 用法: 只读。
waf.reqHeaders
  • 类型: table
  • 默认值: 请求的所有header对象
  • 用法: 只读。
waf.hErr
  • 类型: string
  • 默认值: 请求header解析出错信息
  • 用法: 只读。
waf.isQueryString
  • 类型: bool
  • 默认值: true或false
  • 用法: 只读,是否存在请求参数。
waf.reqContentLength
  • 类型: number
  • 默认值: 0
  • 用法: 只读请求body内容长度整数值。
waf.queryString
  • 类型: table
  • 默认值: 请求url参数key、value
  • 用法: 只读。
waf.qErr
  • 类型: string
  • 默认值: 请求参数解析出错信息
  • 用法: 只读。
waf.form
  • 类型: table
  • 默认值: 请求body对象
  • 用法: 只读。
waf.form["RAW"]
  • 类型: string
  • 默认值: 请求body的原始数据
  • 用法: 只读。
waf.form["FORM"]
  • 类型: table
  • 默认值: 请求body参数key、value
  • 用法: 只读,表单如: {uid="12",vid={[1]="select",[2]="a from b"}}。
waf.form["FILES"]
  • 类型: table
  • 默认值: 解析出的请求body中上传文件信息
  • 用法: 只读,文件信息如: {name={[1]="filename",[2]="file content"}}。
waf.fErr
  • 类型: string
  • 默认值: 解析请求body出错信息
  • 用法: 只读,一般是恶意畸形请求包。
waf.cookies
  • 类型: table
  • 默认值: 请求cookie参数key、value
  • 用法: 只读。
waf.cErr
  • 类型: string
  • 默认值: 解析请求cookie出错信息
  • 用法: 只读。

返回http头阶段新增变量

waf.status
  • 类型: number
  • 默认值: 返回http状态整数值
  • 用法: 只读。
waf.respHeaders
  • 类型: table
  • 默认值: 返回的所有header对象key、value
  • 用法: 只读。
waf.respContentLength
  • 类型: number
  • 默认值: 返回body内容长度整数值
  • 用法: 只读。
waf.respContentType
  • 类型: string
  • 默认值: 服务端返回的Content-Type头数据
  • 用法: 只读。

返回页面阶段新增变量

waf.respBody
  • 类型: string
  • 默认值: 返回body页面内容
  • 用法: 只读。

规则 API

规则通用 API

waf.startWith(sstr,dstr)
  • 参数: sstr 为原字符串dstr 为查找字符串
  • 功能: 判断字符串 sstr 是否以 dstr 开头
  • 返回值: true 或 false
waf.endWith(sstr,dstr)
  • 参数: sstr 为原字符串dstr 为查找字符串
  • 功能: 判断字符串 sstr 是否以 dstr 结尾
  • 返回值: true 或 false
waf.toLower(sstr)
  • 参数: sstr 为原字符串
  • 功能: 将字符串 sstr 转化为小写
  • 返回值: sstr 小写
waf.contains(sstr,dstr)
  • 参数: sstr 为原字符串dstr 为查找字符串
  • 功能: 判断字符串 sstr 是否在字符串 dstr
  • 返回值: true 或 false
waf.rgxMatch(sstr,pat,ext)
  • 参数: sstr 为原字符串pat 为正则表达式ext 为正则属性
  • 功能: 在字符串 sstr 中匹配正则表达式 pat
  • 返回值: true 或 false
waf.kvFilter(v,match,valOnly)
  • 参数: v 为要匹配对象match 为匹配函数,valOnly 为 true 则只匹配 value
  • 功能: 用于匹配 cookie、queryString 等 keyvalue 键值对数据,在对象 v 中用 match 函 数匹配内容
  • 返回值: true,匹配内容或 false,nil
waf.knFilter(v,match,p)
  • 参数: v 为要匹配对象match 为匹配函数p 为 1 时匹配上传文件名,为 0 时文件内容
  • 功能: 用于过滤上传文件信息,在对象 v 中用 match 函数匹配内容
  • 返回值: true,匹配内容或 false,nil
waf.jsonFilter(v, match,parsed,valOnly)
  • 参数: v 为要匹配对象match 为匹配函数parsed 为 false 时解析类型为字符串 v 值,为 true 时解析类型为 table 的 v 值, valOnly 为 true 则只匹配 value
  • 功能: 用于遍历过滤请求中的 json 数据,在对象 v 中用 match 函数匹配内容
  • 返回值: true,匹配内容或 false,nil
waf.base64Decode(str)
  • 参数: str 为要解码的 base64 字符串
  • 功能: 用于解码 base64 数据为明文数据
  • 返回值: 明文字符串或 nil
waf.checkSQLI(str)
  • 参数: str 为要检测的字符串
  • 功能: 基于语义引擎检测 sql 注入攻击
  • 返回值: true 或 false
waf.checkRCE(str)
  • 参数: str 为要检测的字符串
  • 功能: 基于语义引擎检测命令注入攻击
  • 返回值: true 或 false
waf.checkPT(str)
  • 参数: str 为要检测的字符串
  • 功能: 基于语义引擎检测路径遍历攻击
  • 返回值: true 或 false
waf.strCounter(sstr,dstr)
  • 参数: sstr 为原字符串dstr 为查找字符串
  • 功能: 计算字符串 dstr 在 sstr 中出现的次数
  • 返回值: 整数
waf.pmMatch(sstr,dict)
  • 参数: sstr 为原字符串dict 为查找字典,以 lua 表的形式,如:{“aaa”, “bbb”, “ccc”}

  • 功能: 高效多模匹配多个字符串,发现其中一个字符串立即返回

  • 返回值: true字典中的字符串或 falsenil

waf.urlDecode(sstr)
  • 参数: sstr 为原字符串
  • 功能: 将 sstr 进行 url 解码还原成字符串
  • 返回值: 解码后的字符串
waf.htmlEntityDecode(sstr)
  • 参数: sstr 为原字符串
  • 功能: 将字符串 sstr 进行 html 实体解码
  • 返回值: 解码后的字符串
waf.hexDecode(sstr)
  • 参数: sstr 为原字符串
  • 功能: 将字符串 sstr 进行 hex 解码
  • 返回值: 解码后的字符串
waf.block(reset)
  • 参数: reset 为true时直接重置tcp不返回任何内容否则返回403页面
  • 功能: 拦截客户端请求直接重置客户端连接或返回403页面与return搭配使用

🍈 插件

?>南墙支持强大的插件扩展功能,方便用户自行实现一些特有功能。插件模板见:https://github.com/Safe3/uuWAF/blob/main/plugins/kafka-logger.lua 一个kafka日志记录插件。欢迎各位贡献安全插件详情见https://waf.uusec.com/#/guide/contribute

插件编写

一个标准的插件包含以下几个部分,每个部分若无功能实现可省略。

local _M = {
    version = 0.1,          --  插件版本
    name = "kafka-logger"   --  插件名称
}

-- 请求阶段过滤函数
function _M.req_filter(waf)

end

-- 返回header阶段过滤函数
function _M.resp_header_filter(waf)

end

-- 返回body阶段过滤函数
function _M.resp_body_filter(waf)

end

-- 日志记录阶段执行函数
function _M.log(waf)

end

return _M
  • 请求阶段过滤函数

  • 该阶段用于过滤客户端发送的请求数据waf变量同规则变量一致可自行实现该函数功能。

  • 返回header阶段过滤函数

  • 该阶段用于过滤服务器返回的header头数据waf变量同规则变量一致可自行实现该函数功能。

  • 返回body阶段过滤函数

  • 该阶段用于过滤服务器返回的body内容数据waf变量同规则变量一致可自行实现该函数功能。

  • 日志记录阶段执行函数

  • 该阶段用于日志记录阶段做一些日志处理与推送waf变量同规则变量一致可自行实现该函数功能。

插件使用

  1. 将插件文件如kafka-logger.lua 放于/uuwaf/waf/plugins/目录并修改文件扩展名为kafka-logger.w。

  2. 修改/uuwaf/conf/uuwaf.conf文件在init_by_lua_block段中waf = require("waf")下新增一行waf:use("扩展文件名")如启用kafka-logger.lua插件的示例如下

    waf = require("waf")
    waf:use("kafka-logger")
    
  3. 执行/uuwaf/waf-service -s restart使插件生效如果插件代码运行有问题可以在/uuwaf/logs/error.log中查看详细错误信息。

常用功能函数

各阶段数据共享

waf.ctx

有时为了在各个执行函数间共享同一个数据可以通过给waf.ctx赋值来实现

function _M.resp_body_filter(waf)
	waf.ctx = "share"
end

function _M.log(waf)
	log.errLog(waf.ctx)
end

记录错误日志

local log = require("waf.log")
log.errLog(...)
  • 参数: 可变参数,类型为字符串
  • 功能: 将信息写入错误日志/uuwaf/logs/error.log
  • 返回值:
log.encodeJson(obj)
  • 参数: lua table对象
  • 功能: 将lua table对象转化json字符串
  • 返回值: json字符串
log.broker(func...)
  • 参数: func为函数可变参数为传给函数func的参数
  • 功能: 代理执行函数func并传参。
  • 返回值:

😄 其它隐藏功能彩蛋,由用户自行去发掘。