
OpenResty 스택 기반의 고성능 WAF
lua-resty-waf - OpenResty 스택 기반의 고성능 WAF
참고: lua-resty-waf는 본질적으로 중단된 프로젝트입니다. 이 프로젝트는 ModSecurity for Nginx가 실행 가능한 선택지가 아니던 시절에 유용했지만, 이제는 더 이상 그렇지 않습니다. 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에 패키징되어 있어 별도로 설치할 필요가 없습니다. OpenResty 소프트웨어 번들이 실행되는 시스템에 lua-resty-waf를 설치하는 것이 좋습니다. 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/)도 참조하세요.
## Performance
lua-resty-waf는 효율성과 확장성을 염두에 두고 설계되었습니다. Nginx의 비동기 처리 모델과 효율적인 설계를 활용하여 각 트랜잭션을 가능한 한 빠르게 처리합니다. 부하 테스트 결과, ModSecurity CRS의 논리를 모방하도록 설계된 모든 제공 규칙 세트를 구현한 배포 환경은 요청당 약 300~500마이크로초 만에 트랜잭션을 처리하는 것으로 나타났습니다. 이는 [Cloudflare의 WAF](https://www.cloudflare.com/waf)가 광고하는 성능과 동일합니다. 테스트는 합리적인 하드웨어 스택(E3-1230 CPU, 32GB RAM, RAID 0 구성의 840 EVO 2개)에서 실행되었으며, 초당 약 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는 최신 OpenResty 배포판에서 사용할 수 있는 [OPM](https://github.com/openresty/opm) 패키지 관리자를 사용합니다. OPM 클라이언트 도구를 사용하려면 시스템의 `PATH` 환경 변수에 `resty` 명령줄 도구가 있어야 합니다.
기본적으로 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()
}
}
}
}
디스크에서 ModSecurity SecRules 파일을 변환하고 초기화합니다. 이 경우에도 규칙 세트는 add_ruleset을 통해 추가되어야 합니다 (파일의 basename이 키로 제공되어야 합니다).