a little waf
TRANSCRIPT
![Page 2: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/2.jpg)
A Web Application Firewall (or WAF) is a firewall that filters, monitors, and blocks HTTP/S traffic to and from a web
application
![Page 3: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/3.jpg)
Background1. IP Deny — Blacklist and Whitelist with time expire 2. Common Web Attacks Protection like XSS、SQLInject
![Page 4: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/4.jpg)
According the cloudflare blog post in 2013 cloudflares-new-waf-compiling-to-lua
https://blog.cloudflare.com/cloudflares-new-waf-compiling-to-lua/
Principe
![Page 5: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/5.jpg)
Architecture
![Page 6: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/6.jpg)
Nginx Confhttp { init_by_lua_block { local wafinit = require("bkb.waf-init") wafinit.run("/tmp/waf") } access_by_lua_block { local waf = require("bkb.waf") waf.run()
} log_by_lua_block { local waflog = require("bkb.waf-log") waflog.run() }
}
![Page 7: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/7.jpg)
ModSecurityOpen Source Web Application Firewall
https://modsecurity.org/
apache module ModSecurity
Now Nginx Plus Support ModSecurity
![Page 8: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/8.jpg)
OWASP ModSecurity Core Rule Set (CRS)
https://github.com/SpiderLabs/owasp-modsecurity-crs
![Page 9: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/9.jpg)
SecRule ARGS:comment_post_id “@rx ^(\d+)$” "drop,id:WP0005,msg:'Exploit DB 28485 Blind SQL Injection’,phase:0"
SecRule URI “@endsWith .git” “drop,id:WP0006,msg:'Scan .GIT Directory’,phase:0”
![Page 10: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/10.jpg)
Key Concept
![Page 11: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/11.jpg)
if operator(transform(variable), pattern) then action else continue end
![Page 12: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/12.jpg)
VariablePOST / HTTP/1.1 (Request Line) Host: www.google.com (Request Header) Connection: keep-alive Content-Length: 5 Cookie: a=1;b=2;
q=123 (Request Body)
![Page 13: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/13.jpg)
Available Variables
'ip', 'uri', 'request_headers', 'request_cookies', 'args', 'matched_var'
![Page 14: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/14.jpg)
Available Operators
'eq', 'rx', 'ipMatch', 'beginsWith', 'endsWith', 'ge', 'gt', 'lt', 'le', 'empty', 'nonEmpty', 'within', 'pmFromFile', 'pm'
![Page 15: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/15.jpg)
Available Transforms 'urlDecodeUni', 'jsDecode', 'lowercase', 'base64Decode',
'base64Encode', 'length', 'sha1', 'htmlEntityDecode', 'compressWhitespace',
'removeWhitespace', 'cssDecode'
![Page 16: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/16.jpg)
Available Actions
'deny', 'skip', 'log'
![Page 17: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/17.jpg)
WAF Rule Format
![Page 18: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/18.jpg)
Rule To Lua
![Page 19: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/19.jpg)
Rule To Test Code
![Page 20: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/20.jpg)
Rule To Test Code
![Page 21: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/21.jpg)
Hot Load Rules
base on Lua global table package.loaded
![Page 22: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/22.jpg)
local chunk, err = loadstring(code, ‘=rule.lua’)
if not err then package.loaded[‘rule’] = chunk()
end
loadstring
PS: LuaVM
![Page 23: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/23.jpg)
Dry Mode and Run Mode
dry mode: only logging run mode: dis/enable WAF
![Page 24: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/24.jpg)
Dry Mode and Run Mode
lua_shared_dict
![Page 25: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/25.jpg)
Dry Mode and Run Modebase on lua_shared_dict
multi process are communicated with shared memory
![Page 26: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/26.jpg)
Side Effect every request will try to get four locks: ip lock、rule lock、dry lock 、run lock.
ngx_shmtx_lock(&ctx->shpool->mutex);
![Page 27: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/27.jpg)
Side Effect every request will try to get four locks: ip lock、rule lock、dry lock 、run lock.
ngx_shmtx_lock(&ctx->shpool->mutex);
lock time O(log n) based on red black tree
![Page 28: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/28.jpg)
Logging
lua-resty-logger-socket
base on cosocket
![Page 29: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/29.jpg)
Logging
RFC 5424 to rsyslog server
![Page 30: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/30.jpg)
delay
max: 20ms min: 5us avg: 350us
![Page 31: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/31.jpg)
API For OPserver { listen 80; server_name bkb;
allow 127.0.0.1; allow 10.10.0.0/16; deny all;
location / { content_by_lua_block { local wafapi = require("bkb.waf-api"); wafapi.run("/data/waf/mode") } } }
![Page 32: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/32.jpg)
curl -H "Host: bkb” "http://$hostname/waf"
waf dashboard for monitor
API For OP
PS: tsar support
![Page 33: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/33.jpg)
curl -H "Host: bkb” "http://$hostname/waf"API For OP
{ totaldelay: 2263817, waf_mode_file: "/tmp/waf", rule: { version: xxxx}, ip: { version: yyyyy}, delay: 144.884288, dry: false, totalcnt: 15625, trigger: 2, run: true
}
![Page 34: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/34.jpg)
curl -H "Host: bkb" -X POST -d "dry=1" "http://$hostname/waf"
let waf enter dry mode with fs persistence
API For OP
curl -H "Host: bkb" -X POST -d "dry=1" "http://$hostname/waf"
let waf exit dry mode
![Page 35: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/35.jpg)
curl -H "Host: bkb" -X POST -d "run=1" "http://$hostname/waf"
let waf enable run mode with fs persistence
API For OP
curl -H "Host: bkb" -X POST -d "run=0" "http://$hostname/waf"
let waf disable run mode
![Page 36: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/36.jpg)
curl -H "Host: bkb" -X PUT "http://$hostname/rule"
hot load the new rule
API For OP
hot load the new ip
curl -H "Host: bkb" -X PUT "http://$hostname/ip"
![Page 37: A little waf](https://reader030.vdocuments.net/reader030/viewer/2022021416/58f1f3a61a28abe8468b45b1/html5/thumbnails/37.jpg)
Any questions ?