
WAF ad alte prestazioni basato sullo stack OpenResty
lua-resty-waf - WAF ad alte prestazioni costruito sullo stack OpenResty
NOTA: lua-resty-waf è di fatto abbandonato. Questo progetto era utile in un'epoca in cui ModSecurity per Nginx non era un'opzione praticabile; non è più così. C'è stato un tentativo di rivitalizzare il progetto nel 2020, ma non ho le risorse per portarlo a termine; questo lavoro è parzialmente completato nel branch redux.
lua-resty-waf è un WAF proxy inverso costruito usando lo stack OpenResty. Utilizza l'API Lua di Nginx per analizzare le informazioni delle richieste HTTP ed elaborarle secondo una struttura di regole flessibile. lua-resty-waf è distribuito con un ruleset che imita il ModSecurity CRS, oltre ad alcune regole personalizzate create durante lo sviluppo e i test iniziali, e un piccolo patchset virtuale per le minacce emergenti. Inoltre, lua-resty-waf è distribuito con strumenti per tradurre automaticamente le regole ModSecurity esistenti, consentendo agli utenti di estendere l'implementazione di lua-resty-waf senza dover imparare una nuova sintassi per le regole.
lua-resty-waf è stato inizialmente sviluppato da Robert Paprocki per la sua tesi di Master presso la Western Governor's University.
lua-resty-waf richiede diversi moduli Lua resty di terze parti, anche se sono tutti inclusi in lua-resty-waf e quindi non devono essere installati separatamente. Si consiglia di installare lua-resty-waf su un sistema che esegua il bundle software OpenResty; lua-resty-waf non è stato testato su piattaforme costruite con pacchetti separati di sorgente Nginx e modulo Lua per Nginx.
Per ottenere prestazioni ottimali di compilazione delle regex, si consiglia di compilare Nginx/OpenResty con una versione di PCRE che supporti la compilazione JIT. Se il tuo sistema operativo non la fornisce, puoi compilare una PCRE con supporto JIT direttamente nella tua build di Nginx/OpenResty. Per farlo, fai riferimento al percorso del sorgente PCRE nel flag di configurazione --with-pcre. Per esempio:```sh
Puoi scaricare il sorgente PCRE dal [sito web di PCRE](http://www.pcre.org/). Vedi anche questo [post del blog](https://www.cryptobells.com/building-openresty-with-pcre-jit/) per una guida passo-passo sulla creazione di OpenResty con una libreria PCRE con JIT abilitato.
## Performance
lua-resty-waf è stato progettato pensando a efficienza e scalabilità. Sfrutta il modello di elaborazione asincrona di Nginx e un design efficiente per elaborare ogni transazione il più rapidamente possibile. I test di carico hanno mostrato che le implementazioni che utilizzano tutti i ruleset forniti, progettati per imitare la logica alla base del ModSecurity CRS, elaborano le transazioni in circa 300-500 microsecondi per richiesta; questo equivale alle prestazioni pubblicizzate dal [WAF di Cloudflare](https://www.cloudflare.com/waf). I test sono stati eseguiti su una configurazione hardware ragionevole (CPU E3-1230, 32 GB di RAM, 2 x 840 EVO in RAID 0), raggiungendo un massimo di circa 15.000 richieste al secondo. Vedi [questo post del blog](http://www.cryptobells.com/freewaf-a-high-performance-scalable-open-web-firewall) per maggiori informazioni.
Il carico di lavoro di lua-resty-waf è quasi esclusivamente vincolato alla CPU. L'impronta di memoria nella VM Lua (esclusa l'archiviazione persistente supportata da `lua-shared-dict`) è di circa 2MB.
## Installazione
È fornito un semplice Makefile:```
# make && sudo make install
In alternativa, installa via Luarocks:```
lua-resty-waf utilizza il gestore di pacchetti [OPM](https://github.com/openresty/opm), disponibile nelle distribuzioni moderne di OpenResty. Gli strumenti client OPM richiedono che il tool da riga di comando `resty` sia disponibile nella variabile d'ambiente `PATH` del sistema.
Si noti che per impostazione predefinita lua-resty-waf viene eseguito in modalità SIMULATE, per evitare di influenzare immediatamente un'applicazione; gli utenti che desiderano abilitare le azioni delle regole devono impostare esplicitamente la modalità operativa su ACTIVE.
## Sinossi```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 inizializza un file di regole ModSecurity SecRules dal disco. Nota che ciò richiede comunque che il ruleset venga aggiunto tramite add_ruleset (il basename del file deve essere fornito come chiave).
Esempio:```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")
}
}
}
}
Inoltre, `load_secrules` può accettare un secondo argomento opzionale come tabella di opzioni da passare a varie funzioni di traduzione. Sono riconosciute le seguenti opzioni:
* *path*: Definisce un percorso del filesystem in cui cercare i file di dati per operatori come @pmFromFile. Se questa chiave non è definita, viene usata la directory di lavoro corrente (`.`)
* *force*: Non generare errori e non interrompere quando la traduzione di una variabile di regola fallisce
* *loose*: Non generare errori e non interrompere quando la traduzione di un'azione di regola fallisce
* *quiet*: Non generare errori o avvisi quando la traduzione di un'azione di regola fallisce
Questa funzione può anche accettare un terzo argomento come tabella per catturare gli errori di traduzione, per un'elaborazione successiva. Se questa opzione non è presente o non è una tabella, gli errori di traduzione verranno invece registrati nel log degli errori.
### lua-resty-waf.init()
Esegue una pre-elaborazione di regole e ruleset, basata su ciò che è stato reso disponibile tramite i ruleset distribuiti predefiniti. È consigliato, ma non richiesto, chiamare questa funzione (non farlo comporterà una piccola penalità prestazionale). Questa funzione non dovrebbe mai essere chiamata al di fuori di questo ambito.
*Esempio*:```lua
http {
init_by_lua_block {
local lua_resty_waf = require "resty.waf"
lua_resty_waf.init()
}
}
Istanzia una nuova istanza di lua-resty-waf. Devi chiamare questo metodo in ogni fase del request handler in cui desideri eseguire lua-resty-waf e utilizzare il risultato restituito per chiamare ulteriori metodi dell'oggetto.
Esempio:```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 un'opzione su base per-scope.
*Esempio*:```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)
}
}
Definisce una variabile di transazione (memorizzata nella raccolta di variabili TX) prima di eseguire il WAF. Questa funzione può essere utilizzata per definire variabili usate da ruleset complessi come l'OWASP CRS.
Esempio:```lua location / { access_by_lua_block { local lua_resty_waf = require "resty.waf"
local waf = lua_resty_waf:new()
waf:set_var("FOO", "bar")
}
}
Nota che come per qualsiasi altra regola ModSecurity, l'esistenza di una variabile non comporta alcun cambiamento funzionale nell'elaborazione del WAF; è responsabilità dell'autore della regola comprendere e utilizzare le variabili `TX`.
### lua-resty-waf:sieve_rule()
Definisci un'esclusione di raccolta per una data regola.
*Esempio*:```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)
}
}
Consulta la pagina wiki rule sieves per dettagli ed esempi di utilizzo avanzati.
Esegue il motore delle regole. Di default, il motore viene eseguito in base alla fase attualmente in corso. È possibile passare una tabella opzionale, che consente agli utenti di "simulare" l'esecuzione di una fase diversa.
Esempio:```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()
Scrive tutte le voci di audit log generate dalla transazione. È opzionale solo quando `exec` viene chiamato in un handler `log_by_lua`.
*Esempio*:```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()
}
}
Predefinito: nessuno
Aggiunge un ruleset aggiuntivo da utilizzare durante l'elaborazione. Ciò consente agli utenti di implementare ruleset personalizzati senza sovrascrivere la directory delle regole inclusa. I ruleset aggiuntivi devono trovarsi in una cartella chiamata "rules" che risiede all'interno di lua_package_path.
Esempio:```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")
}
}
}
}
È possibile aggiungere più ruleset passando una tabella di valori a `set_option`. Nota: i nomi dei ruleset vengono ordinati prima dell'elaborazione. I ruleset vengono elaborati in ordine crescente.
### add_ruleset_string
*Predefinito*: nessuno
Aggiunge un ruleset aggiuntivo da utilizzare durante l'elaborazione. Ciò consente agli utenti di implementare ruleset personalizzati senza sovrascrivere la directory delle regole inclusa. I ruleset vengono definiti inline come stringa Lua, sotto forma di una struttura JSON di un ruleset tradotto.
*Esempio*:```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":[]}]=])
}
}
Nota: i nomi dei ruleset vengono ordinati prima dell'elaborazione e devono essere forniti come stringhe. I ruleset vengono elaborati in ordine crescente (da basso ad alto).
Default: false
Indica a lua-resty-waf di continuare l'elaborazione della richiesta quando viene inviato un header Content-Type che non è presente nella tabella allowed_content_types. Tali richieste non vedranno il proprio corpo elaborato da lua-resty-waf (la collection REQUEST_BODY sarà nil). In questo modo, gli utenti non devono inserire esplicitamente nella whitelist tutti i possibili header Content-Type che potrebbero incontrare.
Esempio:```lua location / { access_by_lua_block { waf:set_option("allow_unknown_content_types", true) } }
### allowed_content_types
*Predefinito*: nessuno
Definisce una o più intestazioni Content-Type che saranno consentite, in aggiunta ai Content-Type predefiniti `application/x-www-form-urlencoded` e `multipart/form-data`. Una richiesta il cui tipo di contenuto corrisponde a uno di `allowed_content_types` imposterà la raccolta `REQUEST_BODY` a una singola stringa contenente (piuttosto che a una tabella); una richiesta il cui tipo di contenuto non corrisponde a uno di questi valori, o a `application/x-www-form-urlencoded` o `multipart/form-data`, verrà rifiutata.
*Esempio*:```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" })
}
}
Nota che più chiamate set_option con un parametro allowed_content_types sovrascriveranno semplicemente la tabella delle opzioni esistente, quindi se desideri definire più tipi di contenuto consentiti, devi definirli come una tabella Lua come mostrato sopra.
Predefinito: false
Disabilita/abilita il logging di debug. Le istruzioni di log di debug vengono stampate su error_log. Nota che il logging di debug è molto costoso e non dovrebbe essere usato in ambienti di produzione.
Esempio:```lua location / { access_by_lua_block { waf:set_option("debug", true) } }
### debug_log_level
*Predefinito*: ngx.INFO
Imposta la costante del livello di log di nginx utilizzata per la registrazione di debug.
*Esempio*:```lua
location / {
access_by_lua_block {
waf:set_option("debug_log_level", ngx.DEBUG)
}
}
Default: ngx.HTTP_FORBIDDEN
Imposta lo stato da utilizzare quando si negano le richieste.
Esempio:```lua location / { access_by_lua_block { waf:set_option("deny_status", ngx.HTTP_NOT_FOUND) } }
### disable_pcre_optimization
*Default*: false
Rimuove i flag `oj` da tutte le chiamate `ngx.re.match`, `ngx.re.find` e `ngx.re.sub`. Questo può essere utile in alcuni casi in cui vengono utilizzate librerie PCRE meno recenti, ma causerà un grave degrado delle prestazioni, quindi il suo uso è fortemente sconsigliato; si invita invece a compilare OpenResty con una libreria PCRE moderna e in grado di utilizzare JIT.
*Esempio*:```lua
location / {
access_by_lua_block {
waf:set_option("disable_pcre_optimization", true)
}
}
Nota: questo comportamento è deprecato e verrà rimosso nelle versioni future.
Predefinito: true
Determina se scrivere voci di log per le corrispondenze di regole in una transazione che non è stata alterata da lua-resty-waf. "Alterata" è definita come lua-resty-waf che agisce su una regola la cui azione è ACCEPT o DENY. Quando questa opzione non è impostata, lua-resty-waf registrerà le corrispondenze di regole anche se la transazione non è stata alterata. Per impostazione predefinita, lua-resty-waf scriverà solo voci di log per le corrispondenze se la transazione è stata alterata.
Esempio:```lua location / { access_by_lua_block { waf:set_option("event_log_altered_only", false) } }
Note that `mode` non avrà effetto nel determinare se una transazione è considerata alterata. Cioè, se una regola con azione `DENY` viene soddisfatta, ma lua-resty-waf è in esecuzione in modalità `SIMULATE`, la transazione sarà comunque considerata alterata e le corrispondenze delle regole verranno registrate.
### event_log_buffer_size
*Predefinito*: 4096
Definisce la dimensione di soglia, in byte, del buffer utilizzato per contenere i log degli eventi. Il buffer verrà svuotato quando questa soglia viene raggiunta.
*Esempio*:```lua
location / {
access_by_lua_block {
-- 8 KB event log message buffer
waf:set_option("event_log_buffer_size", 8192)
}
}
Predefinito: ngx.INFO
Imposta la costante del livello di log di nginx utilizzata per la registrazione degli eventi.
Esempio:```lua location / { access_by_lua_block { waf:set_option("event_log_level", ngx.WARN) } }
### event_log_ngx_vars
*Predefinito*: vuoto
Definisce quali variabili extra da `ngx.var` vengono inserite nell'evento di log. È un modo generico per estendere l'avviso con contesto aggiuntivo. Il nome della variabile sarà la chiave della voce sotto una chiave `ngx` nella voce di log. Se la variabile non è presente come variabile nginx, nessun elemento viene aggiunto all'evento.
*Esempio*:```lua
location / {
access_by_lua_block {
waf:set_option("event_log_ngx_vars", "host")
waf:set_option("event_log_ngx_vars", "request_id")
}
}
L'evento risultante ha questi elementi aggiuntivi:```json { "ngx": { "host": "example.com", "request_id": "373bcce584e3c18a" } }
### event_log_periodic_flush
*Predefinito*: none
Definisce un intervallo, in secondi, al quale il buffer del registro eventi verrà svuotato periodicamente. Se non viene configurato alcun valore, il buffer non verrà svuotato periodicamente e verrà svuotato solo quando viene raggiunta la soglia `event_log_buffer_size`. Configura questa opzione per siti a traffico molto basso che potrebbero non ricevere dati di registro eventi per un lungo periodo di tempo, per evitare che dati obsoleti rimangano nel buffer.
*Esempio*:```lua
location / {
access_by_lua_block {
-- flush the event log buffer every 30 seconds
waf:set_option("event_log_periodic_flush", 30)
}
}
Default: false
Quando impostato su true, le voci di log contengono gli argomenti della richiesta sotto la chiave uri_args.
Esempio:```lua location / { access_by_lua_block { waf:set_option("event_log_request_arguments", true) } }
### event_log_request_body
*Predefinito*: false
Quando impostato su true, le voci di log contengono il corpo della richiesta sotto la chiave `request_body`.
*Esempio*:```lua
location / {
access_by_lua_block {
waf:set_option("event_log_request_body", true)
}
}
Predefinito: false
Le intestazioni della richiesta HTTP vengono copiate nell'evento di log, sotto la chiave request_headers.
Esempio:```lua location / { access_by_lua_block { waf:set_option("event_log_request_headers", true) } }
L'evento risultante contiene questi elementi aggiuntivi:```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"
}
}
Predefinito: false
Abilita connessioni SSL durante la registrazione tramite TCP/UDP.
Esempio:```lua location / { access_by_lua_block { waf:set_option("event_log_ssl", true) } }
### event_log_ssl_sni_host
*Default*: nessuno
Imposta l'host SNI per le connessioni `lua-resty-logger-socket`.
*Esempio*:```lua
location / {
access_by_lua_block {
waf:set_option("event_log_ssl_sni_host", "loghost.example.com")
}
}
Predefinito: false
Abilita la verifica dei certificati per le connessioni SSL quando si inviano log tramite TCP/UDP.
Esempio:```lua location / { access_by_lua_block { waf:set_option("event_log_ssl_verify", true) } }
### event_log_socket_proto
*Predefinito*: udp
Definisce quale protocollo IP utilizzare (TCP o UDP) quando si inviano i log degli eventi tramite un socket remoto. La stessa logica di buffering e di flush ricorrente verrà utilizzata indipendentemente dal protocollo.
*Esempio*:```lua
location / {
access_by_lua_block {
-- send logs via TCP
waf:set_option("event_log_socket_proto", "tcp")
}
}
Default: error
Definisce la destinazione per i log degli eventi. lua-resty-waf attualmente supporta la registrazione nel log degli errori, in un file separato sul file system locale, oppure verso un server TCP o UDP remoto. In questi ultimi due casi, i log degli eventi vengono bufferizzati e svuotati quando viene raggiunta una soglia definita (vedi sotto per ulteriori opzioni relative alle impostazioni di registrazione degli eventi).
Esempio:```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 che, a causa di una limitazione nella libreria di logging utilizzata, può essere definito un solo socket di destinazione. Ciò significa che puoi configurare solo un target `socket` con una specifica combinazione host/port; se configuri una seconda combinazione host/port, i dati non verranno registrati correttamente.
### event_log_target_host
*Predefinito*: nessuno
Definisce il server di destinazione per i log degli eventi che hanno come target un server remoto.
*Esempio*:```lua
location / {
access_by_lua_block {
waf:set_option("event_log_target_host", "10.10.10.10")
}
}
Predefinito: none
Definisce il percorso di destinazione per i log degli eventi che puntano a una posizione del file system locale.
Esempio:```lua location / { access_by_lua_block { waf:set_option("event_log_target_path", "/var/log/lua-resty-waf/event.log") } }
Questo percorso deve trovarsi in una posizione scrivibile dall'utente nginx. Si noti che, per sua natura, la registrazione su disco può causare un degrado significativo delle prestazioni in ambienti ad alta concorrenza.
### event_log_target_port
*Predefinito*: nessuno
Definisce la porta di destinazione per i log degli eventi destinati a un server remoto.
*Esempio*:```lua
location / {
access_by_lua_block {
waf:set_option("event_log_target_port", 9001)
}
}
Predefinito: nessuno
Sostituisce la funzionalità delle azioni eseguite quando una regola viene soddisfatta. Vedi l'esempio per maggiori dettagli
Esempio:```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
*Predefinito*: nessuno
Indica al modulo di ignorare un ID di regola specificato. Nota che ignorare una regola in una catena comporterà l'ignoramento dell'intera catena e l'elaborazione continuerà con la regola successiva seguente alla catena.
*Esempio*:```lua
location / {
access_by_lua_block {
waf:set_option("ignore_rule", 40294)
waf:set_option("ignore_rule", {40002, 41036})
}
}
È possibile ignorare più regole passando una tabella di ID di regole a set_option.
Predefinito: nessuno
Indica al modulo di ignorare un intero ruleset. Questo può essere utile quando alcuni ruleset (come i ruleset CRS per SQLi o XSS) sono troppo inclini a falsi positivi, oppure non sono applicabili alla tua applicazione.
Esempio:```lua location / { access_by_lua_block { waf:set_option("ignore_ruleset", "41000_sqli") } }
### mode
*Predefinito*: SIMULATE
Imposta la modalità operativa del modulo. Le opzioni sono ACTIVE, INACTIVE e SIMULATE. In modalità ACTIVE, le corrispondenze delle regole vengono registrate e le azioni vengono eseguite. In modalità SIMULATE, lua-resty-waf scorre ogni regola abilitata e registra le corrispondenze delle regole, ma non completa l'azione specificata in una determinata esecuzione. La modalità INACTIVE impedisce l'esecuzione del modulo.
Per impostazione predefinita, SIMULATE viene selezionato se non viene impostata esplicitamente una modalità; ciò richiede ai nuovi utenti di implementare attivamente il blocco impostando la modalità su ACTIVE.
*Esempio*:```lua
location / {
access_by_lua_block {
waf:set_option("mode", "ACTIVE")
}
}
Predefinito: none
Imposta i resolver DNS da utilizzare per le ricerche RBL. Attualmente è supportato solo il traffico UDP/53. Questa opzione deve essere definita come un indirizzo numerico, non come hostname. Se questa opzione non è definita, tutte le regole di ricerca RBL restituiranno false.
Esempio:```lua location / { access_by_lua_block { waf:set_option("nameservers", "10.10.10.10") } }
### process_multipart_body
*Predefinito* true
Abilita l'elaborazione dei body delle richieste multipart/form-data (quando presenti), utilizzando il modulo `lua-resty-upload`. In futuro, lua-resty-waf potrebbe utilizzare questa elaborazione per eseguire controlli più severi sui body degli upload; per ora questo modulo esegue solo controlli di sanità minimi sul body della richiesta e non registrerà un evento se il body della richiesta non è valido. Disabilita questa opzione se non hai bisogno di questo controllo, o se bug nel modulo a monte stanno causando problemi con gli upload HTTP.
*Esempio*:```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)
}
}
Default: false
Imposta un header HTTP X-Lua-Resty-WAF-ID nella richiesta upstream, con il valore corrispondente all'ID della transazione. Questo ID sarà correlato all'ID della transazione presente nei log di debug (se impostato). Può essere utile per il tracciamento delle richieste o per scopi di debug.
Esempio:```lua location / { access_by_lua_block { waf:set_option("req_tid_header", true) } }
### res_body_max_size
*Predefinito*: 1048576 (1 MB)
Definisce la soglia di lunghezza del contenuto oltre la quale i corpi delle risposte non verranno elaborati. Questa dimensione del corpo della risposta è determinata dall'header Content-Length della risposta. Se questo header non esiste nella risposta, il corpo della risposta non verrà mai elaborato.
*Esempio*:```lua
location / {
access_by_lua_block {
-- increase the max response size to 2 MB
waf:set_option("res_body_max_size", 1024 * 1024 * 2)
}
}
Nota che per natura è necessario bufferizzare l'intero corpo della risposta per poter utilizzare correttamente la risposta come collezione, quindi aumentare significativamente questo numero non è raccomandato senza una giustificazione (e ampie risorse server).
Predefinito: "text/plain", "text/html"
Definisce i tipi MIME con cui lua-resty-waf elaborerà il corpo della risposta. Questo valore è determinato dall'header Content-Type. Se questo header non esiste, o il tipo di risposta non è in questa lista, il corpo della risposta non verrà elaborato. Impostando questa opzione si aggiungerà il tipo MIME specificato ai valori predefiniti esistenti di text/plain e text/html.
Esempio:```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") } }
È possibile aggiungere più tipi MIME passando una tabella di tipi a `set_option`.
### res_tid_header
*Predefinito*: false
Imposta un header HTTP `X-Lua-Resty-WAF-ID` nella risposta a valle, con il valore come ID della transazione. Questo ID sarà correlato all'ID della transazione presente nei log di debug (se impostato). Può essere utile per il tracciamento delle richieste o per scopi di debug.
*Esempio*:```lua
location / {
access_by_lua_block {
waf:set_option("res_tid_header", true)
}
}
Predefinito: 5
Imposta la soglia per il punteggio di anomalia. Quando la soglia viene raggiunta, lua-resty-waf negherà la richiesta.
Esempio:```lua location / { access_by_lua_block { waf:set_option("score_threshold", 10) } }
### storage_backend
*Default*: dict
Definisci un motore da utilizzare per l'archiviazione persistente delle variabili. Le opzioni attualmente disponibili sono *dict* (zona di memoria condivisa ngx_lua), *memcached* e *redis*.
*Esempio*:```lua
location / {
acccess_by_lua_block {
waf:set_option("storage_backend", "memcached")
}
}
Predefinito: true
Abilita o disabilita il keepalive TCP per le connessioni a host remoti di storage persistente.
Esempio:```lua location / { acccess_by_lua_block { waf:set_option("storage_keepalive", false) } }
### storage_keepalive_timeout
*Predefinito*: 10000
Configura (in millisecondi) il timeout per il pool keepalive cosocket per gli host remoti di archiviazione persistente.
*Esempio*:```lua
location / {
acccess_by_lua_block {
waf:set_option("storage_keepalive_timeout", 30000)
}
}
Predefinito: 100
Configura la dimensione del pool per il pool keepalive cosocket per gli host di archiviazione persistente remoti.
Esempio:```lua location / { acccess_by_lua_block { waf:set_option("storage_keepalive_pool_size", 50) } }
### storage_memcached_host
*Default*: 127.0.0.1
Definisci un host da utilizzare quando si usa memcached come motore di archiviazione persistente delle variabili.
*Esempio*:```lua
location / {
acccess_by_lua_block {
waf:set_option("storage_memcached_host", "10.10.10.10")
}
}
Predefinito: 11211
Definisci una porta da utilizzare quando si usa memcached come motore di archiviazione persistente delle variabili.
Esempio:```lua location / { acccess_by_lua_block { waf:set_option("storage_memcached_port", 11221) } }
### storage_redis_host
*Predefinito*: 127.0.0.1
Definisci un host da utilizzare quando si usa redis come motore di archiviazione persistente delle variabili.
*Esempio*:```lua
location / {
acccess_by_lua_block {
waf:set_option("storage_redis_host", "10.10.10.10")
}
}
Predefinito: 6379
Definisce una porta da usare quando si utilizza redis come motore di archiviazione persistente delle variabili.
Esempio:```lua location / { acccess_by_lua_block { waf:set_option("storage_redis_port", 6397) } }
### storage_zone
*Predefinito*: none
Definisce il `lua_shared_dict` che verrà utilizzato per contenere i dati di archiviazione persistenti. Questa zona deve essere definita nel blocco `http{}` della configurazione.
*Esempio*:_```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")
}
}
È possibile definire e utilizzare più zone condivise, anche se è possibile definire una sola zona per posizione di configurazione. Se una zona si riempie e l'interfaccia del dizionario condiviso non può aggiungere ulteriori chiavi, nel log degli errori verrà inserito quanto segue:
Error adding key to persistent storage, increase the size of the lua_shared_dict
lua-resty-waf è progettato per essere eseguito in più fasi del ciclo di vita della richiesta. Le regole possono essere elaborate nelle seguenti fasi:
Queste fasi corrispondono ai rispettivi handler lua di Nginx (access_by_lua, header_filter_by_lua, body_filter_by_lua e log_by_lua). Nota che eseguire lua-resty-waf in un handler di fase lua non presente in questo elenco porterà a comportamenti non corretti. Tutti i dati disponibili in una fase precedente sono disponibili in una fase successiva. Cioè, i dati disponibili nella fase access sono disponibili anche nelle fasi header_filter e body_filter, ma non viceversa.
lua-resty-waf è distribuito con una serie di ruleset progettati per replicare le funzionalità della ModSecurity CRS. Per riferimento, questi ruleset sono elencati di seguito:
lua-resty-waf analizza le definizioni delle regole da blocchi JSON salvati su disco. Le regole sono raggruppate in base a scopo e gravità, definite come ruleset. I ruleset inclusi sono stati creati per replicare alcune funzionalità della ModSecurity CRS, in particolare le definizioni base_rules. Inoltre, lo script incluso modsec2lua-resty-waf.pl può essere utilizzato per tradurre ruleset aggiuntivi o personalizzati in un blocco JSON compatibile con lua-resty-waf.
Nota che ci sono diverse limitazioni nello script di traduzione, per quanto riguarda azioni, collection e operatori non supportati. Consulta questa pagina wiki per un elenco aggiornato delle incompatibilità note.
Esiste un canale IRC Freenode #lua-resty-waf. Travis CI invia notifiche qui; sentiti libero di fare domande/lasciare commenti anche in questo canale.
Inoltre, Q/A è disponibile su CodeWake:
Si prega di indirizzare tutte le pull request verso il ramo di sviluppo, o verso un ramo di funzionalità se la PR è una modifica significativa. I commit su master dovrebbero avvenire solo sotto forma di aggiornamenti della documentazione o altre modifiche che non hanno alcun impatto sul modulo stesso (e che possono essere unite senza problemi nello sviluppo).
lua-resty-waf è in continuo sviluppo e miglioramento e, come tale, può presentare limitazioni nelle sue funzionalità e prestazioni. Le limitazioni attualmente note sono disponibili nel tracker dei problemi GitHub di questo repository.
Questo programma è software libero: puoi ridistribuirlo e/o modificarlo secondo i termini della GNU General Public License pubblicata dalla Free Software Foundation, o la versione 3 della Licenza, o (a tua scelta) qualsiasi versione successiva.
Questo programma è distribuito nella speranza che possa essere utile, ma SENZA ALCUNA GARANZIA; senza nemmeno la garanzia implicita di COMMERCIABILITÀ o IDONEITÀ PER UNO SCOPO PARTICOLARE. Vedere la GNU General Public License per maggiori dettagli.
Dovresti aver ricevuto una copia della GNU General Public License insieme a questo programma. Se non l'hai ricevuta, vedi http://www.gnu.org/licenses/
Segnala i bug creando un ticket tramite il tracker dei problemi di GitHub.