Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(waf): 优化规则 #4166

Merged
merged 1 commit into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion frontend/src/lang/modules/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2225,6 +2225,20 @@ const message = {
ipEnd: 'End IP',
ipv4: 'IPV4',
ipv6: 'IPV6',
urlDefense: 'URL rules',
urlHelper: 'Forbidden URL',
dirFilter: 'Directory filter',
sqlInject: 'SQL injection',
xss: 'XSS',
phpExec: 'PHP script execution',
oneWordTrojan: 'One word Trojan',
appFilter: 'Apply dangerous directory filtering',
webshell: 'Webshell',
args: 'Malicious parameters',
protocolFilter: 'Protocol filter',
javaFileter: 'Java Dangerous File Filtering',
scannerFilter: 'Scanner filter',
escapeFilter: 'escape filter',
},
monitor: {
name: 'Website Monitor',
Expand Down Expand Up @@ -2259,7 +2273,7 @@ const message = {
disableHelper:
'The anti-tampering function of website {0} is about to be disabled. Do you want to continue?',
},
setting: {
setting: {
setting: 'Interface Settings',
title: 'Panel Description',
titleHelper:
Expand Down
14 changes: 14 additions & 0 deletions frontend/src/lang/modules/tw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2079,6 +2079,20 @@ const message = {
ipEnd: '結束 IP',
ipv4: 'IPV4',
ipv6: 'IPV6',
urlDefense: 'URL 規則',
urlHelper: '禁止存取的 URL',
dirFilter: '目錄過濾',
sqlInject: 'SQL 注入',
xss: 'XSS',
phpExec: 'PHP 腳本執行',
oneWordTrojan: '一句話木馬',
appFilter: '套用危險目錄過濾',
webshell: 'Webshell',
args: '惡意參數',
protocolFilter: '協議過濾',
javaFileter: 'Java 危險檔案過濾',
scannerFilter: '掃描器過濾',
escapeFilter: '轉義過濾',
},
monitor: {
name: '網站監控',
Expand Down
22 changes: 18 additions & 4 deletions frontend/src/lang/modules/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2056,13 +2056,13 @@ const message = {
sqliHelper: '识别请求中的 SQL 注入并拦截',
xssHelper: '识别请求中的 XSS 并拦截',
xssDefense: 'XSS 防御',
uaDefense: '恶意 User-Agent 规则',
uaDefense: 'User-Agent 规则',
uaHelper: '包含常见的恶意爬虫规则',
argsDefense: '恶意参数规则',
argsDefense: '参数规则',
argsHelper: '禁止请求中携带恶意参数',
cookieDefense: '恶意 Cookie 规则',
cookieDefense: 'Cookie 规则',
cookieHelper: '禁止请求中携带恶意 Cookie',
headerDefense: '恶意 Header 规则',
headerDefense: 'Header 规则',
headerHelper: '禁止请求中携带恶意 Header',
httpRule: 'HTTP 请求方法规则',
httpHelper: '限制网站的请求方法类型',
Expand All @@ -2079,6 +2079,20 @@ const message = {
ipEnd: '结束 IP',
ipv4: 'IPV4',
ipv6: 'IPV6',
urlDefense: 'URL 规则',
urlHelper: '禁止访问的 URL',
dirFilter: '目录过滤',
sqlInject: 'SQL 注入',
xss: 'XSS',
phpExec: 'PHP 脚本执行',
oneWordTrojan: '一句话木马',
appFilter: '应用危险目录过滤',
webshell: 'Webshell',
args: '恶意参数',
protocolFilter: '协议过滤',
javaFileter: 'Java 危险文件过滤',
scannerFilter: '扫描器过滤',
escapeFilter: '转义过滤',
},
monitor: {
name: '网站监控',
Expand Down
16 changes: 11 additions & 5 deletions plugins/openresty/waf/conf/global.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"action": "deny"
},
"notFoundCount": {
"state": "on",
"state": "off",
"type": "notFoundCount",
"threshold": 10,
"duration": 60,
Expand Down Expand Up @@ -85,26 +85,26 @@
"action": "deny"
},
"cc": {
"state": "on",
"state": "off",
"type": "cc",
"rule": "cc",
"tokenTimeOut": 1800,
"threshold": 100,
"threshold": 120,
"duration": 60,
"action": "deny",
"ipBlock": "on",
"ipBlockTime": 600
},
"ccurl": {
"state": "on",
"state": "off",
"type": "urlcc",
"rule": "urlcc",
"action": "deny",
"ipBlock": "on",
"ipBlockTime": 600
},
"attackCount": {
"state": "on",
"state": "off",
"type": "attackCount",
"threshold": 20,
"duration": 60,
Expand Down Expand Up @@ -143,6 +143,12 @@
"code": 403,
"action": "deny"
},
"defaultUrlBlack": {
"type": "defaultUrlBlack",
"state": "on",
"code": 403,
"action": "deny"
},
"args": {
"type": "args",
"state": "on",
Expand Down
2 changes: 2 additions & 0 deletions plugins/openresty/waf/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ local function init_global_config()
rules.args = read_rule(global_rule_dir, "args")
rules.cookie = read_rule(global_rule_dir, "cookie")
rules.defaultUaBlack = read_rule(global_rule_dir, "defaultUaBlack")
rules.defaultUrlBlack = read_rule(global_rule_dir, "defaultUrlBlack")
rules.header = read_rule(global_rule_dir, "header")

config.global_rules = rules
Expand All @@ -101,6 +102,7 @@ local function init_global_config()
_M.waf_dir = waf_dir
_M.waf_db_dir = waf_dir .. "db/"
_M.waf_db_path = _M.waf_db_dir .. "1pwaf.db"
_M.waf_log_db_path = _M.waf_db_dir .. "req_log.db"
_M.config_dir = config_dir
end

Expand Down
61 changes: 36 additions & 25 deletions plugins/openresty/waf/db.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,50 @@ local function check_table(table_name,wafdb)
return rows > 0
end

function _M.init()
local function init_db_config(db_path)
local ok, sqlite3 = pcall(function()
return require "lsqlite3"
end)
if not ok then
return false
end
local wafdb
init_dir(config.waf_db_dir)
wafdb = sqlite3.open(config.waf_db_path)
wafdb = sqlite3.open(db_path)
if wafdb == nil then
return false
end
wafdb:exec([[PRAGMA journal_mode = wal]])
wafdb:exec([[PRAGMA synchronous = 0]])
wafdb:exec([[PRAGMA page_size = 8192]])
wafdb:exec([[PRAGMA journal_size_limit = 2147483648]])
return wafdb
end

function _M.init()
init_dir(config.waf_db_dir)
local wafdb = init_db_config(config.waf_db_path)
if not wafdb then
return false
end

local status = {}
if not check_table("attack_log",wafdb) then
if not check_table("waf_stat",wafdb) then
status = wafdb:exec([[
CREATE TABLE waf_stat (
id INTEGER PRIMARY KEY AUTOINCREMENT,
day TEXT,
req_count INTEGER,
attack_count INTEGER,
count4xx INTEGER,
count5xx INTEGER,
create_date DATETIME
)]])
ngx.log(ngx.ERR, "init waf_stat status"..status)
end

local logdb = init_db_config(config.waf_log_db_path)
if not check_table("req_logs",logdb) then
status = logdb:exec([[
CREATE TABLE req_logs (
id TEXT PRIMARY KEY,
ip TEXT,
Expand All @@ -58,14 +82,14 @@ function _M.init()
ip_province_en TEXT,
ip_longitude TEXT,
ip_latitude TEXT,
time INTEGER,
localtime TEXT,
localtime DATETIME,
server_name TEXT,
website_key TEXT,
host TEXT,
method TEXT,
uri TEXT,
user_agent TEXT,
exec_rule TEXT,
rule_type TEXT,
match_rule TEXT,
match_value TEXT,
Expand All @@ -77,30 +101,17 @@ function _M.init()
)]])
end

if not check_table("block_ip",wafdb) then
status = wafdb:exec([[
CREATE TABLE block_ip (
if not check_table("block_ips",logdb) then
status = logdb:exec([[
CREATE TABLE block_ips (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ip TEXT,
is_block INTEGER,
attack_log_id INTEGER
)]])

ngx.log(ngx.ERR, "init block_ip status"..status)
end

if not check_table("waf_stat",wafdb) then
status = wafdb:exec([[
CREATE TABLE waf_stat (
id INTEGER PRIMARY KEY AUTOINCREMENT,
day TEXT,
req_count INTEGER,
attack_count INTEGER,
count4xx INTEGER,
count5xx INTEGER,
blocking_time INTEGER,
req_log_id TEXT,
create_date DATETIME
)]])
ngx.log(ngx.ERR, "init waf_stat status"..status)
ngx.log(ngx.ERR, "init block_ip status"..status)
end

ngx.log(ngx.ERR, "init db success")
Expand Down
1 change: 0 additions & 1 deletion plugins/openresty/waf/init.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
local db = require "db"
local config = require "config"
local geoip = require "geoip"

config.load_config_file()
db.init()
Expand Down
27 changes: 10 additions & 17 deletions plugins/openresty/waf/lib/action.lua
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,10 @@ end

function _M.block_ip(ip, rule)
local ok, err = nil, nil
local msg = "拉黑IP : " .. ip .. "国家 " .. ngx.ctx.geoip.country["zh"]
local msg = "拉黑IP : " .. ip .. "国家 " .. ngx.ctx.ip_location.country["zh"]
if rule then
msg = msg .. " 规则 " .. rule.type
end

ngx.log(ngx.ERR, msg)

if config.redis_on then
Expand All @@ -56,7 +55,7 @@ function _M.block_ip(ip, rule)
if exists == 0 then
ok, err = red:set(key, 1)
if ok then
ngx.ctx.ipBlocked = true
ngx.ctx.ip_blocked = true
else
ngx.log(ngx.ERR, "failed to set redis key " .. key, err)
end
Expand All @@ -76,14 +75,14 @@ function _M.block_ip(ip, rule)
if not exists then
ok, err = wafBlackIp:set(ip, 1, rule.ipBlockTime)
if ok then
ngx.ctx.ipBlocked = true
ngx.ctx.ip_blocked = true
else
ngx.log(ngx.ERR, "failed to set key " .. ip, err)
end
elseif rule.ipBlockTime > 0 then
ok, err = wafBlackIp:expire(ip, rule.ipBlockTime)
if ok then
ngx.ctx.ipBlocked = true
ngx.ctx.ip_blocked = true
else
ngx.log(ngx.ERR, "failed to expire key " .. ip, err)
end
Expand Down Expand Up @@ -128,29 +127,23 @@ end

function _M.exec_action(rule_config, match_rule, data)
local action = rule_config.action

if match_rule then
rule_config.rule = match_rule.rule
else
rule_config.rule = "默认"
rule_config.match_rule = match_rule
end

ngx.ctx.rule_table = rule_config
ngx.ctx.action = action
ngx.ctx.exec_rule = rule_config
ngx.ctx.hitData = data
ngx.ctx.is_attack = true

if rule_config.ipBlock and rule_config.ipBlock == 'on' then
_M.block_ip(ngx.ctx.ip, rule_config)
end

if rule_config.type == nil then
rule_config.type = "默认"
end

attack_count(rule_config.type)

local msg = "访问 IP " .. ngx.ctx.ip .. " 访问 URL" .. ngx.var.uri .. " 触发动作 " .. action .. " User-Agent " .. ngx.ctx.ua .. " 规则类型 " .. rule_config.type .. " 规则 " .. rule_config.rule
local msg = "访问 IP " .. ngx.ctx.ip .. " 访问 URL" .. ngx.var.uri .. " 触发动作 " .. action .. " 规则类型 " .. rule_config.type
if match_rule then
msg = msg .. " 触发规则 " .. match_rule.type
end

ngx.log(ngx.ERR, msg)
if action == "allow" then
Expand Down
Loading
Loading