
WAF de alto rendimiento construido sobre la pila OpenResty
lua-resty-waf - WAF de alto rendimiento construido sobre el stack de OpenResty
NOTA: lua-resty-waf está esencialmente abandonado. Este proyecto tenía utilidad en una época en la que ModSecurity para Nginx no era una opción viable; ya no es el caso. Hubo un intento de revitalizar el proyecto en 2020, pero no tengo los recursos para completarlo; este trabajo está parcialmente completo en la rama redux.
lua-resty-waf es un WAF de proxy inverso construido con el stack de OpenResty. Utiliza la API Lua de Nginx para analizar la información de las solicitudes HTTP y procesarlas contra una estructura de reglas flexible. lua-resty-waf se distribuye con un conjunto de reglas que imita el CRS de ModSecurity, además de algunas reglas personalizadas creadas durante el desarrollo y las pruebas iniciales, y un pequeño parche virtual para amenazas emergentes. Adicionalmente, lua-resty-waf se distribuye con herramientas para traducir automáticamente reglas existentes de ModSecurity, lo que permite a los usuarios ampliar la implementación de lua-resty-waf sin necesidad de aprender una nueva sintaxis de reglas.
lua-resty-waf fue desarrollado inicialmente por Robert Paprocki para su tesis de maestría en Western Governor's University.
lua-resty-waf requiere varios módulos Lua resty de terceros, aunque todos vienen empaquetados con lua-resty-waf, por lo que no necesitan instalarse por separado. Se recomienda instalar lua-resty-waf en un sistema que ejecute el paquete de software OpenResty; lua-resty-waf no ha sido probado en plataformas construidas con paquetes separados de código fuente de Nginx y del módulo Lua de Nginx.
Para obtener un rendimiento óptimo de compilación de expresiones regulares, se recomienda compilar Nginx/OpenResty con una versión de PCRE que soporte compilación JIT. Si tu sistema operativo no la proporciona, puedes compilar PCRE con capacidad JIT directamente en tu compilación de Nginx/OpenResty. Para ello, indica la ruta al código fuente de PCRE en el flag de configuración --with-pcre. Por ejemplo:```sh
Puedes descargar el código fuente de PCRE desde el [sitio web de PCRE](http://www.pcre.org/). Consulta también esta [entrada de blog](https://www.cryptobells.com/building-openresty-with-pcre-jit/) para ver una guía paso a paso sobre cómo compilar OpenResty con una librería PCRE con JIT habilitado.
## Rendimiento
lua-resty-waf fue diseñado pensando en la eficiencia y la escalabilidad. Aprovecha el modelo de procesamiento asíncrono de Nginx y un diseño eficiente para procesar cada transacción lo más rápido posible. Las pruebas de carga han demostrado que los despliegues que implementan todos los conjuntos de reglas proporcionados, diseñados para imitar la lógica detrás del ModSecurity CRS, procesan transacciones en aproximadamente 300-500 microsegundos por petición; esto equivale al rendimiento anunciado por el [WAF de Cloudflare](https://www.cloudflare.com/waf). Las pruebas se ejecutaron sobre una pila de hardware razonable (CPU E3-1230, 32 GB de RAM, 2 x 840 EVO en RAID 0), alcanzando un máximo de aproximadamente 15,000 peticiones por segundo. Consulta [esta entrada de blog](http://www.cryptobells.com/freewaf-a-high-performance-scalable-open-web-firewall) para más información.
La carga de trabajo de lua-resty-waf está casi exclusivamente limitada por CPU. La huella de memoria en la máquina virtual de Lua (excluyendo el almacenamiento persistente respaldado por `lua-shared-dict`) es de aproximadamente 2 MB.
## Instalación
Se proporciona un sencillo Makefile:```
# make && sudo make install
Alternativamente, instala mediante Luarocks:```
lua-resty-waf hace uso del gestor de paquetes [OPM](https://github.com/openresty/opm), disponible en las distribuciones modernas de OpenResty. Las herramientas cliente de OPM requieren que la herramienta de línea de comandos `resty` esté disponible en la variable de entorno `PATH` de tu sistema.
Ten en cuenta que, por defecto, lua-resty-waf se ejecuta en modo SIMULATE, para evitar afectar inmediatamente a una aplicación; los usuarios que deseen habilitar las acciones de las reglas deben establecer explícitamente el modo operativo en ACTIVE.
## Sinopsis```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()
}
}
}
}
Traduce e inicializa un archivo de reglas ModSecurity SecRules desde el disco. Ten en cuenta que esto aún requiere que el conjunto de reglas se agregue mediante add_ruleset (el nombre base del archivo debe proporcionarse como clave).
Ejemplo:```lua http { init_by_lua_block { local lua_resty_waf = require "resty.waf"
-- 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")
}
}
}
}
Además, `load_secrules` puede aceptar un segundo argumento opcional como una tabla de opciones para pasar a varias funciones de traducción. Se reconocen las siguientes opciones:
* *path*: Define una ruta del sistema de archivos para buscar archivos de datos para operadores como @pmFromFile. Si no se define dicha clave, se utiliza el directorio de trabajo actual (`.`)
* *force*: No mostrar error ni abortar al fallar la traducción de una variable de regla
* *loose*: No mostrar error ni abortar al fallar la traducción de una acción de regla
* *quiet*: No mostrar error ni advertencia al fallar la traducción de una acción de regla
Esta función también puede aceptar una tercera opción como tabla para capturar errores de traducción y procesarlos posteriormente. Si esta opción no está presente o no es una tabla, los errores de traducción se registrarán en el registro de errores.
### lua-resty-waf.init()
Realiza algún precálculo de reglas y conjuntos de reglas, basado en lo que se ha puesto a disposición mediante los conjuntos de reglas distribuidos por defecto. Se recomienda, aunque no es obligatorio, llamar a esta función (no hacerlo resultará en una pequeña penalización de rendimiento). Esta función nunca debe llamarse fuera de este ámbito.
*Ejemplo*:```lua
http {
init_by_lua_block {
local lua_resty_waf = require "resty.waf"
lua_resty_waf.init()
}
}
Instancie una nueva instancia de lua-resty-waf. Debe llamar a este método en cada fase del manejador de solicitudes en la que desee ejecutar lua-resty-waf, y utilizar el resultado devuelto para llamar a otros métodos del objeto.
Ejemplo:```lua location / { access_by_lua_block { local lua_resty_waf = require "resty.waf"
local waf = lua_resty_waf:new()
}
}
### lua-resty-waf:set_option()
Configura una opción a nivel de ámbito.
*Ejemplo*:```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)
}
}
Define una variable de transacción (almacenada en la colección de variables TX) antes de ejecutar el WAF. Esto se puede usar para definir variables utilizadas por conjuntos de reglas complejos como el OWASP CRS.
Ejemplo:```lua location / { access_by_lua_block { local lua_resty_waf = require "resty.waf"
local waf = lua_resty_waf:new()
waf:set_var("FOO", "bar")
}
}
Tenga en cuenta que, como con cualquier otra regla de ModSecurity, la existencia de una variable no conlleva ningún cambio funcional en el procesamiento del WAF; es responsabilidad del autor de la regla comprender y utilizar las variables `TX`.
### lua-resty-waf:sieve_rule()
Define una exclusión de colección para una regla determinada.
*Ejemplo*:```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)
}
}
Consulte la página wiki de rule sieves para obtener detalles y ejemplos de uso avanzado.
Ejecuta el motor de reglas. Por defecto, el motor se ejecuta de acuerdo con la fase actualmente en curso. Se puede pasar una tabla opcional, lo que permite a los usuarios "simular" la ejecución de una fase diferente.
Ejemplo:```lua location / { access_by_lua_block { local lua_resty_waf = require "resty.waf"
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)
}
}
### lua-resty-waf:write_log_events()
Escriba cualquier entrada de registro de auditoría generada por la transacción. Esto es solo opcional cuando se llama a `exec` en un manejador `log_by_lua`.
*Ejemplo*:```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()
}
}
Predeterminado: ninguno
Añade un conjunto de reglas adicional para usar durante el procesamiento. Esto permite a los usuarios implementar conjuntos de reglas personalizados sin pisar el directorio de reglas incluido. Los conjuntos de reglas adicionales deben residir dentro de una carpeta llamada "rules" que se encuentre dentro del lua_package_path.
Ejemplo:```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;;';
server {
location / {
access_by_lua_block {
waf:set_option("add_ruleset", "50000_extra_rules")
}
}
}
}
Se pueden añadir múltiples rulesets pasando una tabla de valores a `set_option`. Tenga en cuenta que los nombres de los rulesets se ordenan antes del procesamiento. Los rulesets se procesan en orden de menor a mayor.
### add_ruleset_string
*Por defecto*: ninguno
Añade un ruleset adicional para usar durante el procesamiento. Esto permite a los usuarios implementar rulesets personalizados sin sobrescribir el directorio de rules incluido. Los rulesets se definen en línea como una cadena Lua, en forma de una estructura JSON de ruleset traducida.
*Ejemplo*:```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":[]}]=])
}
}
Note that ruleset names are sorted before processing, and must be given as strings. Rulesets are processed in a low-to-high sorted order.
Predeterminado: false
Indica a lua-resty-waf que continúe procesando la solicitud cuando se haya enviado una cabecera Content-Type que no esté en la tabla allowed_content_types. Estas solicitudes no tendrán su cuerpo de solicitud procesado por lua-resty-waf (la colección REQUEST_BODY será nil). De este modo, los usuarios no necesitan incluir explícitamente en la lista blanca todas las posibles cabeceras Content-Type que puedan encontrar.
Ejemplo:```lua location / { access_by_lua_block { waf:set_option("allow_unknown_content_types", true) } }
### allowed_content_types
*Predeterminado*: ninguno
Define uno o más encabezados Content-Type que se permitirán, además de los Content-Type predeterminados `application/x-www-form-urlencoded` y `multipart/form-data`. Una solicitud cuyo tipo de contenido coincida con uno de `allowed_content_types` establecerá la colección `REQUEST_BODY` en una única cadena que contiene (en lugar de una tabla); una solicitud cuyo tipo de contenido no coincida con ninguno de estos valores, ni con `application/x-www-form-urlencoded` ni con `multipart/form-data`, será rechazada.
*Ejemplo*:```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" })
}
}
Tenga en cuenta que múltiples llamadas a set_option con un parámetro de allowed_content_types simplemente sobrescribirán la tabla de opciones existente, por lo que si desea definir múltiples tipos de contenido permitidos, debe definirlos como una tabla Lua como se muestra arriba.
Default: false
Deshabilita/habilita el registro de depuración. Las declaraciones de registro de depuración se imprimen en error_log. Tenga en cuenta que el registro de depuración es muy costoso y no debe usarse en entornos de producción.
Example:```lua location / { access_by_lua_block { waf:set_option("debug", true) } }
### debug_log_level
*Default*: ngx.INFO
Establece la constante de nivel de registro de nginx utilizada para el registro de depuración.
*Ejemplo*:```lua
location / {
access_by_lua_block {
waf:set_option("debug_log_level", ngx.DEBUG)
}
}
Por defecto: ngx.HTTP_FORBIDDEN
Establece el estado que se utilizará al denegar solicitudes.
Ejemplo:```lua location / { access_by_lua_block { waf:set_option("deny_status", ngx.HTTP_NOT_FOUND) } }
### disable_pcre_optimization
*Valor predeterminado*: false
Elimina las banderas `oj` de todas las llamadas a `ngx.re.match`, `ngx.re.find` y `ngx.re.sub`. Esto puede ser útil en algunos casos en los que se utilizan bibliotecas PCRE antiguas, pero causará una degradación severa del rendimiento, por lo que su uso está fuertemente desaconsejado; en su lugar, se recomienda a los usuarios compilar OpenResty con una biblioteca PCRE moderna y compatible con JIT.
*Ejemplo*:```lua
location / {
access_by_lua_block {
waf:set_option("disable_pcre_optimization", true)
}
}
Nota: Este comportamiento está obsoleto y se eliminará en versiones futuras.
Predeterminado: true
Determina si se deben escribir entradas de registro para coincidencias de reglas en una transacción que no fue alterada por lua-resty-waf. "Alterada" se define como lua-resty-waf actuando sobre una regla cuya acción es ACCEPT o DENY. Cuando esta opción no está establecida, lua-resty-waf registrará las coincidencias de reglas incluso si la transacción no fue alterada. De forma predeterminada, lua-resty-waf solo escribirá entradas de registro para coincidencias si la transacción fue alterada.
Ejemplo:```lua location / { access_by_lua_block { waf:set_option("event_log_altered_only", false) } }
Tenga en cuenta que `mode` no tendrá efecto en determinar si una transacción se considera alterada. Es decir, si se coincide con una regla con una acción `DENY`, pero lua-resty-waf se está ejecutando en modo `SIMULATE`, la transacción aún se considerará alterada y las coincidencias de reglas se registrarán.
### event_log_buffer_size
*Predeterminado*: 4096
Define el tamaño umbral, en bytes, del búfer que se utilizará para contener los registros de eventos. El búfer se vaciará cuando se alcance este umbral.
*Ejemplo*:```lua
location / {
access_by_lua_block {
-- 8 KB event log message buffer
waf:set_option("event_log_buffer_size", 8192)
}
}
Predeterminado: ngx.INFO
Establece la constante de nivel de log de nginx utilizada para el registro de eventos.
Ejemplo:```lua location / { access_by_lua_block { waf:set_option("event_log_level", ngx.WARN) } }
### event_log_ngx_vars
*Predeterminado*: vacío
Define qué variables adicionales de `ngx.var` se incluyen en el evento de registro. Esta es una forma genérica de ampliar la alerta con contexto adicional. El nombre de la variable será la clave de la entrada bajo una clave `ngx` en la entrada de registro. Si la variable no está presente como variable de nginx, no se añade ningún elemento al evento.
*Ejemplo*:```lua
location / {
access_by_lua_block {
waf:set_option("event_log_ngx_vars", "host")
waf:set_option("event_log_ngx_vars", "request_id")
}
}
El evento resultante tiene estos elementos adicionales:```json { "ngx": { "host": "example.com", "request_id": "373bcce584e3c18a" } }
### event_log_periodic_flush
*Predeterminado*: ninguno
Define un intervalo, en segundos, en el que el búfer del registro de eventos se vaciará periódicamente. Si no se configura ningún valor, el búfer no se vaciará periódicamente y solo se vaciará cuando se alcance el umbral de `event_log_buffer_size`. Configure esta opción para sitios de tráfico muy bajo que puedan no recibir datos de registro de eventos durante un largo período de tiempo, para evitar que datos obsoletos permanezcan en el búfer.
*Ejemplo*:```lua
location / {
access_by_lua_block {
-- flush the event log buffer every 30 seconds
waf:set_option("event_log_periodic_flush", 30)
}
}
Por defecto: false
Cuando se establece a true, las entradas de registro contienen los argumentos de la solicitud bajo la clave uri_args.
Ejemplo:```lua location / { access_by_lua_block { waf:set_option("event_log_request_arguments", true) } }
### event_log_request_body
*Predeterminado*: false
Cuando se establece en true, las entradas de registro contienen el cuerpo de la solicitud bajo la clave `request_body`.
*Ejemplo*:```lua
location / {
access_by_lua_block {
waf:set_option("event_log_request_body", true)
}
}
Predeterminado: false
Las cabeceras de la solicitud HTTP se copian en el evento de registro, bajo la clave request_headers.
Ejemplo:```lua location / { access_by_lua_block { waf:set_option("event_log_request_headers", true) } }
El evento resultante tiene estos elementos adicionales:```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"
}
}
Por defecto: false
Habilita conexiones SSL al registrar mediante TCP/UDP.
Ejemplo:```lua location / { access_by_lua_block { waf:set_option("event_log_ssl", true) } }
### event_log_ssl_sni_host
*Por defecto*: none
Establece el host SNI para las conexiones de `lua-resty-logger-socket`.
*Ejemplo*:```lua
location / {
access_by_lua_block {
waf:set_option("event_log_ssl_sni_host", "loghost.example.com")
}
}
Por defecto: false
Habilita la verificación de certificados para conexiones SSL al registrar mediante TCP/UDP.
Ejemplo:```lua location / { access_by_lua_block { waf:set_option("event_log_ssl_verify", true) } }
### event_log_socket_proto
*Predeterminado*: udp
Define qué protocolo IP usar (TCP o UDP) al enviar registros de eventos a través de un socket remoto. Se utilizará la misma lógica de almacenamiento en búfer y vaciado recurrente independientemente del protocolo.
*Ejemplo*:```lua
location / {
access_by_lua_block {
-- send logs via TCP
waf:set_option("event_log_socket_proto", "tcp")
}
}
Default: error
Define el destino de los registros de eventos. lua-resty-waf actualmente admite el registro en el log de errores, en un archivo separado en el sistema de archivos local, o en un servidor remoto TCP o UDP. En los dos últimos casos, los registros de eventos se almacenan en búfer y se vacían cuando se alcanza un umbral definido (consulte a continuación más opciones relacionadas con el registro de eventos).
Ejemplo:```lua location / { access_by_lua_block { -- send event logs to the server's error_log location (default) waf:set_option("event_log_target", "error")
-- 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")
}
}
Nota: debido a una limitación en la biblioteca de registro utilizada, solo se puede definir un único socket de destino. Es decir, solo puede configurar un destino `socket` con una combinación específica de host/puerto; si configura una segunda combinación host/puerto, los datos no se registrarán correctamente.
### event_log_target_host
*Predeterminado*: none
Define el servidor de destino para los registros de eventos que apuntan a un servidor remoto.
*Ejemplo*:```lua
location / {
access_by_lua_block {
waf:set_option("event_log_target_host", "10.10.10.10")
}
}
Predeterminado: ninguno
Define la ruta de destino para los registros de eventos que apuntan a una ubicación del sistema de archivos local.
Ejemplo:```lua location / { access_by_lua_block { waf:set_option("event_log_target_path", "/var/log/lua-resty-waf/event.log") } }
Esta ruta debe estar en una ubicación escribible por el usuario de nginx. Tenga en cuenta que, por naturaleza, el registro en disco puede causar una degradación significativa del rendimiento en entornos de alta concurrencia.
### event_log_target_port
*Por defecto*: ninguno
Define el puerto de destino para los registros de eventos que se dirigen a un servidor remoto.
*Ejemplo*:```lua
location / {
access_by_lua_block {
waf:set_option("event_log_target_port", 9001)
}
}
Predeterminado: none
Sobrescribe la funcionalidad de las acciones tomadas cuando una regla coincide. Ver el ejemplo para más detalles
Ejemplo:```lua
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)
}
}
### ignore_rule
*Predeterminado*: ninguno
Indica al módulo que ignore un ID de regla específico. Ten en cuenta que ignorar una regla en una cadena provocará que se ignore toda la cadena, y el procesamiento continuará con la siguiente regla posterior a la cadena.
*Ejemplo*:```lua
location / {
access_by_lua_block {
waf:set_option("ignore_rule", 40294)
waf:set_option("ignore_rule", {40002, 41036})
}
}
Se pueden ignorar múltiples reglas pasando una tabla de IDs de reglas a set_option.
Predeterminado: ninguno
Indica al módulo que ignore un ruleset completo. Esto puede ser útil cuando algunos rulesets (como los de SQLi o XSS de CRS) son demasiado propensos a falsos positivos, o no son aplicables a tu aplicación.
Ejemplo:```lua location / { access_by_lua_block { waf:set_option("ignore_ruleset", "41000_sqli") } }
### mode
*Por defecto*: SIMULATE
Establece el modo operativo del módulo. Las opciones son ACTIVE, INACTIVE y SIMULATE. En el modo ACTIVE, las coincidencias de reglas se registran y se ejecutan las acciones. En el modo SIMULATE, lua-resty-waf recorre cada regla habilitada y registra las coincidencias de reglas, pero no completa la acción especificada en una ejecución determinada. El modo INACTIVE evita que el módulo se ejecute.
Por defecto, se selecciona SIMULATE si no se establece un modo explícitamente; esto requiere que los nuevos usuarios implementen activamente el bloqueo estableciendo el modo en ACTIVE.
*Ejemplo*:```lua
location / {
access_by_lua_block {
waf:set_option("mode", "ACTIVE")
}
}
Predeterminado: ninguno
Define los resolutores DNS que se utilizarán para las consultas RBL. Actualmente solo se admite tráfico UDP/53. Esta opción debe definirse como una dirección numérica, no como un nombre de host. Si esta opción no está definida, todas las reglas de consulta RBL devolverán false.
Ejemplo:```lua location / { access_by_lua_block { waf:set_option("nameservers", "10.10.10.10") } }
### process_multipart_body
*Por defecto* true
Habilita el procesamiento de cuerpos de solicitud multipart/form-data (cuando estén presentes), utilizando el módulo `lua-resty-upload`. En el futuro, lua-resty-waf puede utilizar este procesamiento para realizar comprobaciones más estrictas de los cuerpos de subida; por ahora, este módulo realiza solo comprobaciones mínimas de cordura en el cuerpo de la solicitud y no registrará un evento si el cuerpo de la solicitud no es válido. Deshabilita esta opción si no necesitas esta comprobación, o si los errores en el módulo upstream están causando problemas con las subidas HTTP.
*Ejemplo*:```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)
}
}
Por defecto: false
Establece una cabecera HTTP X-Lua-Resty-WAF-ID en la solicitud upstream, con el valor como ID de transacción. Este ID se correlacionará con el ID de transacción presente en los registros de depuración (si está configurado). Esto puede ser útil para el seguimiento de solicitudes o con fines de depuración.
Ejemplo:```lua location / { access_by_lua_block { waf:set_option("req_tid_header", true) } }
### res_body_max_size
*Predeterminado*: 1048576 (1 MB)
Define el umbral de longitud de contenido a partir del cual los cuerpos de respuesta no se procesarán. Este tamaño del cuerpo de respuesta se determina mediante el encabezado de respuesta Content-Length. Si este encabezado no existe en la respuesta, el cuerpo de respuesta nunca se procesará.
*Ejemplo*:```lua
location / {
access_by_lua_block {
-- increase the max response size to 2 MB
waf:set_option("res_body_max_size", 1024 * 1024 * 2)
}
}
Tenga en cuenta que, por naturaleza, es necesario almacenar en búfer el cuerpo completo de la respuesta para poder utilizarla correctamente como colección, por lo que no se recomienda aumentar este número significativamente sin justificación (y amplios recursos del servidor).
Valor predeterminado: "text/plain", "text/html"
Define los tipos MIME con los que lua-resty-waf procesará el cuerpo de la respuesta. Este valor se determina mediante la cabecera Content-Type. Si esta cabecera no existe, o el tipo de respuesta no está en esta lista, el cuerpo de la respuesta no se procesará. Esta opción añadirá el tipo MIME indicado a los valores predeterminados existentes de text/plain y text/html.
Ejemplo:```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") } }
Se pueden añadir múltiples tipos MIME pasando una tabla de tipos a `set_option`.
### res_tid_header
*Por defecto*: false
Establece una cabecera HTTP `X-Lua-Resty-WAF-ID` en la respuesta descendente, con el valor como ID de transacción. Este ID se correlacionará con el ID de transacción presente en los registros de depuración (si está configurado). Esto puede ser útil para el seguimiento de solicitudes o con fines de depuración.
*Ejemplo*:```lua
location / {
access_by_lua_block {
waf:set_option("res_tid_header", true)
}
}
Predeterminado: 5
Establece el umbral para la puntuación de anomalías. Cuando se alcanza el umbral, lua-resty-waf denegará la solicitud.
Ejemplo:```lua location / { access_by_lua_block { waf:set_option("score_threshold", 10) } }
### storage_backend
*Predeterminado*: dict
Define un motor para el almacenamiento persistente de variables. Las opciones disponibles actualmente son *dict* (zona de memoria compartida de ngx_lua), *memcached* y *redis*.
*Ejemplo*:```lua
location / {
acccess_by_lua_block {
waf:set_option("storage_backend", "memcached")
}
}
Predeterminado: true
Habilita o deshabilita TCP keepalive para las conexiones a hosts remotos de almacenamiento persistente.
Ejemplo:```lua location / { acccess_by_lua_block { waf:set_option("storage_keepalive", false) } }
### storage_keepalive_timeout
*Por defecto*: 10000
Configura (en milisegundos) el tiempo de espera para el pool de keepalive cosocket de los hosts remotos de almacenamiento persistente.
*Ejemplo*:```lua
location / {
acccess_by_lua_block {
waf:set_option("storage_keepalive_timeout", 30000)
}
}
Por defecto: 100
Configure el tamaño del pool para el pool keepalive de cosocket para hosts remotos de almacenamiento persistente.
Ejemplo:```lua location / { acccess_by_lua_block { waf:set_option("storage_keepalive_pool_size", 50) } }
### storage_memcached_host
*Predeterminado*: 127.0.0.1
Define un host para usar cuando se utiliza memcached como motor de almacenamiento de variables persistentes.
*Ejemplo*:```lua
location / {
acccess_by_lua_block {
waf:set_option("storage_memcached_host", "10.10.10.10")
}
}
Predeterminado: 11211
Define un puerto para usar cuando se utiliza memcached como motor de almacenamiento de variables persistentes.
Ejemplo:```lua location / { acccess_by_lua_block { waf:set_option("storage_memcached_port", 11221) } }
### storage_redis_host
*Predeterminado*: 127.0.0.1
Define un host para usar cuando se use redis como motor de almacenamiento de variables persistente.
*Ejemplo*:```lua
location / {
acccess_by_lua_block {
waf:set_option("storage_redis_host", "10.10.10.10")
}
}
Predeterminado: 6379
Define un puerto para usar cuando se usa redis como motor de almacenamiento de variables persistentes.
Ejemplo:```lua location / { acccess_by_lua_block { waf:set_option("storage_redis_port", 6397) } }
### storage_zone
*Default*: none
Define el `lua_shared_dict` que se usará para mantener datos de almacenamiento persistente. Esta zona debe definirse en el bloque `http{}` de la configuración.
*Ejemplo*:_```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")
}
}
Se pueden definir y utilizar múltiples zonas compartidas, aunque solo se puede definir una zona por ubicación de configuración. Si una zona se llena y la interfaz del diccionario compartido no puede agregar claves adicionales, se escribirá lo siguiente en el registro de errores:
Error adding key to persistent storage, increase the size of the lua_shared_dict
lua-resty-waf está diseñado para ejecutarse en múltiples fases del ciclo de vida de la solicitud. Las reglas se pueden procesar en las siguientes fases:
Estas fases se corresponden con sus manejadores lua de Nginx apropiados (access_by_lua, header_filter_by_lua, body_filter_by_lua y log_by_lua, respectivamente). Ten en cuenta que ejecutar lua-resty-waf en un manejador de fase lua que no esté en esta lista provocará un comportamiento incorrecto. Todos los datos disponibles en una fase anterior están disponibles en una fase posterior. Es decir, los datos disponibles en la fase access también están disponibles en las fases header_filter y body_filter, pero no a la inversa.
lua-resty-waf se distribuye con una serie de conjuntos de reglas diseñados para imitar la funcionalidad del ModSecurity CRS. Como referencia, estos conjuntos de reglas se enumeran a continuación:
lua-resty-waf analiza las definiciones de reglas a partir de blobs JSON almacenados en disco. Las reglas se agrupan según su propósito y gravedad, definidas como un conjunto de reglas. Los conjuntos de reglas incluidos se crearon para imitar parte de la funcionalidad del ModSecurity CRS, en particular las definiciones de base_rules. Además, el script incluido modsec2lua-resty-waf.pl se puede utilizar para traducir conjuntos de reglas adicionales o personalizados a un blob JSON compatible con lua-resty-waf.
Ten en cuenta que el script de traducción tiene varias limitaciones con respecto a acciones, colecciones y operadores no soportados. Consulta esta página wiki para obtener una lista actualizada de incompatibilidades conocidas.
Existe un canal de IRC en Freenode #lua-resty-waf. Travis CI envía notificaciones aquí; no dudes en hacer preguntas o dejar comentarios en este canal también.
Además, hay preguntas y respuestas disponibles en CodeWake:
Por favor, dirige todas las pull requests hacia la rama de desarrollo, o a una rama de características si la PR es un cambio significativo. Los commits a master solo deben realizarse en forma de actualizaciones de documentación u otros cambios que no tengan impacto en el módulo en sí (y que puedan fusionarse limpiamente en desarrollo).
lua-resty-waf está en continuo desarrollo y mejora y, como tal, puede tener limitaciones en su funcionalidad y rendimiento. Las limitaciones actualmente conocidas se pueden encontrar en el rastreador de incidencias de GitHub para este repositorio.
Este programa es software libre: puedes redistribuirlo y/o modificar bajo los términos de la Licencia Pública General de GNU publicada por la Free Software Foundation, ya sea la versión 3 de la Licencia, o (a tu elección) cualquier versión posterior.
Este programa se distribuye con la esperanza de que sea útil, pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de COMERCIABILIDAD o IDONEIDAD PARA UN PROPÓSITO PARTICULAR. Véase la Licencia Pública General de GNU para más detalles.
Deberías haber recibido una copia de la Licencia Pública General de GNU junto con este programa. Si no, consulta http://www.gnu.org/licenses/
Por favor, informa de los errores creando un ticket en el rastreador de incidencias de GitHub.