Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
lua-resty-waf — 基于 OpenResty 技术栈构建的高性能 WAF | Kitploit
工具/GitHubGitHub/p0pr0ck5/lua-resty-waf
防御工具Web安全API 安全
GitHubp0pr0ck5/lua-resty-waf

lua-resty-waf

基于 OpenResty 技术栈构建的高性能 WAF

查看仓库
1.3k3052年前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

名称

lua-resty-waf - 基于 OpenResty 技术栈构建的高性能 WAF

目录

  • 名称
  • 状态
  • 描述
  • 要求
  • 性能
  • 安装
  • 概要
  • 公共函数
    • lua-resty-waf.load_secrules()
    • lua-resty-waf.init()
  • 公共方法
    • lua-resty-waf:new()
    • lua-resty-waf:set_option()
    • lua-resty-waf:set_var()
    • lua-resty-waf:sieve_rule()
    • lua-resty-waf:exec()
    • lua-resty-waf:write_log_events()
  • 选项
    • add_ruleset
    • add_ruleset_string
    • allow_unknown_content_types
    • allowed_content_types
    • debug
    • debug_log_level
    • deny_status
    • disable_pcre_optimization
    • event_log_altered_only
    • event_log_buffer_size
    • event_log_level
    • event_log_ngx_vars
    • event_log_periodic_flush
    • event_log_request_arguments
    • event_log_request_body
    • event_log_request_headers
    • event_log_ssl
    • event_log_ssl_sni_host
    • event_log_ssl_verify
    • event_log_socket_proto
    • event_log_target
    • event_log_target_host
    • event_log_target_path
    • event_log_target_port
    • hook_action
    • ignore_rule
    • ignore_ruleset
    • mode
    • nameservers
    • process_multipart_body
    • req_tid_header
    • res_body_max_size
    • res_body_mime_types
    • res_tid_header
    • score_threshold
    • storage_backend
    • storage_keepalive
    • storage_keepalive_timeout
    • storage_keepalive_pool_size
    • storage_memcached_host
    • storage_memcached_port
    • storage_redis_host
    • storage_redis_port
    • storage_zone
  • 阶段处理
  • 包含的规则集
  • 规则定义
  • 注意事项
    • 社区
    • 拉取请求
  • 路线图
  • 限制
  • 许可证
  • 缺陷
  • 另请参阅

状态

Build Status Codewake CII Best Practices

注意:lua-resty-waf 基本上已被弃用。这个项目在 ModSecurity 对 Nginx 不是可行选择的时代曾有用武之地;如今情况已不再如此。曾有在 2020 年重振该项目的尝试,但我没有资源来完成这项工作;这项工作在 redux 分支中部分完成。

描述

lua-resty-waf 是一个基于 OpenResty 技术栈构建的反向代理 WAF。它使用 Nginx Lua API 分析 HTTP 请求信息,并按照灵活的规则结构进行处理。lua-resty-waf 随附一套模拟 ModSecurity CRS 的规则集,以及一些在初始开发和测试期间构建的自定义规则,还有一个用于新兴威胁的小型虚拟补丁集。此外,lua-resty-waf 还随附自动翻译现有 ModSecurity 规则的工具,使用户无需学习新的规则语法即可扩展 lua-resty-waf 的实现。

lua-resty-waf 最初由 Robert Paprocki 为他在 Western Governor's University 的硕士论文开发。

要求

lua-resty-waf 需要几个第三方 resty lua 模块,尽管这些模块都已随 lua-resty-waf 打包,因此无需单独安装。建议在运行 OpenResty 软件包的系统上安装 lua-resty-waf;lua-resty-waf 尚未在使用独立 Nginx 源码和 Nginx Lua 模块包构建的平台上测试过。

为获得最佳的正则表达式编译性能,建议使用支持 JIT 编译的 PCRE 版本来构建 Nginx/OpenResty。如果您的操作系统未提供此版本,您可以将支持 JIT 的 PCRE 直接构建到您的 Nginx/OpenResty 中。为此,请在 --with-pcre 配置标志中引用 PCRE 源码的路径。例如:```sh

./configure --with-pcre=/path/to/pcre/source --with-pcre-jit

root@kitploit:~
您可以从 [PCRE 官网](http://www.pcre.org/) 下载 PCRE 源码。另请参阅这篇 [博客文章](https://www.cryptobells.com/building-openresty-with-pcre-jit/),了解如何构建带有 JIT 支持的 PCRE 库的 OpenResty 的分步指南。

## 性能

lua-resty-waf 的设计以效率和可扩展性为核心。它利用 Nginx 的异步处理模型和高效设计,尽可能快速地处理每个事务。负载测试表明,部署了所有自带规则集(这些规则集旨在模拟 ModSecurity CRS 背后的逻辑)的部署,每个请求的处理时间大约为 300-500 微秒;这相当于 [Cloudflare 的 WAF](https://www.cloudflare.com/waf) 所宣传的性能。测试在合理的硬件配置(E3-1230 CPU、32 GB RAM、2 x 840 EVO 组 RAID 0)上运行,最高达到约每秒 15,000 个请求。更多信息请参阅 [这篇博客文章](http://www.cryptobells.com/freewaf-a-high-performance-scalable-open-web-firewall)。

lua-resty-waf 的工作负载几乎完全受 CPU 限制。Lua VM 中的内存占用(不包括由 `lua-shared-dict` 支持的持久化存储)约为 2MB。

## 安装

提供了一个简单的 Makefile:```
# make && sudo make install

或者,通过 Luarocks 安装:```

luarocks install lua-resty-waf

root@kitploit:~
lua-resty-waf 使用 [OPM](https://github.com/openresty/opm) 包管理器,该管理器可在现代 OpenResty 发行版中使用。OPM 客户端工具要求系统的 `PATH` 环境变量中存在 `resty` 命令行工具。

请注意,默认情况下 lua-resty-waf 以 SIMULATE 模式运行,以避免立即影响应用程序;希望启用规则操作的用户必须显式将运行模式设置为 ACTIVE。

## Synopsis```lua
http {
    init_by_lua_block {
        -- use resty.core for performance improvement, see the status note above
        require "resty.core"

        -- require the base module
        local lua_resty_waf = require "resty.waf"

        -- perform some preloading and optimization
        lua_resty_waf.init()
    }

    server {
        location / {
            access_by_lua_block {
                local lua_resty_waf = require "resty.waf"

                local waf = lua_resty_waf:new()

                -- define options that will be inherited across all scopes
                waf:set_option("debug", true)
                waf:set_option("mode", "ACTIVE")

                -- this may be desirable for low-traffic or testing sites
                -- by default, event logs are not written until the buffer is full
                -- for testing, flush the log buffer every 5 seconds
                --
                -- this is only necessary when configuring a remote TCP/UDP
                -- socket server for event logs. otherwise, this is ignored
                waf:set_option("event_log_periodic_flush", 5)

                -- run the firewall
                waf:exec()
            }

            header_filter_by_lua_block {
                local lua_resty_waf = require "resty.waf"

                -- note that options set in previous handlers (in the same scope)
                -- do not need to be set again
                local waf = lua_resty_waf:new()

                waf:exec()
            }

            body_filter_by_lua_block {
                local lua_resty_waf = require "resty.waf"

                local waf = lua_resty_waf:new()

                waf:exec()
            }

            log_by_lua_block {
                local lua_resty_waf = require "resty.waf"

                local waf = lua_resty_waf:new()

                waf:exec()
            }
        }
    }
}

公共函数

lua-resty-waf.load_secrules()

从磁盘解析并初始化一个 ModSecurity SecRules 文件。请注意,这仍然需要通过 add_ruleset 添加规则集(必须使用文件的基本名称作为键)。

示例:```lua http { init_by_lua_block { local lua_resty_waf = require "resty.waf"

root@kitploit:~
    -- this translates and calculates a ruleset called 'ruleset_name'
    local ok, errs = pcall(function()
        lua_resty_waf.load_secrules("/path/to/secrules/ruleset_name")
    end)

    -- errs is an array-like table
    if errs then
        for i = 1, #errs do
            ngx.log(ngx.ERR, errs[i])
        end
    end
}

server {
    location / {
        access_by_lua_block {
            local lua_resty_waf = require "resty.waf"

            local waf = lua_resty_waf:new()

            -- in order to use the loaded ruleset, it must be added via
            -- the 'add_ruleset' option
            waf:set_option("add_ruleset", "ruleset_name")
        }
    }
}

}

root@kitploit:~
此外,`load_secrules` 可以接受一个可选的第二个参数,作为传递给各种转换函数的选项表。识别以下选项:

* *path*: 定义用于搜索操作符(如 @pmFromFile)数据文件的文件系统路径。如果未定义此键,则使用当前工作目录(`.`)
* *force*: 在无法转换规则变量时不报错并中止
* *loose*: 在无法转换规则操作时不报错并中止
* *quiet*: 在无法转换规则操作时不报错或警告

该函数还可以接受第三个选项作为表,用于捕获转换错误以供后续处理。如果此选项不存在或不是表,则转换错误将改为记录到错误日志中。

### lua-resty-waf.init()

根据默认分发的规则集所提供的内容,对规则和规则集进行一些预计算。建议(但非必需)调用此函数(不调用将导致轻微的性能损失)。此函数不应在此范围之外调用。

*示例*:```lua
http {
    init_by_lua_block {
        local lua_resty_waf = require "resty.waf"

        lua_resty_waf.init()
    }
}

Public Methods

lua-resty-waf:new()

实例化一个新的 lua-resty-waf 实例。您必须在希望运行 lua-resty-waf 的每个请求处理阶段调用此方法,并使用返回结果来调用更多的对象方法。

示例:```lua location / { access_by_lua_block { local lua_resty_waf = require "resty.waf"

root@kitploit:~
    local waf = lua_resty_waf:new()
}

}

root@kitploit:~
### lua-resty-waf:set_option()

按作用域配置选项。

*示例*:```lua
location / {
    access_by_lua_block {
        local lua_resty_waf = require "resty.waf"

        local waf = lua_resty_waf:new()

        -- enable debug logging only for this scope
        waf:set_option("debug", true)
    }
}

lua-resty-waf:set_var()

在执行 WAF 之前定义一个事务变量(存储在 TX 变量集合中)。这可用于定义复杂规则集(如 OWASP CRS)所使用的变量。

示例:```lua location / { access_by_lua_block { local lua_resty_waf = require "resty.waf"

root@kitploit:~
    local waf = lua_resty_waf:new()

    waf:set_var("FOO", "bar")
}

}

root@kitploit:~
请注意,与任何其他 ModSecurity 规则一样,变量的存在并不会对 WAF 处理产生功能上的改变;理解并使用 `TX` 变量是规则编写者的责任。

### lua-resty-waf:sieve_rule()

为给定规则定义集合排除。

*示例*:```lua
location / {
    access_by_lua_block {
        local lua_resty_waf = require "resty.waf"

        local waf = lua_resty_waf:new()

        local sieves = {
            {
                type   = "ARGS",
                elts   = "foo",
                action = "ignore",
            }
        }

        waf:sieve_rule("12345", sieves)
    }
}

See the rule sieves wiki page for details and advanced usage examples.

lua-resty-waf:exec()

运行规则引擎。默认情况下,引擎根据当前运行阶段执行。可以传入一个可选表,允许用户“模拟”执行不同的阶段。

示例:```lua location / { access_by_lua_block { local lua_resty_waf = require "resty.waf"

root@kitploit:~
    local waf = lua_resty_waf:new()

    -- execute according to access phase collections and rules
    waf:exec()
}

content_by_lua_block {
    local lua_resty_waf = require "waf"

    local waf = lua_resty_waf:new()

    -- execute header_filter rules, passing in a table of additional collections
    -- this assumes the 'request_headers' and 'status' Lua variables were
    -- declared and initialized elsewhere
    local opts = {
        phase = 'header_filter',
        collections = {
            REQUEST_HEADERS = request_headers,
            STATUS = status,
        }
    }

    waf:exec(opts)
}

}

root@kitploit:~
### lua-resty-waf:write_log_events()

写入从事务中生成的任何审计日志条目。仅当 `exec` 在 `log_by_lua` 处理器中被调用时,此步骤才是可选的。

*示例*:```lua
location / {
    log_by_lua_block {
        local lua_resty_waf = require "resty.waf"

        local waf = lua_resty_waf:new()

        -- write out any event log entries to the
        -- configured target, if applicable
        waf:write_log_events()
    }
}

选项

add_ruleset

默认: 无

在处理过程中添加一个额外的规则集。这允许用户实现自定义规则集,而不会覆盖自带的 rules 目录。额外的规则集必须位于 lua_package_path 中名为 "rules" 的文件夹内。

示例:```lua http { -- the rule file 50000.json must live at -- /path/to/extra/rulesets/rules/50000.json lua_package_path '/path/to/extra/rulesets/?.lua;;';

root@kitploit:~
server {
    location / {
        access_by_lua_block {
            waf:set_option("add_ruleset", "50000_extra_rules")
        }
    }
}

}

root@kitploit:~
可以通过向 `set_option` 传递一个值表来添加多个规则集。请注意,规则集名称在处理前会进行排序。规则集将按从低到高的排序顺序进行处理。

### add_ruleset_string

*默认*:无

添加一个在处理期间使用的额外规则集。这允许用户实现自定义规则集,而不会覆盖随附的规则目录。规则集以内联 Lua 字符串的形式定义,即转换后的规则集 JSON 结构。

*示例*:```lua
location / {
    access_by_lua_block {
        waf:set_option("add_ruleset_string", "70000_extra_rules", [=[{"access":[{"action":"DENY","id":73,"operator":"REGEX","opts":{},"pattern":"foo","vars":[{"parse":{"values":1},"type":"REQUEST_ARGS"}]}],"body_filter":[],"header_filter":[]}]=])
    }
}

请注意,规则集名称在处理前会进行排序,并且必须以字符串形式给出。规则集按从低到高的排序顺序进行处理。

allow_unknown_content_types

默认: false

指示 lua-resty-waf 在已发送的 Content-Type 头不在 allowed_content_types 表中时继续处理请求。此类请求的请求体将不会被 lua-resty-waf 处理(REQUEST_BODY 集合将为 nil)。这样,用户无需显式地将他们可能遇到的所有 Content-Type 头加入白名单。

示例:```lua location / { access_by_lua_block { waf:set_option("allow_unknown_content_types", true) } }

root@kitploit:~
### allowed_content_types

*默认值*: 无

定义了一个或多个允许的 Content-Type 头,除了默认的 Content-Type `application/x-www-form-urlencoded` 和 `multipart/form-data` 之外。当请求的内容类型与 `allowed_content_types` 之一匹配时,`REQUEST_BODY` 集合将被设置为一个字符串(而不是一个表);当请求的内容类型与这些值或 `application/x-www-form-urlencoded`、`multipart/form-data` 均不匹配时,该请求将被拒绝。

*示例*:```lua
location / {
    access_by_lua_block {
        -- define a single allowed Content-Type value
        waf:set_option("allowed_content_types", "text/xml")

        -- defines multiple allowed Content-Type values
        waf:set_option("allowed_content_types", { "text/html", "text/json", "application/json" })
    }
}

请注意,多次使用参数为 allowed_content_types 的 set_option 调用只会覆盖现有的选项表,因此如果你想定义多个允许的内容类型,则必须按照上述方式将它们定义为 Lua 表。

debug

默认值: false

禁用/启用调试日志记录。调试日志语句会打印到 error_log 中。请注意,调试日志记录开销非常大,不应在生产环境中使用。

示例:```lua location / { access_by_lua_block { waf:set_option("debug", true) } }

root@kitploit:~
### debug_log_level

*默认*: ngx.INFO

设置用于调试日志记录的 nginx 日志级别常量。

*示例*:```lua
location / {
    access_by_lua_block {
        waf:set_option("debug_log_level", ngx.DEBUG)
    }
}

deny_status

默认: ngx.HTTP_FORBIDDEN

设置拒绝请求时使用的状态码。

示例:```lua location / { access_by_lua_block { waf:set_option("deny_status", ngx.HTTP_NOT_FOUND) } }

root@kitploit:~
### disable_pcre_optimization

*默认值*: false

从所有 `ngx.re.match`、`ngx.re.find` 和 `ngx.re.sub` 调用中移除 `oj` 标志。在某些使用较旧 PCRE 库的情况下这可能有用,但会导致严重的性能下降,因此强烈不建议使用;建议用户改用带有现代、支持 JIT 的 PCRE 库来构建 OpenResty。

*示例*:```lua
location / {
    access_by_lua_block {
        waf:set_option("disable_pcre_optimization", true)
    }
}

注意:此行为已弃用,并将在未来版本中移除。

event_log_altered_only

默认值: true

确定是否在未被 lua-resty-waf 修改的事务中写入规则匹配的日志条目。“已修改”定义为 lua-resty-waf 对操作为 ACCEPT 或 DENY 的规则执行操作。当此选项未设置时,lua-resty-waf 将记录规则匹配,即使事务未被修改。默认情况下,lua-resty-waf 仅在事务被修改时写入匹配的日志条目。

示例:```lua location / { access_by_lua_block { waf:set_option("event_log_altered_only", false) } }

root@kitploit:~
注意:`mode` 不会影响事务是否被视为已修改。也就是说,如果匹配了带有 `DENY` 操作的规则,但 lua-resty-waf 正在以 `SIMULATE` 模式运行,该事务仍将被视为已修改,并且规则匹配会被记录。

### event_log_buffer_size

*默认值*: 4096

定义用于保存事件日志的缓冲区的阈值大小(以字节为单位)。当达到此阈值时,缓冲区将被刷新。

*示例*:```lua
location / {
    access_by_lua_block {
        -- 8 KB event log message buffer
        waf:set_option("event_log_buffer_size", 8192)
    }
}

event_log_level

默认: ngx.INFO

设置用于事件日志记录的 nginx 日志级别常量。

示例:```lua location / { access_by_lua_block { waf:set_option("event_log_level", ngx.WARN) } }

root@kitploit:~
### event_log_ngx_vars

*默认值*:空

定义 `ngx.var` 中的哪些额外变量会被写入日志事件。这是一种通用的方式,用于为告警增加额外的上下文。变量名将作为日志条目中 `ngx` 键下条目的键。如果该变量不存在于 nginx 变量中,则不会向事件中添加任何条目。

*示例*:```lua
location / {
    access_by_lua_block {
        waf:set_option("event_log_ngx_vars", "host")
        waf:set_option("event_log_ngx_vars", "request_id")
    }
}

生成的事件包含以下额外项目:```json { "ngx": { "host": "example.com", "request_id": "373bcce584e3c18a" } }

root@kitploit:~
### event_log_periodic_flush

*默认值*: none

定义一个时间间隔(以秒为单位),事件日志缓冲区将按照该间隔定期刷新。如果未配置任何值,缓冲区将不会定期刷新,而只会在达到 `event_log_buffer_size` 阈值时刷新。对于流量极低、可能在很长时间内不会收到任何事件日志数据的站点,请配置此选项,以防止陈旧数据滞留在缓冲区中。

*示例*:```lua
location / {
    access_by_lua_block {
        -- flush the event log buffer every 30 seconds
        waf:set_option("event_log_periodic_flush", 30)
    }
}

event_log_request_arguments

默认: false

当设置为 true 时,日志条目会在 uri_args 键下包含请求参数。

示例:```lua location / { access_by_lua_block { waf:set_option("event_log_request_arguments", true) } }

root@kitploit:~
### event_log_request_body

*默认*: false

当设置为 true 时,日志条目在 `request_body` 键下包含请求正文。

*示例*:```lua
location / {
    access_by_lua_block {
        waf:set_option("event_log_request_body", true)
    }
}

event_log_request_headers

默认: false

HTTP 请求的请求头会被复制到日志事件中,位于 request_headers 键下。

示例:```lua location / { access_by_lua_block { waf:set_option("event_log_request_headers", true) } }

root@kitploit:~
生成的事件包含这些额外项:```json
{
"request_headers": {
    "accept": "*/*",
    "user-agent": "curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3"
}
}

event_log_ssl

默认: false

通过 TCP/UDP 记录日志时启用 SSL 连接。

示例:```lua location / { access_by_lua_block { waf:set_option("event_log_ssl", true) } }

root@kitploit:~
### event_log_ssl_sni_host

*默认*: none

为 `lua-resty-logger-socket` 连接设置 SNI 主机。

*示例*:```lua
location / {
    access_by_lua_block {
        waf:set_option("event_log_ssl_sni_host", "loghost.example.com")
    }
}

event_log_ssl_verify

默认: false

通过 TCP/UDP 记录日志时,对 SSL 连接启用证书验证。

示例:```lua location / { access_by_lua_block { waf:set_option("event_log_ssl_verify", true) } }

root@kitploit:~
### event_log_socket_proto

*默认*: udp

定义通过远程套接字发送事件日志时使用的 IP 协议(TCP 或 UDP)。无论使用哪种协议,都将采用相同的缓冲和定期刷新逻辑。

*示例*:```lua
location / {
    access_by_lua_block {
        -- send logs via TCP
        waf:set_option("event_log_socket_proto", "tcp")
    }
}

event_log_target

默认值: error

定义事件日志的目标位置。lua-resty-waf 目前支持将事件日志写入错误日志、本地文件系统上的单独文件,或远程 TCP 或 UDP 服务器。在后两种情况下,事件日志会先进行缓冲,待达到设定的阈值后再刷新(有关事件日志选项的更多设置,请参阅下文)。

示例:```lua location / { access_by_lua_block { -- send event logs to the server's error_log location (default) waf:set_option("event_log_target", "error")

root@kitploit:~
    -- send event logs to a local file on disk
    waf:set_option("event_log_target", "file")

    -- send event logs to a remote server
    waf:set_option("event_log_target", "socket")
}

}

root@kitploit:~
注意,由于所使用的日志库存在限制,只能定义一个目标套接字。也就是说,您只能配置一个具有特定主机/端口组合的 `socket` 目标;如果配置了第二个主机/端口组合,数据将无法正确记录。

### event_log_target_host

*默认值*: none

定义指向远程服务器的事件日志的目标服务器。

*示例*:```lua
location / {
    access_by_lua_block {
        waf:set_option("event_log_target_host", "10.10.10.10")
    }
}

event_log_target_path

默认: none

定义事件日志的目标路径,这些日志针对本地文件系统位置。

示例:```lua location / { access_by_lua_block { waf:set_option("event_log_target_path", "/var/log/lua-resty-waf/event.log") } }

root@kitploit:~
该路径必须位于 nginx 用户可写的位置。请注意,从本质上讲,磁盘日志记录在高并发环境中可能导致显著的性能下降。

### event_log_target_port

*默认值*: 无

定义指向远程服务器的事件日志的目标端口。

*示例*:```lua
location / {
    access_by_lua_block {
        waf:set_option("event_log_target_port", 9001)
    }
}

hook_action

默认值: none

覆盖规则匹配时执行的操作的功能。有关更多详细信息,请参阅示例。

示例:```lua

root@kitploit:~
location / {
    access_by_lua_block {
        local deny_override = function(waf, ctx)
            ngx.log(ngx.INFO, "Overriding DENY action")
            ngx.status = 404
        end

        -- override the DENY action with the function defined above
        waf:set_option("hook_action", "DENY", deny_override)
    }
}
root@kitploit:~
### ignore_rule

*默认值*:无

指示模块忽略指定的规则 ID。请注意,忽略链中的某条规则将导致整条链被忽略,并且处理将继续到该链之后的下一条规则。

*示例*:```lua
location / {
    access_by_lua_block {
        waf:set_option("ignore_rule", 40294)
        waf:set_option("ignore_rule", {40002, 41036})
    }
}

Multiple rules can be ignored by passing a table of rule IDs to set_option.

ignore_ruleset

Default: none

Instructs the module to ignore an entire ruleset. This can be useful when some rulesets (such as the SQLi or XSS CRS rulesets) are too prone to false positives, or aren't applicable to your application.

Example:```lua location / { access_by_lua_block { waf:set_option("ignore_ruleset", "41000_sqli") } }

root@kitploit:~
### mode

*默认*: SIMULATE

设置模块的运行模式。可选值为 ACTIVE、INACTIVE 和 SIMULATE。在 ACTIVE 模式下,规则匹配会被记录并执行操作。在 SIMULATE 模式下,lua-resty-waf 会遍历每个已启用的规则并记录规则匹配情况,但不会执行给定运行中指定的操作。INACTIVE 模式会阻止模块运行。

默认情况下,如果没有显式设置模式,则选择 SIMULATE;这要求新用户通过将模式设置为 ACTIVE 来主动实施拦截。

*示例*:```lua
location / {
    access_by_lua_block {
        waf:set_option("mode", "ACTIVE")
    }
}

nameservers

默认值: none

设置用于 RBL 查询的 DNS 解析器。目前仅支持 UDP/53 流量。此选项必须定义为数字地址,而不是主机名。如果未定义此选项,所有 RBL 查询规则将返回 false。

示例:```lua location / { access_by_lua_block { waf:set_option("nameservers", "10.10.10.10") } }

root@kitploit:~
### process_multipart_body

*默认值* true

启用对 multipart/form-data 请求体(如果存在)的处理,使用 `lua-resty-upload` 模块。将来,lua-resty-waf 可能会使用此处理来对上传请求体执行更严格的检查;目前该模块仅对请求体执行最小限度的健全性检查,并且如果请求体无效,不会记录事件。如果您不需要此检查,或者上游模块中的错误导致 HTTP 上传出现问题,请禁用此选项。

*示例*:```lua
location / {
    access_by_lua_block {
        -- disable processing of multipart/form-data requests
        -- note that the request body will still be sent to the upstream
        waf:set_option("process_multipart_body", false)
    }
}

req_tid_header

默认值: false

在向上游服务器发送的请求中设置一个 HTTP 头 X-Lua-Resty-WAF-ID,其值为事务 ID。该 ID 将与调试日志(如果启用)中的事务 ID 相关联。这对于请求跟踪或调试目的非常有用。

示例:```lua location / { access_by_lua_block { waf:set_option("req_tid_header", true) } }

root@kitploit:~
### res_body_max_size

*默认值*: 1048576 (1 MB)

定义内容长度阈值,超过该阈值的响应体将不会被处理。响应体的大小由 Content-Length 响应头确定。如果响应中不存在该响应头,则响应体将永远不会被处理。

*示例*:```lua
location / {
    access_by_lua_block {
        -- increase the max response size to 2 MB
        waf:set_option("res_body_max_size", 1024 * 1024 * 2)
    }
}

请注意,本质上,为了正确地将响应用作集合,必须缓冲整个响应体,因此在没有充分理由(以及充足的服务器资源)的情况下,不建议显著增大此数值。

res_body_mime_types

默认值: "text/plain", "text/html"

定义 lua-resty-waf 将处理响应体所使用的 MIME 类型。该值由 Content-Type 响应头决定。如果该响应头不存在,或者响应类型不在此列表中,则不会处理响应体。设置此选项会将给定的 MIME 类型添加到现有的默认值 text/plain 和 text/html 中。

示例:```lua location / { access_by_lua_block { -- mime types that will be processed are now text/plain, text/html, and text/json waf:set_option("res_body_mime_types", "text/json") } }

root@kitploit:~
### res_tid_header

*默认值*: false

在下游响应中设置一个 HTTP 头 `X-Lua-Resty-WAF-ID`,其值为事务 ID。该 ID 将与调试日志(如果已设置)中的事务 ID 相关联。这对于请求跟踪或调试目的非常有用。

*示例*:```lua
location / {
    access_by_lua_block {
        waf:set_option("res_tid_header", true)
    }
}

score_threshold

默认: 5

设置异常评分的阈值。当达到阈值时,lua-resty-waf 将拒绝该请求。

示例:```lua location / { access_by_lua_block { waf:set_option("score_threshold", 10) } }

root@kitploit:~
### storage_backend

*默认*: dict

定义用于持久变量存储的引擎。当前可用的选项有 *dict*(ngx_lua 共享内存区)、*memcached* 和 *redis*。

*示例*:```lua
location / {
    acccess_by_lua_block {
        waf:set_option("storage_backend", "memcached")
    }
}

storage_keepalive

默认: true

启用或禁用与远程持久化存储主机连接的 TCP keepalive。

示例:```lua location / { acccess_by_lua_block { waf:set_option("storage_keepalive", false) } }

root@kitploit:~
### storage_keepalive_timeout

*默认值*: 10000

配置远程持久化存储主机的 cosocket 保持连接池的超时时间(以毫秒为单位)。

*示例*:```lua
location / {
    acccess_by_lua_block {
        waf:set_option("storage_keepalive_timeout", 30000)
    }
}

storage_keepalive_pool_size

默认: 100

为远程持久化存储主机配置 cosocket keepalive 连接池的大小。

示例:```lua location / { acccess_by_lua_block { waf:set_option("storage_keepalive_pool_size", 50) } }

root@kitploit:~
### storage_memcached_host

*默认值*: 127.0.0.1

定义当使用 memcached 作为持久变量存储引擎时要使用的主机。

*示例*:```lua
location / {
    acccess_by_lua_block {
        waf:set_option("storage_memcached_host", "10.10.10.10")
    }
}

storage_memcached_port

默认: 11211

定义当使用 memcached 作为持久化变量存储引擎时要使用的端口。

示例:```lua location / { acccess_by_lua_block { waf:set_option("storage_memcached_port", 11221) } }

root@kitploit:~
### storage_redis_host

*默认值*: 127.0.0.1

定义在使用 redis 作为持久化变量存储引擎时要使用的主机。

*示例*:```lua
location / {
    acccess_by_lua_block {
        waf:set_option("storage_redis_host", "10.10.10.10")
    }
}

storage_redis_port

默认值: 6379

定义在使用 redis 作为持久化变量存储引擎时使用的端口。

示例:```lua location / { acccess_by_lua_block { waf:set_option("storage_redis_port", 6397) } }

root@kitploit:~
### storage_zone

*默认值*: none

定义用于保存持久化存储数据的 `lua_shared_dict`。该 zone 必须在配置的 `http{}` 块中定义。

*示例*:_```lua
http {
    -- define a 64M shared memory zone to hold persistent storage data
    lua_shared_dict persistent_storage 64m;
}

location / {
    access_by_lua_block {
        waf:set_option("storage_zone", "persistent_storage")
    }
}

可以定义和使用多个共享区域,但每个配置位置只能定义一个区域。如果某个区域已满,共享字典接口无法添加更多键,则会在错误日志中记录以下内容:

Error adding key to persistent storage, increase the size of the lua_shared_dict

阶段处理

lua-resty-waf 被设计为在请求生命周期的多个阶段中运行。规则可以在以下阶段中处理:

  • access:此阶段提供请求信息,例如 URI、请求头、URI 参数和请求体。
  • header_filter:此阶段提供响应头和 HTTP 状态码。
  • body_filter:此阶段提供响应体。
  • log:事件日志在此阶段完成时自动写入。

这些阶段分别对应相应的 Nginx lua 处理程序(access_by_lua、header_filter_by_lua、body_filter_by_lua 和 log_by_lua)。请注意,在此列表之外的 lua 阶段处理程序中运行 lua-resty-waf 将导致行为异常。在较早阶段可用的所有数据在较后阶段中同样可用。也就是说,在 access 阶段可用的数据在 header_filter 和 body_filter 阶段中同样可用,但反之则不然。

内置规则集

lua-resty-waf 随附了许多规则集,旨在模拟 ModSecurity CRS 的功能。为方便参考,这些规则集列举如下:

  • 11000_whitelist:本地策略白名单
  • 20000_http_violation:HTTP 协议违规
  • 21000_http_anomaly:HTTP 协议异常
  • 35000_user_agent:恶意/可疑用户代理
  • 40000_generic_attack:通用攻击
  • 41000_sqli:SQL 注入
  • 42000_xss:XSS
  • 90000_custom:自定义规则/虚拟补丁
  • 99000_scoring:异常分数处理

规则定义

lua-resty-waf 从存储在磁盘上的 JSON 数据块中解析规则定义。规则根据用途和严重性进行分组,并定义为一个规则集。内置的规则集旨在模拟 ModSecurity CRS 的某些功能,特别是 base_rules 定义。此外,随附的 modsec2lua-resty-waf.pl 脚本可用于将额外的或自定义的规则集转换为与 lua-resty-waf 兼容的 JSON 数据块。

请注意,翻译脚本存在若干限制,涉及不支持的 action、collection 和 operator。请参阅此 wiki 页面以获取已知不兼容性的最新列表。

备注

社区

有一个 Freenode IRC 频道 #lua-resty-waf。Travis CI 会向此频道发送通知;也欢迎在此频道中提问/留言。

此外,CodeWake 上提供问答(Q/A):

Codewake

拉取请求

请将所有拉取请求(pull request)指向 development 分支;如果 PR 是一项重大变更,则指向功能分支。对 master 的提交仅应为文档更新或其他对模块本身无影响的更改(并且可以干净地合并到 development 分支)。

路线图

  • 扩展虚拟补丁规则集:扩大对新出现威胁的覆盖范围。
  • 扩展集成/验收测试:扩大对常见威胁和使用场景的覆盖范围。
  • 扩展 ModSecurity 语法翻译:支持更多运算符、变量和动作。
  • 常见应用程序配置文件:为常见 CMS/应用程序调优的规则集。
  • 支持多个 socket/文件日志记录目标:可能需要分叉 lua-resty-logger-socket 项目。

限制

lua-resty-waf 正在持续开发和改进中,因此其功能和性能可能存在限制。当前已知的限制可在本仓库的 GitHub issue 跟踪器中找到。

许可证

本程序是自由软件:您可以根据自由软件基金会发布的 GNU 通用公共许可证的条款(许可证第 3 版,或(由您选择)任何更高版本)重新分发和/或修改它。

分发本程序是希望它会有用,但没有任何担保;甚至没有适销性或特定用途适用性的默示担保。有关详情,请参阅 GNU 通用公共许可证。

您应该已经随本程序收到一份 GNU 通用公共许可证的副本。如果没有,请参阅 http://www.gnu.org/licenses/。

Bug 报告

请通过 GitHub issue 跟踪器创建工单(ticket)来报告 bug。

另请参阅

  • OpenResty 项目:http://openresty.org/
  • 我的个人博客,提供 lua-resty-waf 开发的更新和说明:http://www.cryptobells.com/tag/lua-resty-waf/
下载工具