Saltar a contenido

hyperscan: Hyperscan para nginx-module-lua

Instalación

Si no has configurado la suscripción al repositorio RPM, regístrate. Luego puedes proceder con los siguientes pasos.

CentOS/RHEL 7 o 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

Para usar esta biblioteca Lua con NGINX, asegúrate de que nginx-module-lua esté instalado.

Este documento describe lua-resty-hyperscan v0.3 lanzado el 14 de abril de 2022.


lua-resty-hyperscan - Hyperscan para Openresty

!!! Old Branch tuvo un problema de demasiados callbacks, porque luajit no soporta completamente CALLBACK. Así que necesitamos un C wrapper para manejar callbacks.

Primero, debes instalar openresty

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

## 

## 

## Sinopsis

Ejemplo de configuración

```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, "Fallo:", err)
            return
        end

       -- nuevo
       local obj = whs.block_new("a-uniq-name", true) -- true : habilitar modo de depuración

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

        -- compilar
        ret, err = obj:compile(patterns)
        if not ret then
           ngx.log(ngx.ERR, "la compilación del bloque hyperscan falló, ", 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")
                -- escanear
                local ret, id, from, to = obj:scan(ngx.var.uri)
                if ret then
                    return ngx.print("[", ngx.var.uri,"] coincide: ", id, " zona [", from, " - ", to, ").\n")
                else
                    return ngx.print("[", ngx.var.uri, "] no coincide con ninguna regla.\n")
                end
            }
        }
    }
}

Casos de prueba:

$ curl http://localhost
[/] no coincide con ninguna regla.

$ curl http://localhost/131111111
[/131111111] coincide: 1001 zona [0 - 3).

$ curl "http://localhost/      end"
[/      end] coincide: 1002 zona [0 - 4).

$ curl http://localhost/aaaaaaa
[/aaaaaaa] coincide: 1003 zona [0 - 3).

Métodos

Forma de cargar esta biblioteca

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

block_new

Crea una instancia de hyperscan para el modo bloque.

local handle, err = whs.block_new(name, debug)
if not handle then
    ngx.log(ngx.ERR, "razón: ", err)
end
Campo Nombre Tipo Lua Descripción
Parámetro name string nombre de la instancia, principalmente para el registro
debug boolean habilitar/deshabilitar el registro de depuración en syslog
Valor de Retorno handle table/nil referencia de la instancia
err string razón del fallo

block_free

Destruir una instancia de hyperscan para el modo bloque.

whs.block_free(name)

block_get

Obtener la referencia de la instancia por nombre.

local handle = whs.block_get(name)
Campo Nombre Tipo Lua Descripción
Parámetro name string nombre de la instancia
Valor de Retorno handle table/nil referencia de la instancia

vector_new

Crea una instancia de hyperscan para el modo vector.

local handle, err = whs.vector_new(name, debug)
if not handle then
    ngx.log(ngx.ERR, "razón: ", err)
end
Campo Nombre Tipo Lua Descripción
Parámetro name string nombre de la instancia, principalmente para el registro
debug boolean habilitar/deshabilitar el registro de depuración en syslog
Valor de Retorno handle table/nil referencia de la instancia
err string razón del fallo

vector_free

Destruir una instancia de hyperscan para el modo vector.

whs.vector_free(name)

vector_get

Obtener la referencia de la instancia por nombre.

local handle = whs.vector_get(name)
Campo Nombre Tipo Lua Descripción
Parámetro name string nombre de la instancia
Valor de Retorno handle table/nil referencia de la instancia

handle:compile

Compilar una expresión regular en una base de datos de Hyperscan.

--local handle = whs.block_new(name, debug)
local ok, err = handle:compile(patterns)
if not ok then
    ngx.log(ngx.ERR, "razón: ", err)
end
Campo Nombre Tipo Lua Descripción
parámetro patterns table lista de patrones
Valor de Retorno ok boolean éxito/fallo
err string razón del fallo

Lista de Patrones

Ejemplo
local patterns = {
    {id = 1001, pattern = "\\d3",       flag = "iu"   },
    {id = 1002, pattern = "\\s{3,5}",   flag = "dmsu" },
    {id = 1003, pattern = "[a-d]{2,7}", flag = ""     }
}
Flags
Flag Valor de Hyperscan Descripción
'i' HS_FLAG_CASELESS Establecer coincidencias sin distinción entre mayúsculas y minúsculas
'd' HS_FLAG_DOTALL Coincidir un . no excluirá nuevas líneas.
'm' HS_FLAG_MULTILINE Establecer anclaje de varias líneas.
's' HS_FLAG_SINGLEMATCH Establecer modo de coincidencia única.
'e' HS_FLAG_ALLOWEMPTY Permitir expresiones que pueden coincidir con búferes vacíos.
'u' HS_FLAG_UTF8 Habilitar modo UTF-8 para esta expresión.
'p' HS_FLAG_UCP Habilitar soporte de propiedades Unicode para esta expresión.
'f' HS_FLAG_PREFILTER Habilitar modo de prefiltrado para esta expresión.
'l' HS_FLAG_SOM_LEFTMOST Habilitar el informe del inicio de coincidencia más a la izquierda.
'c' HS_FLAG_COMBINATION Combinación lógica.
'q' HS_FLAG_QUIET No hacer ningún informe de coincidencias.

handle:scan

La coincidencia real de patrones tiene lugar para bases de datos de patrones en modo bloque.

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

La coincidencia real de patrones tiene lugar para bases de datos de patrones en modo vector.

--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, "coincidencia exitosa", id, from, to)
end
Campo Nombre Tipo Lua Descripción
Parámetro data string/string[] cadena a escanear (solo string[] en modo vector)
Valor de Retorno ok boolean true para coincidencia, false para no coincidencia
id number id de coincidencia
from number índice de byte de inicio de coincidencia (incluido)
to number índice de byte de fin de coincidencia (excluido)
dataindex number índice de datos coincidente (solo modo vector)

handle:free

Destruir una instancia de hyperscan.

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

GitHub

Puedes encontrar consejos adicionales de configuración y documentación para este módulo en el repositorio de GitHub para nginx-module-hyperscan.