跳转至

hyperscan: Hyperscan for nginx-module-lua

安装

如果您尚未设置 RPM 仓库订阅,请 注册。然后您可以继续以下步骤。

CentOS/RHEL 7 或 Amazon Linux 2

yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-hyperscan

CentOS/RHEL 8+、Fedora Linux、Amazon Linux 2023

dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-hyperscan

要在 NGINX 中使用此 Lua 库,请确保已安装 nginx-module-lua

本文档描述了 lua-resty-hyperscan v0.3,于 2022 年 4 月 14 日发布。


lua-resty-hyperscan - Hyperscan for Openresty

!!! 旧分支 遇到 太多回调 问题,因为 luajit 并不完全支持 CALLBACK。因此我们需要一个 C 包装器 来处理回调。

首先,您应该安装 openresty

git clone git@github.com:LubinLew/lua-resty-hyperscan.git cd lua-resty-hyperscan make make install make test

##

##

## 概述

配置示例

```lua
user  nobody;
worker_processes  auto;
error_log logs/error.log error;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    access_log  logs/access.log;

    init_by_lua_block {
       local whs, err = require('hyperscan')
        if not whs then
            ngx.log(ngx.ERR, "失败:", err)
            return
        end

       -- 新建
       local obj = whs.block_new("a-uniq-name", true) -- true : 启用调试模式

       local patterns = {
           {id = 1001, pattern = "\\d3",       flag = "iu"},
           {id = 1002, pattern = "\\s{3,5}",   flag = "u"},
           {id = 1003, pattern = "[a-d]{2,7}", flag = ""}
       }

        -- 编译
        ret, err = obj:compile(patterns)
        if not ret then
           ngx.log(ngx.ERR, "hyperscan 块编译失败, ", err)
           return
        end
    }

    server {
        listen       80;
        server_name  localhost;

        location / {
            content_by_lua_block {
                local whs = require('hyperscan')
                local obj = whs.block_get("a-uniq-name")
                -- 扫描
                local ret, id, from, to = obj:scan(ngx.var.uri)
                if ret then
                    return ngx.print("[", ngx.var.uri,"] 匹配: ", id, " 区域 [", from, " - ", to, ").\n")
                else
                    return ngx.print("[", ngx.var.uri, "] 不匹配任何规则.\n")
                end
            }
        }
    }
}

测试用例:

$ curl http://localhost
[/] 不匹配任何规则。

$ curl http://localhost/131111111
[/131111111] 匹配: 1001 区域 [0 - 3)。

$ curl "http://localhost/      end"
[/      end] 匹配: 1002 区域 [0 - 4)。

$ curl http://localhost/aaaaaaa
[/aaaaaaa] 匹配: 1003 区域 [0 - 3)

方法

加载此库的方法

local whs,err = require('hyperscan')
if not whs then
    ngx.log(ngx.ERR, "原因: ", err)
end

block_new

为块模式创建一个 hyperscan 实例。

local handle, err = whs.block_new(name, debug)
if not handle then
    ngx.log(ngx.ERR, "原因: ", err)
end
字段 名称 Lua 类型 描述
参数 name string 实例名称,主要用于日志
debug boolean 启用/禁用将调试日志写入 syslog
返回值 handle table/nil 实例引用
err string 失败原因

block_free

销毁块模式的 hyperscan 实例。

whs.block_free(name)

block_get

通过名称获取实例引用。

local handle = whs.block_get(name)
字段 名称 Lua 类型 描述
参数 name string 实例名称
返回值 handle table/nil 实例引用

vector_new

为向量模式创建一个 hyperscan 实例。

local handle, err = whs.vector_new(name, debug)
if not handle then
    ngx.log(ngx.ERR, "原因: ", err)
end
字段 名称 Lua 类型 描述
参数 name string 实例名称,主要用于日志
debug boolean 启用/禁用将调试日志写入 syslog
返回值 handle table/nil 实例引用
err string 失败原因

vector_free

销毁向量模式的 hyperscan 实例。

whs.vector_free(name)

vector_get

通过名称获取实例引用。

local handle = whs.vector_get(name)
字段 名称 Lua 类型 描述
参数 name string 实例名称
返回值 handle table/nil 实例引用

handle:compile

将正则表达式编译成 Hyperscan 数据库。

--local handle = whs.block_new(name, debug)
local ok, err = handle:compile(patterns)
if not ok then
    ngx.log(ngx.ERR, "原因: ", err)
end
字段 名称 Lua 类型 描述
参数 patterns table 模式列表
返回值 ok boolean 成功/失败
err string 失败原因

模式列表

示例
local patterns = {
    {id = 1001, pattern = "\\d3",       flag = "iu"   },
    {id = 1002, pattern = "\\s{3,5}",   flag = "dmsu" },
    {id = 1003, pattern = "[a-d]{2,7}", flag = ""     }
}
标志
标志 Hyperscan 值 描述
'i' HS_FLAG_CASELESS 设置不区分大小写的匹配
'd' HS_FLAG_DOTALL 匹配 . 不会排除换行符。
'm' HS_FLAG_MULTILINE 设置多行锚定。
's' HS_FLAG_SINGLEMATCH 设置仅单次匹配模式。
'e' HS_FLAG_ALLOWEMPTY 允许可以匹配空缓冲区的表达式。
'u' HS_FLAG_UTF8 启用此表达式的 UTF-8 模式。
'p' HS_FLAG_UCP 启用此表达式的 Unicode 属性支持。
'f' HS_FLAG_PREFILTER 启用此表达式的预过滤模式。
'l' HS_FLAG_SOM_LEFTMOST 启用最左侧匹配报告。
'c' HS_FLAG_COMBINATION 逻辑组合。
'q' HS_FLAG_QUIET 不进行任何匹配报告。

handle:scan

实际的模式匹配发生在块模式的模式数据库中。

--local handle = whs.block_get(name)
local ok, id, from, to = handle:scan(data)
if ok then
    ngx.log(ngx.INFO, "匹配成功", id, from, to)
end

实际的模式匹配发生在向量模式的模式数据库中。

--local handle = whs.vector_get(name)
--local data = {"s","s2"}
--local data = "s"
local ok, id, dataindex, to = handle:scan(data)
if ok then
    ngx.log(ngx.INFO, "匹配成功", id, from, to)
end
字段 名称 Lua 类型 描述
参数 data string/string[] 要扫描的字符串(仅向量模式为 string[])
返回值 ok boolean true 表示匹配,false 表示不匹配
id number 匹配 ID
from number 匹配开始字节数组索引(包括自身)
to number 匹配结束字节数组索引(不包括自身)
dataindex number 匹配数据索引(仅向量模式)

handle:free

销毁一个 hyperscan 实例。

--local handle = whs.block_get(name)
handle:free()

GitHub

您可以在 nginx-module-hyperscan 的 GitHub 仓库 中找到此模块的其他配置提示和文档。