Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
lua-resty-waf — Высокопроизводительный WAF, построенный на стеке OpenResty | Kitploit
Инструменты/GitHubGitHub/p0pr0ck5/lua-resty-waf
Оборонительные ИнструментыВеб-безопасностьБезопасность API
GitHubp0pr0ck5/lua-resty-waf

lua-resty-waf

Высокопроизводительный WAF, построенный на стеке OpenResty

Репозиторий
1.3k3052 лет назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Название

lua-resty-waf - высокопроизводительный WAF, построенный на стеке OpenResty

Содержание

  • Название
  • Статус
  • Описание
  • Требования
  • Производительность
  • Установка
  • Синопсис
  • Публичные функции
    • 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
  • Обработка фаз
  • Включённые наборы правил
  • Определения правил
  • Примечания
    • Сообщество
    • Pull Requests
  • Дорожная карта
  • Ограничения
  • Лицензия
  • Ошибки
  • См. также

Статус

Build Status Codewake CII Best Practices

ПРИМЕЧАНИЕ: lua-resty-waf по сути заброшен. Этот проект был полезен в то время, когда ModSecurity для Nginx не был жизнеспособным вариантом; сейчас это уже не так. В 2020 году была попытка оживить проект, но у меня нет ресурсов, чтобы завершить её; эта работа частично выполнена в ветке redux.

Описание

lua-resty-waf - это обратный прокси-WAF, построенный на стеке OpenResty. Он использует 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, и поэтому их не нужно устанавливать отдельно. Рекомендуется устанавливать lua-resty-waf на систему с программным пакетом OpenResty; lua-resty-waf не тестировался на платформах, собранных с использованием отдельных пакетов исходного кода Nginx и модуля Nginx Lua.

Для оптимальной производительности компиляции регулярных выражений рекомендуется собирать Nginx/OpenResty с версией PCRE, поддерживающей JIT-компиляцию. Если ваша ОС не предоставляет такой версии, вы можете собрать PCRE с поддержкой JIT непосредственно в вашу сборку Nginx/OpenResty. Для этого укажите путь к исходному коду PCRE в флаге конфигурации --with-pcre. Например:```sh

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

root@kitploit:~
Вы можете загрузить исходный код PCRE с [сайта PCRE](http://www.pcre.org/). Также смотрите этот [пост в блоге](https://www.cryptobells.com/building-openresty-with-pcre-jit/) с пошаговым руководством по сборке OpenResty с библиотекой PCRE с поддержкой JIT.

## Производительность

lua-resty-waf проектировался с учётом эффективности и масштабируемости. Он использует асинхронную модель обработки Nginx и эффективную архитектуру, чтобы обрабатывать каждую транзакцию как можно быстрее. Нагрузочное тестирование показало, что развёртывания, использующие все предоставляемые наборы правил, которые призваны имитировать логику ModSecurity CRS, обрабатывают транзакции примерно за 300–500 микросекунд на запрос; это соответствует производительности, заявленной для [WAF Cloudflare](https://www.cloudflare.com/waf). Тесты проводились на разумном аппаратном стеке (CPU E3-1230, 32 ГБ ОЗУ, 2 x 840 EVO в RAID 0), достигая примерно 15 000 запросов в секунду. Более подробную информацию см. в [этом посте в блоге](http://www.cryptobells.com/freewaf-a-high-performance-scalable-open-web-firewall).

## Установка

Предоставляется простой Makefile:```
# make && sudo make install

Как вариант, установите через Luarocks:```

luarocks install lua-resty-waf

root@kitploit:~
lua-resty-waf использует пакетный менеджер [OPM](https://github.com/openresty/opm), доступный в современных дистрибутивах OpenResty. Клиентские инструменты OPM требуют, чтобы инструмент командной строки `resty` был доступен в переменной окружения `PATH` вашей системы.

Обратите внимание, что по умолчанию 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()
            }
        }
    }
}

Public Functions

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()
    }
}

Публичные методы

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()

Определите переменную транзакции (хранящуюся в коллекции переменных TX) перед выполнением WAF. Это можно использовать для определения переменных, используемых сложными наборами правил, такими как 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)
    }
}

См. вики-страницу сита правил для подробностей и примеров расширенного использования.

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

По умолчанию: none

Добавляет дополнительный набор правил, используемый во время обработки. Это позволяет пользователям реализовывать собственные наборы правил, не затрагивая встроенный каталог правил. Дополнительные наборы правил должны находиться в папке "rules", расположенной внутри lua_package_path.

Пример:```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

*По умолчанию*: none

Добавляет дополнительный набор правил для использования при обработке. Это позволяет пользователям создавать собственные наборы правил, не затирая входящий в комплект каталог правил. Наборы правил определяются инлайн в виде 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

*По умолчанию*: none

Определяет один или несколько заголовков 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" })
    }
}

Обратите внимание, что множественные вызовы set_option с параметром allowed_content_types просто переопределяют существующую таблицу опций, поэтому, если вы хотите определить несколько разрешённых типов контента, вы должны определить их в виде Lua-таблицы, как показано выше.

debug

Default: 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

Удаляет флаги `oj` из всех вызовов `ngx.re.match`, `ngx.re.find` и `ngx.re.sub`. Это может быть полезно в некоторых случаях, когда используются старые библиотеки PCRE, но вызовет серьёзную деградацию производительности, поэтому использование этой опции настоятельно не рекомендуется; вместо этого пользователям рекомендуется собрать OpenResty с современной библиотекой PCRE, поддерживающей JIT.

*Пример*:```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

*Default*: пусто

Определяет, какие дополнительные переменные из `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

Включить SSL-соединения при ведении журнала через TCP/UDP.

Пример:```lua location / { access_by_lua_block { waf:set_option("event_log_ssl", true) } }

root@kitploit:~
### event_log_ssl_sni_host

*По умолчанию*: none

Установите SNI-хост для подключений `lua-resty-logger-socket`.

*Пример*:```lua
location / {
    access_by_lua_block {
        waf:set_option("event_log_ssl_sni_host", "loghost.example.com")
    }
}

event_log_ssl_verify

По умолчанию: false

Включить проверку сертификатов для SSL-соединений при ведении журнала через TCP/UDP.

Пример:```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

*По умолчанию*: не задано

Определяет целевой сервер для журналов событий, которые направляются на удалённый сервер.

*Пример*:```lua
location / {
    access_by_lua_block {
        waf:set_option("event_log_target_host", "10.10.10.10")
    }
}

event_log_target_path

По умолчанию: нет

Определяет целевой путь для журналов событий, которые направляются в локальную файловую систему.

Пример:```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

По умолчанию: нет

Переопределяет функциональность действий, выполняемых при срабатывании правила. Более подробно см. в примере.

Пример:```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

*По умолчанию*: none

Инструктирует модуль игнорировать указанный идентификатор правила. Обратите внимание, что игнорирование правила в цепочке приведёт к игнорированию всей цепочки, и обработка продолжится со следующего правила после цепочки.

*Пример*:```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

Default: none

Задает DNS-резолвер(ы), используемые для RBL-запросов. В настоящее время поддерживается только трафик 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 в upstream-запросе, значением которого является идентификатор транзакции. Этот идентификатор будет коррелировать с идентификатором транзакции, присутствующим в журналах отладки (если они включены). Это может быть полезно для отслеживания запросов или целей отладки.

Пример:```lua location / { access_by_lua_block { waf:set_option("req_tid_header", true) } }

root@kitploit:~
### res_body_max_size

*По умолчанию*: 1048576 (1 МБ)

Определяет порог длины содержимого, при превышении которого тела ответов не будут обрабатываться. Этот размер тела ответа определяется заголовком ответа 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"

Определяет MIME-типы, с которыми lua-resty-waf будет обрабатывать тело ответа. Это значение определяется заголовком 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:~
Несколько MIME-типов можно добавить, передав таблицу типов в `set_option`.

### res_tid_header

*По умолчанию*: false

Устанавливает HTTP-заголовок `X-Lua-Resty-WAF-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

*Default*: 10000

Настройте (в миллисекундах) тайм-аут для cosocket keepalive-пула для удаленных хостов постоянного хранилища.

*Пример*:```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

Default: 6379

Определите порт для использования при использовании redis в качестве механизма постоянного хранения переменных.

Пример:```lua location / { acccess_by_lua_block { waf:set_option("storage_redis_port", 6397) } }

root@kitploit:~
### storage_zone

*По умолчанию*: none

Определяет `lua_shared_dict`, который будет использоваться для хранения данных постоянного хранилища. Эта зона должна быть определена в блоке `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-resty-waf в обработчике фазы lua, отсутствующем в этом списке, приведёт к некорректной работе. Все данные, доступные на более ранней фазе, доступны и на более поздней фазе. То есть данные, доступные на фазе 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: SQLi
  • 42000_xss: XSS
  • 90000_custom: Пользовательские правила/виртуальное патчирование
  • 99000_scoring: Обработка оценки аномалий

Определения правил

lua-resty-waf разбирает определения правил из JSON-блобов, хранящихся на диске. Правила группируются по назначению и серьёзности и образуют набор правил. Включённые наборы правил были созданы для имитации некоторой функциональности ModSecurity CRS, особенно определений base_rules. Кроме того, включённый скрипт modsec2lua-resty-waf.pl можно использовать для преобразования дополнительных или пользовательских наборов правил в JSON-блоб, совместимый с lua-resty-waf.

Обратите внимание, что в скрипте преобразования есть несколько ограничений в отношении неподдерживаемых действий, коллекций и операторов. Актуальный список известных несовместимостей см. на этой странице вики.

Примечания

Сообщество

Существует IRC-канал Freenode #lua-resty-waf. Travis CI отправляет сюда уведомления; не стесняйтесь также задавать вопросы и оставлять комментарии в этом канале.

Кроме того, вопросы и ответы доступны на CodeWake:

Codewake

Pull Requests

Направляйте все pull request'ы в ветку разработки или в функциональную ветку, если PR является значительным изменением. Коммиты в master должны поступать только в виде обновлений документации или других изменений, которые не влияют на сам модуль (и могут быть без конфликтов объединены с веткой разработки).

Дорожная карта

  • Расширенный набор правил виртуального патчирования: Увеличение покрытия новых угроз.
  • Расширенное интеграционное/приёмочное тестирование: Увеличение покрытия распространённых угроз и сценариев использования.
  • Расширенные преобразования синтаксиса ModSecurity: Поддержка большего числа операторов, переменных и действий.
  • Профили распространённых приложений: Настроенные наборы правил для распространённых CMS/приложений.
  • Поддержка нескольких целей журналирования через сокет/файл: Вероятно, потребует форка проекта lua-resty-logger-socket.

Ограничения

lua-resty-waf находится в процессе постоянной разработки и улучшения и, как следствие, может иметь ограничения в функциональности и производительности. Текущие известные ограничения можно найти в трекере проблем GitHub для этого репозитория.

Лицензия

Эта программа является свободным программным обеспечением: вы можете распространять и/или изменять её в соответствии с условиями Стандартной общественной лицензии GNU, опубликованной Фондом свободного программного обеспечения, либо версии 3 этой лицензии, либо (по вашему выбору) любой более поздней версии.

Эта программа распространяется в надежде, что она будет полезной, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ; без даже подразумеваемой гарантии КОММЕРЧЕСКОЙ ЦЕННОСТИ или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННОЙ ЦЕЛИ. Подробнее см. Стандартную общественную лицензию GNU.

Вы должны были получить копию Стандартной общественной лицензии GNU вместе с этой программой. Если вы её не получили, см. http://www.gnu.org/licenses/

Ошибки

Пожалуйста, сообщайте об ошибках, создавая тикет в трекере проблем GitHub.

См. также

  • Проект OpenResty: http://openresty.org/
  • Мой личный блог с обновлениями и заметками о разработке lua-resty-waf: http://www.cryptobells.com/tag/lua-resty-waf/
Скачать инструмент