
lua-resty-waf - OpenResty スタック上に構築された高性能 WAF
注記: lua-resty-waf は実質的に放棄されています。このプロジェクトは、Nginx 向け ModSecurity が実行可能な選択肢ではなかった時代に役割がありましたが、もはやそうではありません。2020年にプロジェクトを再生させる試みがありましたが、私にはこれを完了するリソースがありません。この作業は redux ブランチで部分的に完了しています。
lua-resty-waf は、OpenResty スタックを使用して構築されたリバースプロキシ WAF です。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 モジュールパッケージを使用して構築されたプラットフォームではテストされていません。
最適な正規表現コンパイルパフォーマンスを得るには、JIT コンパイルをサポートするバージョンの PCRE を使用して Nginx/OpenResty をビルドすることをお勧めします。OS がこれを提供しない場合、JIT 対応の PCRE を Nginx/OpenResty ビルドに直接組み込むことができます。これを行うには、--with-pcre 設定フラグで PCRE ソースへのパスを指定します。例:```sh
PCREソースは[PCREウェブサイト](http://www.pcre.org/)からダウンロードできます。JIT対応のPCREライブラリを使用したOpenRestyの構築手順については、こちらの[ブログ記事](https://www.cryptobells.com/building-openresty-with-pcre-jit/)も参照してください。
## パフォーマンス
lua-resty-wafは、効率性とスケーラビリティを念頭に設計されています。Nginxの非同期処理モデルと効率的な設計を活用し、各トランザクションを可能な限り迅速に処理します。負荷テストによると、ModSecurity CRSの背後にあるロジックを模倣するように設計された、提供されているすべてのルールセットを実装したデプロイメントでは、リクエストあたり約300〜500マイクロ秒でトランザクションを処理します。これは[CloudflareのWAF](https://www.cloudflare.com/waf)が宣伝するパフォーマンスに相当します。テストは妥当なハードウェア構成(E3-1230 CPU、32 GB RAM、RAID 0の2 x 840 EVO)で実行され、最大で毎秒約15,000リクエストを処理しました。詳細については、[こちらのブログ記事](http://www.cryptobells.com/freewaf-a-high-performance-scalable-open-web-firewall)を参照してください。
lua-resty-wafのワークロードは、ほぼ完全にCPUバウンドです。Lua VM内のメモリフットプリント(`lua-shared-dict`に支えられた永続ストレージを除く)は、およそ2MBです。
## インストール
シンプルなMakefileが提供されています:```
# make && sudo make install
または、Luarocks 経由でインストール:```
lua-resty-waf は、[OPM](https://github.com/openresty/opm) パッケージマネージャーを利用します。これは最新の OpenResty ディストリビューションで利用可能です。クライアント OPM ツールを使用するには、システムの `PATH` 環境変数に `resty` コマンドラインツールが含まれている必要があります。
デフォルトでは、lua-resty-waf はアプリケーションに即座に影響を与えないよう SIMULATE モードで実行されることに注意してください。ルールアクションを有効にしたいユーザーは、運用モードを明示的に ACTIVE に設定する必要があります。
## 概要```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()
}
}
}
}
ModSecurity SecRules ファイルをディスクから変換して初期化します。なお、ルールセットは add_ruleset で追加する必要があります(キーにはファイルの basename を指定する必要があります)。