简介:本文详细介绍如何基于ngx_lua_waf模块配置Web应用防火墙,涵盖模块原理、安装部署、规则配置及性能优化,助力开发者构建高效安全防护体系。
ngx_lua_waf是基于OpenResty(Nginx+Lua)开发的轻量级Web应用防火墙模块,其核心优势在于通过Lua脚本实现灵活的规则引擎,能够实时拦截SQL注入、XSS跨站脚本、CC攻击等常见Web威胁。与传统硬件WAF相比,ngx_lua_waf具有以下特点:
典型应用场景包括中小型网站的防护、API接口保护及CDN边缘节点的安全加固。其工作原理可分为三个阶段:请求解析(提取URI、参数、Header等)、规则匹配(基于正则或黑白名单)、动作执行(拦截、放行或限速)。
安装OpenResty:
# CentOS示例yum install -y yum-utilsyum-config-manager --add-repo https://openresty.org/package/centos/openresty.repoyum install -y openresty
下载ngx_lua_waf:
git clone https://github.com/loveshell/ngx_lua_waf.git /usr/local/ngx_lua_waf
配置Nginx:
在nginx.conf的http块中添加:
lua_package_path "/usr/local/ngx_lua_waf/lib/?.lua;;";lua_shared_dict limit_req_store 100m;init_by_lua_file /usr/local/ngx_lua_waf/init.lua;access_by_lua_file /usr/local/ngx_lua_waf/waf.lua;
通过curl发送测试请求:
curl -I "http://localhost/?id=1' OR '1'='1"
预期返回403状态码,表示SQL注入规则生效。
/usr/local/ngx_lua_waf/├── config.lua # 全局配置├── rule/ # 规则目录│ ├── args.rule # 参数规则│ ├── url.rule # URI规则│ └── post.rule # POST数据规则└── waf.lua # 主逻辑
config.lua核心参数:
config_waf_enable = 1 -- 启用WAFconfig_log_dir = "/tmp/waf_log" -- 日志路径config_rule_dir = "/usr/local/ngx_lua_waf/rule" -- 规则目录config_max_req_per_ip = 100 -- IP限速config_under_attack = 0 -- 紧急防护模式
规则编写规范(以args.rule为例):
# 格式:规则ID|匹配模式|动作|日志描述1001|select.*from|\"block\"|\"SQL注入检测\"1002|<script.*?>|\"block\"|\"XSS攻击检测\"
CC攻击防护:
-- 在waf.lua中添加local limit_req = require "resty.limit.req"local limiter, err = limit_req.new("limit_req_store", 10, 5) -- 10r/s,突发5if not limiter thenngx.log(ngx.ERR, "failed to instantiate a resty.limit.req object: ", err)return ngx.exit(500)endlocal key = ngx.var.binary_remote_addrlocal delay, err = limiter:incoming(key, true)if not delay thenif err == "rejected" thenngx.exit(429)endngx.log(ngx.ERR, "failed to limit req: ", err)return ngx.exit(500)end
规则精简:
^/admin/替代复杂路径匹配)日志异步化:
-- 修改init.lua中的日志函数local async_log = function(msg)local ok, err = ngx.thread.spawn(function()local file = io.open(config_log_dir.."/waf_"..ngx.localtime():gsub(":", ""), "a")if file thenfile:write(os.date("%Y-%m-%d %H:%M:%S").." "..msg.."\n")file:close()endend)if not ok thenngx.log(ngx.ERR, "async log failed: ", err)endend
内存调优:
# 在nginx.conf中调整共享内存大小lua_shared_dict limit_req_store 512m; # 默认10m可能不足lua_shared_dict waf_cache 256m; # 用于缓存规则
分级防护:
监控告警:
# 通过Prometheus监控拦截量curl -s "http://localhost:9145/metrics" | grep waf_blocked_total
应急响应:
config_under_attack = 1iptables -A INPUT -s 攻击IP -j DROP临时封禁问题1:规则生效但误拦截正常请求
config_white_url = {"/api/health","/static/"}config_white_ip = {"192.168.1.100"}
问题2:高并发下出现502错误
# 统计TOP10拦截规则awk -F'|' '{print $3}' /tmp/waf_log/* | sort | uniq -c | sort -nr | head -10# 分析攻击来源IPawk '{print $1}' /tmp/waf_log/* | sort | uniq -c | sort -nr
威胁情报联动:
-- 通过API获取实时黑名单local http = require "resty.http"local httpc = http.new()local res, err = httpc:request_uri("https://threatfeed.example.com/iplist", {method = "GET",headers = {["Authorization"] = "Bearer API_KEY"}})if res and res.body thenlocal ips = cjson.decode(res.body).ipsfor _, ip in ipairs(ips) doconfig_black_ip[ip] = trueendend
SIEM系统对接:
waf_type=>threat.type配置原则:
性能基准:
持续改进:
通过合理配置ngx_lua_waf模块,开发者可在不显著影响性能的前提下,构建起符合等保2.0要求的Web应用防护体系。实际部署中需结合业务特点进行调优,建议先在测试环境验证规则,再逐步推广至生产环境。