feat(waf): 优化规则 (#4166)

This commit is contained in:
zhengkunwang 2024-03-12 20:34:07 +08:00 committed by GitHub
parent 3b697c7520
commit 77f4f64f0d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 813 additions and 10385 deletions

View file

@ -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',
@ -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:

View file

@ -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: '網站監控',

View file

@ -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: '限制网站的请求方法类型',
@ -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: '网站监控',

View file

@ -39,7 +39,7 @@
"action": "deny"
},
"notFoundCount": {
"state": "on",
"state": "off",
"type": "notFoundCount",
"threshold": 10,
"duration": 60,
@ -85,18 +85,18 @@
"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",
@ -104,7 +104,7 @@
"ipBlockTime": 600
},
"attackCount": {
"state": "on",
"state": "off",
"type": "attackCount",
"threshold": 20,
"duration": 60,
@ -143,6 +143,12 @@
"code": 403,
"action": "deny"
},
"defaultUrlBlack": {
"type": "defaultUrlBlack",
"state": "on",
"code": 403,
"action": "deny"
},
"args": {
"type": "args",
"state": "on",

View file

@ -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
@ -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

View file

@ -28,7 +28,7 @@ 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)
@ -36,8 +36,7 @@ function _M.init()
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
@ -45,50 +44,17 @@ function _M.init()
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
status = wafdb:exec([[
CREATE TABLE req_logs (
id TEXT PRIMARY KEY,
ip TEXT,
ip_iso TEXT,
ip_country_zh TEXT,
ip_country_en TEXT,
ip_province_zh TEXT,
ip_province_en TEXT,
ip_longitude TEXT,
ip_latitude TEXT,
time INTEGER,
localtime TEXT,
server_name TEXT,
website_key TEXT,
host TEXT,
method TEXT,
uri TEXT,
user_agent TEXT,
rule_type TEXT,
match_rule TEXT,
match_value TEXT,
nginx_log TEXT,
blocking_time INTEGER,
action TEXT,
is_block INTEGER,
is_attack INTEGER
)]])
end
if not check_table("block_ip",wafdb) then
status = wafdb:exec([[
CREATE TABLE block_ip (
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 (
@ -102,6 +68,51 @@ function _M.init()
)]])
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,
ip_iso TEXT,
ip_country_zh TEXT,
ip_country_en TEXT,
ip_province_zh TEXT,
ip_province_en TEXT,
ip_longitude TEXT,
ip_latitude 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,
nginx_log TEXT,
blocking_time INTEGER,
action TEXT,
is_block INTEGER,
is_attack INTEGER
)]])
end
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,
blocking_time INTEGER,
req_log_id TEXT,
create_date DATETIME
)]])
ngx.log(ngx.ERR, "init block_ip status"..status)
end
ngx.log(ngx.ERR, "init db success")
end

View file

@ -1,6 +1,5 @@
local db = require "db"
local config = require "config"
local geoip = require "geoip"
config.load_config_file()
db.init()

View file

@ -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
@ -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
@ -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
@ -128,15 +127,10 @@ 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
@ -144,13 +138,12 @@ function _M.exec_action(rule_config, match_rule, data)
_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

View file

@ -6,7 +6,6 @@ local ck = require "resty.cookie"
local geo = require "geoip"
local libinjection = require "resty.libinjection"
local config = require "config"
local cjson = require "cjson"
local utils = require "utils"
local pairs = pairs
@ -14,12 +13,13 @@ local ipairs = ipairs
local tostring = tostring
local type = type
local next = next
local tonumber = tonumber
local concat_table = table.concat
local ngx_re_find = ngx.re.find
local decode = cjson.decode
local ngx_re_gmatch = ngx.re.gmatch
local ngx_re_match = ngx.re.match
local ipv4_to_int = utils.ipv4_to_int
local is_ip_in_array = utils.is_ip_in_array
local is_ipv6 = utils.is_ipv6
local exec_action = action.exec_action
@ -97,7 +97,7 @@ local function match_ip(ip_rule, ip, ipn)
return false
end
local ip_rule_type = ip_rule.type
if utils.is_ipv6(ip) and ip_rule_type == "ipv6" then
if is_ipv6(ip) and ip_rule_type == "ipv6" then
if ip == ip_rule.ipv6 then
return true
end
@ -105,12 +105,13 @@ local function match_ip(ip_rule, ip, ipn)
end
if ip_rule.type == "ipv4" then
if ipn == tonumber(ip_rule.ipv4) then
if ipn == ipv4_to_int(ip_rule.ipv4) then
return true
end
elseif ip_rule.type == "ipArr" then
local ipArr = ip_rule.ipArr
if utils.is_ip_in_array(ipn, ipArr.start, ipArr["end"]) then
local ip_start_n = ipv4_to_int(ip_rule.ipStart)
local ip_end_n = ipv4_to_int(ip_rule.ipEnd)
if is_ip_in_array(ipn, ip_start_n, ip_end_n) then
return true
end
elseif ip_rule.type == "ipGroup" then
@ -120,34 +121,50 @@ local function match_ip(ip_rule, ip, ipn)
return false
end
local function xss_and_sql_check(body)
if body then
if is_global_state_on("xss") or is_global_state_on("sql") then
for k, v in pairs(body) do
if type(v) == 'string' then
if is_site_state_on("xss") then
local is_xss, fingerprint = libinjection.xss(tostring(v))
local xss_config = get_site_config("xss")
if is_xss then
exec_action(xss_config, { rule = tostring(k) .. '=' .. tostring(v) })
return
end
end
if is_site_state_on("sql") then
local is_sqli, fingerprint = libinjection.sqli(tostring(v))
local sql_config = get_site_config("sql")
if is_sqli then
exec_action(sql_config, { rule = tostring(k) .. '=' .. tostring(v) })
return
end
end
end
end
end
local function get_boundary()
local header = utils.get_headers()["content-type"]
if not header then
return nil
end
if type(header) == "table" then
header = header[1]
end
local m = ngx_re_match(header, ";%s*boundary=\"([^\"]+)\"")
if m then
return m
end
return ngx_re_match(header, ";%s*boundary=([^\",;]+)")
end
local function xss_and_sql_check(kv)
if type(kv) ~= 'string' then
return
end
if is_site_state_on("xss") then
local is_xss, fingerprint = libinjection.xss(tostring(kv))
local xss_config = get_site_config("xss")
if is_xss then
exec_action(xss_config, { rule = kv })
return
end
end
if is_site_state_on("sql") then
local is_sqli, fingerprint = libinjection.sqli(tostring(kv))
local sql_config = get_site_config("sql")
if is_sqli then
exec_action(sql_config, { rule = kv })
return
end
end
end
local function get_request_body()
ngx.req.read_body()
local body_data = ngx.req.get_body_data()
@ -182,9 +199,9 @@ end
function _M.allow_location_check()
if is_state_on("geoRestrict") then
local geo_ip = ngx.ctx.geoip
if geo_ip and geo_ip.iso and geo_ip.iso ~= "" then
local iso = geo_ip.iso
local ip_location = ngx.ctx.ip_location
if ip_location and ip_location.iso and ip_location.iso ~= "" then
local iso = ip_location.iso
local geo_config = get_site_config("geoRestrict")
local exist = false
for _, rule in ipairs(geo_config.rules) do
@ -233,7 +250,7 @@ function _M.black_ip()
if ip == "unknown" then
return false
end
local exists = nil
local exists = false
if config.is_redis_on() then
exists = redis_util.get("black_ip:" .. ip)
@ -241,14 +258,12 @@ function _M.black_ip()
exists = ngx.shared.waf_black_ip:get(ip)
end
if not exists then
local ip_black_list = get_global_rules("ipBlack")
local ipn = utils.ipv4_to_int(ip)
for _, ip_rule in pairs(ip_black_list) do
if match_ip(ip_rule, ip, ipn) then
exists = true
break
end
local ip_black_list = get_global_rules("ipBlack")
local ipn = ipv4_to_int(ip)
for _, ip_rule in pairs(ip_black_list) do
if match_ip(ip_rule, ip, ipn) then
exists = true
break
end
end
@ -424,6 +439,20 @@ function _M.black_url()
end
end
function _M.default_url_black()
if is_state_on("defaultUrlBlack") then
local url = ngx.var.uri
if url == nil or url == "" then
return false
end
local m, mr = match_rule(get_global_rules('defaultUrlBlack'), url)
if m then
exec_action(get_global_config('defaultUrlBlack'), mr)
return
end
end
end
function _M.args_check()
if is_state_on("args") then
local args = ngx.req.get_uri_args()
@ -436,13 +465,14 @@ function _M.args_check()
end
if val_arr and type(val_arr) ~= "boolean" and val_arr ~= "" then
local m, mr = match_rule(args_list, utils.unescape_uri(val_arr))
ngx.log(ngx.ERR, "args_check: ", m, " ", mr.rule, " ", val_arr)
if m then
exec_action(get_global_config("args"), mr)
return
end
xss_and_sql_check(val_arr)
end
end
xss_and_sql_check(args)
end
end
end
@ -453,8 +483,7 @@ function _M.cookie_check()
local cookieList = get_site_rule('cookie')
local m, mr = match_rule(cookieList, cookie)
if m then
local rule_config = get_global_config('cookie')
exec_action(rule_config, mr)
exec_action(get_global_config('cookie'), mr)
return true
end
end
@ -500,15 +529,10 @@ function _M.post_check()
return
end
if ngx_re_find(content_type, '^application/json', "ijo") then
local data = get_request_body()
if data then
xss_and_sql_check(decode(data))
end
end
local boundary = get_boundary()
if is_site_state_on('fileExtCheck') and ngx_re_find(content_type, [[multipart]], 'ijo') then
if not ngx_re_match(content_type, '^multipart/form-data; boundary=') then
if boundary and is_site_state_on('fileExtCheck') then
if not ngx_re_match(content_type, '^multipart/form-data; boundary=') or not ngx_re_find(content_type, [[multipart]], 'ijo')then
return
end
local boundary_value = ngx_re_match(content_type, '^multipart/form-data; boundary=(.+)')
@ -541,6 +565,27 @@ function _M.post_check()
break
end
end
else
ngx.req.read_body()
local body_obj = ngx.req.get_post_args()
if not body_obj then
return
end
for key, val in pairs(body_obj) do
if is_global_state_on("xss") or is_global_state_on("sql") then
xss_and_sql_check(key)
xss_and_sql_check(val)
end
if is_state_on("args") then
local post_rules = get_global_rules("args")
local m, mr = match_rule(post_rules, val)
if m then
exec_action(get_global_config("args"), mr)
return
end
end
end
end
end

View file

@ -7,6 +7,7 @@ local ipairs = ipairs
local type = type
local find_str = string.find
local gmatch_str = string.gmatch
local pcall = pcall
local cjson = require "cjson"
local _M = {}
@ -116,15 +117,13 @@ function _M.get_real_ip()
return "unknown"
end
function _M.get_geo_ip(ip)
function _M.get_ip_location(ip)
if _M.is_intranet_address(ip) then
return {
country = { ["zh"] = "内网", ["en"] = "intranet" },
province = { ["zh"] = "内网", ["en"] = "intranet" },
city = { ["zh"] = "内网", ["en"] = "intranet" },
country = { ["zh"] = "内网", ["en"] = "Intranet" },
longitude = 0,
latitude = 0,
iso = "local"
iso = "Local"
}
else
geoip.init()

View file

@ -7,103 +7,111 @@ local uuid = require"resty.uuid"
local upper_str = string.upper
local tonumber = tonumber
local pairs = pairs
local type = type
local concat_table = table.concat
local function write_req_log(wafdb,attack)
local rule_table = nil
local action = ""
local rule = nil
local rule_type = ""
local is_attack = 0
local is_block = 0
local blocking_time = 0
if attack then
rule_table = ngx.ctx.rule_table
action = ngx.ctx.action
rule = rule_table.rule
rule_type = rule_table.type
is_attack = 1
if not rule_type then
rule_type = "default"
end
if ngx.ctx.ipBlocked then
is_block = 1
blocking_time = tonumber(rule_table.ipBlockTime)
end
local function write_req_log(attack)
local wafdb = utils.get_wafdb(config.waf_log_db_path)
if not wafdb then
ngx.log(ngx.ERR, "get log db failed")
return
end
local real_ip = ngx.ctx.ip
local geoip = ngx.ctx.geoip
local ip_location = ngx.ctx.ip_location
local country
local province
local longitude = 0.0
local latitude = 0.0
local iso = "CN"
if geoip then
country = geoip.country
province = geoip.province
longitude = geoip.longitude
latitude = geoip.latitude
iso = geoip.iso
else
ngx.log(ngx.ERR, real_ip .. " 无法获取地址")
end
if not country then
country = {
if ip_location then
country = ip_location.country or {
["zh"] = "unknown",
["en"] = "unknown"
}
end
if not province then
province = {
["zh"] = "unknown",
["en"] = "unknown"
province = ip_location.province or {
["zh"] = "",
["en"] = ""
}
longitude = ip_location.longitude
latitude = ip_location.latitude
iso = ip_location.iso
end
local method = ngx.req.get_method()
local uri = ngx.var.request_uri
local ua = ngx.ctx.ua
local host = ngx.var.server_name
local protocol = ngx.var.server_protocol
local website_key = ngx.ctx.website_key
local logs_str = method .. " " .. uri .. " "..protocol.."\n"
local headers = ngx.req.get_headers(20000)
for k, v in pairs(headers) do
local value = ""
if v then
if type(v) == "table" then
value = table.concat(v, ",")
else
value = v
end
local exec_rule = {}
local rule_action = ""
local exec_rule_type = ""
local match_rule_detail = ""
local match_rule_type = ""
local is_attack = 0
local is_block = 0
local blocking_time = 0
local method = ""
local uri = ""
local ua = ""
local host = ""
local protocol = ""
local website_key = ""
local logs_str = ""
if attack then
exec_rule = ngx.ctx.exec_rule
rule_action = exec_rule.action
exec_rule_type = exec_rule.type
is_attack = 1
method = ngx.req.get_method()
uri = ngx.var.request_uri
ua = ngx.ctx.ua
host = ngx.var.server_name
protocol = ngx.var.server_protocol or ""
website_key = ngx.ctx.website_key
if exec_rule.match_rule then
match_rule_detail = exec_rule.match_rule.rule
match_rule_type = exec_rule.match_rule.type
end
if ngx.ctx.ip_blocked then
is_block = 1
blocking_time = tonumber(exec_rule.ipBlockTime)
end
logs_str = method .. " " .. uri .. " "..protocol.."\n"
local headers = ngx.req.get_headers(20000)
for k, v in pairs(headers) do
local value = ""
if v then
if type(v) == "table" then
value = concat_table(v, ",")
else
value = v
end
end
logs_str = logs_str .. upper_str(k) .. ": " .. value .. "\n"
end
logs_str = logs_str .. upper_str(k) .. ": " .. value .. "\n"
end
local log_id = uuid()
local time = os.time()
local localtime = os.date("%Y-%m-%d %H:%M:%S", time)
local insertQuery = [[
INSERT INTO req_logs (
id, ip, ip_iso, ip_country_zh, ip_country_en,
ip_province_zh, ip_province_en, ip_longitude, ip_latitude,
time, localtime, server_name, website_key, host, method,
uri, user_agent, rule_type,match_rule, match_value,
localtime, server_name, website_key, host, method,
uri, user_agent, exec_rule, rule_type, match_rule, match_value,
nginx_log, blocking_time, action, is_block,is_attack
) VALUES (
:id, :real_ip, :iso, :country_zh, :country_en,
:province_zh, :province_en,:longitude, :latitude,
:time, :localtime, :server_name,:host, :website_key, :method,
:uri, :ua, :rule_type, :match_rule, :match_value,
DATETIME('now'), :server_name,:host, :website_key, :method,
:uri, :ua, :exec_rule, :rule_type, :match_rule, :match_value,
:logs_str, :blocking_time, :action, :is_block, :is_attack
)
]]
wafdb:execute([[BEGIN TRANSACTION]])
local stmt = wafdb:prepare(insertQuery)
stmt:bind_names {
id = log_id,
iso = iso,
@ -114,31 +122,48 @@ local function write_req_log(wafdb,attack)
province_en = province["en"],
longitude = longitude,
latitude = latitude,
time = time,
localtime = localtime,
host = host,
server_name = host,
website_key = website_key,
method = method,
uri = uri,
ua = ua,
rule_type = rule_type,
match_rule = rule,
exec_rule = exec_rule_type,
rule_type = match_rule_type,
match_rule = match_rule_detail,
match_value = "",
logs_str = logs_str,
blocking_time = blocking_time or 0,
action = action,
action = rule_action,
is_block = is_block,
is_attack = is_attack
}
local code = stmt:step()
stmt:finalize()
if code ~= 101 then
local errorMsg = wafdb:errmsg()
if errorMsg then
ngx.log(ngx.ERR, "insert attack_log error ", errorMsg .. " ")
local code2 = 101
if ngx.ctx.ip_blocked then
local insertBlockIp = [[
INSERT INTO block_ips (ip, is_block, blocking_time, req_log_id,create_date)
VALUES (:ip, :is_block, :blocking_time, :req_log_id, DATETIME('now'))
]]
stmt = wafdb:prepare(insertBlockIp)
stmt:bind_names {
ip=real_ip,
is_block = is_block,
blocking_time = blocking_time or 0,
req_log_id = log_id
}
code2 = stmt:step()
stmt:finalize()
end
wafdb:execute([[COMMIT]])
if code ~= 101 or code2 ~= 101 then
local error_msg = wafdb:errmsg()
if error_msg then
ngx.log(ngx.ERR, "insert attack_log error ", error_msg .. " ")
end
end
@ -176,7 +201,13 @@ local function count_not_found()
end
end
local function count_req_status(wafdb,is_attack)
local function count_req_status(is_attack)
local wafdb = utils.get_wafdb(config.waf_db_path)
if not wafdb then
ngx.log(ngx.ERR, "get log db failed")
return
end
local today = ngx.today()
local status = ngx.status
@ -184,7 +215,8 @@ local function count_req_status(wafdb,is_attack)
stmt_exist:bind_values(today)
stmt_exist:step()
local count = stmt_exist:get_uvalues()
stmt_exist:finalize()
local req_count_update = 1
local count_4xx_update = (status >= 400 and status < 500) and 1 or 0
local count_5xx_update = (status >= 500) and 1 or 0
@ -204,9 +236,9 @@ local function count_req_status(wafdb,is_attack)
end
if code ~= 101 then
local errorMsg = wafdb:errmsg()
if errorMsg then
ngx.log(ngx.ERR, "update waf_stat error ", errorMsg .. " ")
local error_msg = wafdb:errmsg()
if error_msg then
ngx.log(ngx.ERR, "update waf_stat error ", error_msg .. " ")
end
end
end
@ -217,17 +249,13 @@ if config.is_waf_on() then
if not ngx.ctx.ip then
ngx.ctx.ip = utils.get_real_ip()
ngx.ctx.geoip = utils.get_geo_ip(ngx.ctx.ip)
ngx.ctx.ip_location = utils.get_ip_location(ngx.ctx.ip)
local ua = utils.get_header("user-agent")
if not ua then
ua = ""
end
end
local wafdb = utils.get_wafdb(config.waf_db_path)
if wafdb ~= nil then
count_req_status(wafdb,is_attack)
write_req_log(wafdb,is_attack)
end
count_req_status(is_attack)
write_req_log(is_attack)
end

View file

@ -2,87 +2,144 @@
"rules": [
{
"state": "on",
"rule": "select.+(from|limit)"
"name": "sqlInject1",
"rule": "select.+(from|limit)",
"type": "sqlInject"
},
{
"state": "on",
"rule": "(?:(union(.*?)select))"
"name": "sqlInject2",
"rule": "(?:(union(.*?)select))",
"type": "sqlInject"
},
{
"state": "on",
"rule": "having|rongjitest"
"name": "sqlInject3",
"rule": "having|rongjitest",
"type": "sqlInject"
},
{
"state": "on",
"rule": "sleep\\((\\s*)(\\d*)(\\s*)\\)"
"name": "sqlInject4",
"rule": "sleep\\((\\s*)(\\d*)(\\s*)\\)",
"type": "sqlInject"
},
{
"state": "on",
"rule": "benchmark\\((.*)\\,(.*)\\)"
"name": "sqlInject5",
"rule": "benchmark\\((.*)\\,(.*)\\)",
"type": "sqlInject"
},
{
"state": "on",
"rule": "(?:from\\W+information_schema\\W)"
"name": "sqlInject6",
"rule": "group\\s+by.+\\(",
"type": "sqlInject"
},
{
"state": "on",
"rule": "(?:(?:current_)user|database|schema|connection_id)\\s*\\("
"name": "sqlInject7",
"rule": "(?:from\\W+information_schema\\W)",
"type": "sqlInject"
},
{
"state": "on",
"rule": "(?:etc\\/\\W*passwd)"
"name": "sqlInject8",
"rule": "(?:(?:current_)user|database|schema|connection_id)\\s*\\(",
"type": "sqlInject"
},
{
"state": "on",
"rule": "into(\\s+)+(?:dump|out)file\\s*"
"name": "sqlInject9",
"rule": "into(\\s+)+(?:dump|out)file\\s*",
"type": "sqlInject"
},
{
"state": "on",
"rule": "group\\s+by.+\\("
"name": "sqlInject10",
"rule": "\\s+(or|xor|and)\\s+.*(=|<|>|'|\")",
"type": "sqlInject"
},
{
"state": "on",
"rule": "xwork.MethodAccessor"
"name": "args1",
"rule": "xwork.MethodAccessor",
"type": "args",
"description": "Struts 恶意参数过滤"
},
{
"state": "on",
"rule": "(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\\("
"name": "args2",
"rule": "xwork\\.MethodAccessor",
"type": "args",
"description": "Struts 恶意参数过滤"
},
{
"state": "on",
"rule": "xwork\\.MethodAccessor"
"name": "oneWordTrojan1",
"rule": "(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\\(",
"type": "oneWordTrojan"
},
{
"state": "on",
"rule": "(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\\:\\/"
"name": "oneWordTrojan2",
"rule": "\\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\\[",
"type": "oneWordTrojan"
},
{
"state": "on",
"rule": "java\\.lang"
"name": "protocolFilter1",
"rule": "(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\\:\\/",
"type": "protocolFilter",
"description": "协议过滤"
},
{
"state": "on",
"rule": "\\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\\["
"name": "dirFilter1",
"rule": "(?:etc\\/\\W*passwd)",
"type": "dirFilter"
},
{
"state": "on",
"rule": "\\<(iframe|script|body|img|layer|div|meta|style|base|object|input)"
"name": "dirFilter2",
"rule": "java\\.lang",
"type": "dirFilter"
},
{
"state": "on",
"rule": "(onmouseover|onerror|onload)\\="
"name": "xss1",
"rule": "\\<(iframe|script|body|img|layer|div|meta|style|base|object|input)",
"type": "xss"
},
{
"state": "on",
"rule": "/shell?cd+/tmp;\\s*rm+-rf\\+\\*;\\s*wget"
"name": "xss2",
"rule": "(onmouseover|onerror|onload)\\=",
"type": "xss"
},
{
"state": "on",
"rule": "/systembc/password.php"
"name": "xss3",
"rule": "base64_decode\\(",
"type": "xss"
},
{
"state": "on",
"name": "webshell1",
"rule": "/shell?cd+/tmp;\\s*rm+-rf\\+\\*;\\s*wget",
"type": "webshell"
},
{
"state": "on",
"name": "phpExec1",
"rule": "/systembc/password.php",
"type": "phpExec"
},
{
"state":"on",
"rule":"(Acunetix-Aspect|Acunetix-Aspect-Password|Acunetix-Aspect-Queries|X-WIPP|X-RequestManager-Memo|X-Request-Memo|X-Scan-Memo)"
"name": "scannerFilter1",
"rule":"(Acunetix-Aspect|Acunetix-Aspect-Password|Acunetix-Aspect-Queries|X-WIPP|X-RequestManager-Memo|X-Request-Memo|X-Scan-Memo)",
"type": "scannerFilter"
}
]
}

View file

@ -2,87 +2,137 @@
"rules": [
{
"state": "on",
"rule": "\\.\\./"
"name": "dirFilter1",
"rule": "\\.\\./",
"type": "dirFilter"
},
{
"state": "on",
"rule": "\\:\\$"
"name": "dirFilter2",
"rule": "\\:\\$",
"type": "dirFilter"
},
{
"state": "on",
"rule": "\\$\\{"
"name": "dirFilter3",
"rule": "\\$\\{",
"type": "dirFilter"
},
{
"state": "on",
"rule": "select.+(from|limit)"
"name": "dirFilter4",
"rule": "(?:etc\\/\\W*passwd)",
"type": "dirFilter"
},
{
"state": "on",
"rule": "(?:(union(.*?)select))"
"name": "dirFilter5",
"rule": "java\\.lang",
"type": "dirFilter"
},
{
"state": "on",
"rule": "having|rongjitest"
"name": "sqlInject1",
"rule": "select.+(from|limit)",
"type": "sqlInject"
},
{
"state": "on",
"rule": "sleep\\((\\s*)(\\d*)(\\s*)\\)"
"name": "sqlInject2",
"rule": "(?:(union(.*?)select))",
"type": "sqlInject"
},
{
"state": "on",
"rule": "benchmark\\((.*)\\,(.*)\\)"
"name": "sqlInject3",
"rule": "having|rongjitest",
"type": "sqlInject"
},
{
"state": "on",
"rule": "base64_decode\\("
"name": "sqlInject4",
"rule": "sleep\\((\\s*)(\\d*)(\\s*)\\)",
"type": "sqlInject"
},
{
"state": "on",
"rule": "(?:from\\W+information_schema\\W)"
"name": "sqlInject5",
"rule": "benchmark\\((.*)\\,(.*)\\)",
"type": "sqlInject"
},
{
"state": "on",
"rule": "(?:(?:current_)user|database|schema|connection_id)\\s*\\("
"name": "sqlInject6",
"rule": "group\\s+by.+\\(",
"type": "sqlInject"
},
{
"state": "on",
"rule": "(?:etc\\/\\W*passwd)"
"name": "sqlInject7",
"rule": "(?:from\\W+information_schema\\W)",
"type": "sqlInject"
},
{
"state": "on",
"rule": "into(\\s+)+(?:dump|out)file\\s*"
"name": "sqlInject8",
"rule": "(?:(?:current_)user|database|schema|connection_id)\\s*\\(",
"type": "sqlInject"
},
{
"state": "on",
"rule": "group\\s+by.+\\("
"name": "sqlInject9",
"rule": "into(\\s+)+(?:dump|out)file\\s*",
"type": "sqlInject"
},
{
"state": "on",
"rule": "xwork.MethodAccessor"
"name": "sqlInject10",
"rule": "\\s+(or|xor|and)\\s+.*(=|<|>|'|\")",
"type": "sqlInject"
},
{
"state": "on",
"rule": "(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\\("
"name": "args1",
"rule": "xwork.MethodAccessor",
"type": "args",
"description": "Struts 恶意参数过滤"
},
{
"state": "on",
"rule": "xwork\\.MethodAccessor"
"name": "args2",
"rule": "xwork\\.MethodAccessor",
"type": "args",
"description": "Struts 恶意参数过滤"
},
{
"state": "on",
"rule": "(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\\:\\/"
"name": "oneWordTrojan1",
"rule": "(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\\(",
"type": "oneWordTrojan"
},
{
"state": "on",
"rule": "java\\.lang"
"name": "oneWordTrojan2",
"rule": "\\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\\[",
"type": "oneWordTrojan"
},
{
"state": "on",
"rule": "\\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\\["
"name": "protocolFilter1",
"rule": "(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\\:\\/",
"type": "protocolFilter"
},
{
"state":"on",
"rule":"(CustomCookie|acunetixCookie)"
"name":"scannerFilter1",
"rule":"(CustomCookie|acunetixCookie)",
"type": "scannerFilter"
},
{
"state": "on",
"name": "xss1",
"rule": "base64_decode\\(",
"type": "xss"
}
]
}

View file

@ -1,16 +1,10 @@
{
"nextId": 3,
"rules": [
{
"id": 1,
"state": "on",
"type": "defaultUABlack",
"action": "deny",
"name": "uaBlock1",
"rule": "HTTrack|Apache-HttpClient|harvest|audit|dirbuster|pangolin|nmap|sqln|hydra|Parser|libwww|BBBike|sqlmap|w3af|owasp|Nikto|fimap|havij|zmeu|BabyKrokodil|netsparker|httperf| SF/",
"ipBlock": "on",
"ipBlockTimeout": 600,
"code": 403,
"description": "一些不友好ua"
"type": "scannerFilter"
}
]
}

View file

@ -0,0 +1,82 @@
{
"rules": [
{
"state": "on",
"rule": "\\.(htaccess|mysql_history|bash_history|DS_Store|idea|user\\.ini)",
"name": "dirFilter1",
"type": "dirFilter"
},
{
"state": "on",
"rule": "\\.(bak|inc|old|mdb|sql|backup|java|class)$",
"name": "dirFilter2",
"type": "dirFilter"
},
{
"state": "on",
"rule": "^/(vhost|bbs|host|wwwroot|www|site|root|backup|data|ftp|db|admin|website|web).*\\.(rar|sql|zip|tar\\.gz|tar)$",
"name": "dirFilter3",
"type": "dirFilter"
},
{
"state": "on",
"rule": "java\\.lang",
"name": "dirFilter4",
"type": "dirFilter"
},
{
"state": "on",
"rule": "/(hack|shell|spy|phpspy)\\.php$",
"name": "phpExec1",
"type": "phpExec"
},
{
"state": "on",
"rule": "/(attachments|upimg|images|css|uploadfiles|html|uploads|templets|static|template|data|inc|forumdata|upload|includes|cache|avatar)/(\\\\w+).(php|jsp)",
"name": "phpExec2",
"type": "phpExec"
},
{
"state": "on",
"rule": "(?:phpMyAdmin2|phpMyAdmin|phpmyadmin|dbadmin|pma|myadmin|admin|mysql)/scripts/setup%.php",
"name": "phpExec3",
"type": "phpExec"
},
{
"state": "on",
"rule": "(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\\(",
"name": "oneWordTrojan1",
"type": "oneWordTrojan"
},
{
"state": "on",
"rule": "(phpmyadmin|jmx-console|jmxinvokerservlet)",
"name": "appFilter1",
"type": "appFilter"
},
{
"state": "on",
"rule": "wp-includes/wlwmanifest.xml",
"name": "appFilter2",
"type": "appFilter"
},
{
"state": "on",
"rule": "<php>die(@md5(HelloThinkCMF))</php>",
"name": "appFilter3",
"type": "appFilter"
},
{
"state": "on",
"rule": "/boaform/admin/formLogin",
"name": "appFilter4",
"type": "appFilter"
},
{
"state": "on",
"rule": "(?:(union(.*?)select))",
"name": "sqlInject1",
"type": "sqlInject"
}
]
}

View file

@ -1,7 +1,22 @@
{
"rules":[
{"state":"on","rule":"/TomcatBypass/Command/Base64"},
{"state":"on","rule":"j\\S*ndi\\S*:\\S*(?:dap|dns)\\S+"},
{"state":"on","rule":"(/acunetix-wvs-test-for-some-inexistent-file|netsparker|acunetix_wvs_security_test|AppScan|XSS@HERE)"}
"rules": [
{
"state": "on",
"name": "appFilter1",
"rule": "/TomcatBypass/Command/Base64",
"type": "appFilter"
},
{
"state": "on",
"name": "appFilter2",
"rule": "j\\S*ndi\\S*:\\S*(?:dap|dns)\\S+",
"type": "appFilter"
},
{
"state": "on",
"name": "scannerFilter1",
"rule": "(/acunetix-wvs-test-for-some-inexistent-file|netsparker|acunetix_wvs_security_test|AppScan|XSS@HERE)",
"type": "scannerFilter"
}
]
}

View file

@ -4,7 +4,23 @@
"name": "拦截IP",
"state": "on",
"type": "ipv4",
"ipv4": "123"
"ipv4": "123",
"description": "拦截IP"
},
{
"name": "拦截IP",
"state": "on",
"type": "ipv6",
"ipv6": "kjdhsakjdhsakjdhakshd",
"description": "拦截IP"
},
{
"name": "拦截IP",
"state": "on",
"type": "ipArr",
"ipStart": "192.168.1.1",
"ipEnd": "192.168.1.10",
"description": "拦截IP"
}
]
}

File diff suppressed because it is too large Load diff

View file

@ -2,87 +2,129 @@
"rules": [
{
"state": "on",
"rule": "GET"
"rule": "GET",
"name": "GET",
"type": "httpMethod"
},
{
"state": "on",
"rule": "POST"
"rule": "POST",
"name": "POST",
"type": "httpMethod"
},
{
"state": "on",
"rule": "PUT"
"rule": "PUT",
"name": "PUT",
"type": "httpMethod"
},
{
"state": "on",
"rule": "DELETE"
"rule": "DELETE",
"name": "DELETE",
"type": "httpMethod"
},
{
"state": "on",
"rule": "PATCH"
"rule": "PATCH",
"name": "PATCH",
"type": "httpMethod"
},
{
"state": "on",
"rule": "HEAD"
"rule": "HEAD",
"name": "HEAD",
"type": "httpMethod"
},
{
"state": "on",
"rule": "OPTIONS"
"rule": "OPTIONS",
"name": "OPTIONS",
"type": "httpMethod"
},
{
"state": "on",
"rule": "TRACE"
"rule": "TRACE",
"name": "TRACE",
"type": "httpMethod"
},
{
"state": "on",
"rule": "CONNECT"
"rule": "CONNECT",
"name": "CONNECT",
"type": "httpMethod"
},
{
"state": "on",
"rule": "PROPFIND"
"rule": "PROPFIND",
"name": "PROPFIND",
"type": "httpMethod"
},
{
"state": "on",
"rule": "PROPPATCH"
"rule": "PROPPATCH",
"name": "PROPPATCH",
"type": "httpMethod"
},
{
"state": "on",
"rule": "MKCOL"
"rule": "MKCOL",
"name": "MKCOL",
"type": "httpMethod"
},
{
"state": "on",
"rule": "COPY"
"rule": "COPY",
"name": "COPY",
"type": "httpMethod"
},
{
"state": "on",
"rule": "MOVE"
"rule": "MOVE",
"name": "MOVE",
"type": "httpMethod"
},
{
"state": "on",
"rule": "LOCK"
"rule": "LOCK",
"name": "LOCK",
"type": "httpMethod"
},
{
"state": "on",
"rule": "UNLOCK"
"rule": "UNLOCK",
"name": "UNLOCK",
"type": "httpMethod"
},
{
"state": "on",
"rule": "LINK"
"rule": "LINK",
"name": "LINK",
"type": "httpMethod"
},
{
"state": "on",
"rule": "UNLINK"
"rule": "UNLINK",
"name": "UNLINK",
"type": "httpMethod"
},
{
"state": "on",
"rule": "WRAPPED"
"rule": "WRAPPED",
"name": "WRAPPED",
"type": "httpMethod"
},
{
"state": "on",
"rule": "PROPFIND"
"rule": "PROPFIND",
"name": "PROPFIND",
"type": "httpMethod"
},
{
"state": "on",
"rule": "SRARCH"
"rule": "SRARCH",
"name": "SRARCH",
"type": "httpMethod"
}
]
}

View file

@ -1,23 +1,121 @@
{
"rules":[
{"state":"on","action":"deny","rule":"select.+(from|limit)"},
{"state":"on","action":"deny","rule":"(?:(union(.*?)select))"},
{"state":"on","action":"deny","rule":"having|rongjitest"},
{"state":"on","action":"deny","rule":"sleep\\((\\s*)(\\d*)(\\s*)\\)"},
{"state":"on","action":"deny","rule":"benchmark\\((.*)\\,(.*)\\)"},
{"state":"on","action":"deny","rule":"base64_decode\\("},
{"state":"on","action":"deny","rule":"(?:from\\W+information_schema\\W)"},
{"state":"on","action":"deny","rule":"(?:(?:current_)user|database|schema|connection_id)\\s*\\("},
{"state":"on","action":"deny","rule":"(?:etc\\/\\W*passwd)"},
{"state":"on","action":"deny","rule":"into(\\s+)+(?:dump|out)file\\s*"},
{"state":"on","action":"deny","rule":"group\\s+by.+\\("},
{"state":"on","action":"deny","rule":"xwork.MethodAccessor"},
{"state":"on","action":"deny","rule":"(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\\("},
{"state":"on","action":"deny","rule":"xwork\\.MethodAccessor"},
{"state":"on","action":"deny","rule":"(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\\:\\/"},
{"state":"on","action":"deny","rule":"java\\.lang"},
{"state":"on","action":"deny","rule":"\\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\\["},
{"state":"on","action":"deny","rule":"\\<(iframe|script|body|img|layer|div|meta|style|base|object|input)"},
{"state":"on","action":"deny","rule":"(onmouseover|onerror|onload)\\="}
"rules": [
{
"state": "on",
"name": "sqlInject1",
"rule": "select.+(from|limit)",
"type": "sqlInject"
},
{
"state": "on",
"name": "sqlInject2",
"rule": "(?:(union(.*?)select))",
"type": "sqlInject"
},
{
"state": "on",
"name": "sqlInject3",
"rule": "having|rongjitest",
"type": "sqlInject"
},
{
"state": "on",
"name": "sqlInject4",
"rule": "sleep\\((\\s*)(\\d*)(\\s*)\\)",
"type": "sqlInject"
},
{
"state": "on",
"name": "sqlInject5",
"rule": "benchmark\\((.*)\\,(.*)\\)",
"type": "sqlInject"
},
{
"state": "on",
"name": "sqlInject6",
"rule": "group\\s+by.+\\(",
"type": "sqlInject"
},
{
"state": "on",
"name": "sqlInject7",
"rule": "(?:from\\W+information_schema\\W)",
"type": "sqlInject"
},
{
"state": "on",
"name": "sqlInject8",
"rule": "(?:(?:current_)user|database|schema|connection_id)\\s*\\(",
"type": "sqlInject"
},
{
"state": "on",
"name": "sqlInject9",
"rule": "into(\\s+)+(?:dump|out)file\\s*",
"type": "sqlInject"
},
{
"state": "on",
"name": "args1",
"rule": "xwork.MethodAccessor",
"type": "args",
"description": "Struts 恶意参数过滤"
},
{
"state": "on",
"name": "args2",
"rule": "xwork\\.MethodAccessor",
"type": "args",
"description": "Struts 恶意参数过滤"
},
{
"state": "on",
"name": "oneWordTrojan1",
"rule": "(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\\(",
"type": "oneWordTrojan"
},
{
"state": "on",
"name": "protocolFilter1",
"rule": "(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\\:\\/",
"type": "protocolFilter",
"description": "协议过滤"
},
{
"state": "on",
"name": "oneWordTrojan2",
"rule": "\\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\\[",
"type": "oneWordTrojan"
},
{
"state": "on",
"name": "xss1",
"rule": "\\<(iframe|script|body|img|layer|div|meta|style|base|object|input)",
"type": "xss"
},
{
"state": "on",
"name": "xss2",
"rule": "(onmouseover|onerror|onload)\\=",
"type": "xss"
},
{
"state": "on",
"name": "xss3",
"rule": "base64_decode\\(",
"type": "xss"
},
{
"state": "on",
"name": "dirFilter1",
"rule": "(?:etc\\/\\W*passwd)",
"type": "dirFilter"
},
{
"state": "on",
"name": "dirFilter2",
"rule": "java\\.lang",
"type": "dirFilter"
}
]
}

View file

@ -1,5 +1,11 @@
{
"rules": [
{
"name": "UaBlack",
"state": "on",
"action": "deny",
"rule": "ua-blacklist",
"description": "测试"
}
]
}

View file

@ -1,8 +1,3 @@
{
"rules": [
{
"state": "on",
"rule": "PostmanRuntime/7.36.1"
}
]
"rules": []
}

View file

@ -1,44 +1,3 @@
{
"rules": [
{
"state": "on",
"rule": "\\.(svn|htaccess|bash_history)"
},
{
"state": "on",
"rule": "\\.(bak|inc|old|mdb|sql|backup|java|class)$"
},
{
"state": "on",
"rule": "(vhost|bbs|host|wwwroot|www|site|root|hytop|flashfxp).*\\.rar"
},
{
"state": "on",
"rule": "(phpmyadmin|jmx-console|jmxinvokerservlet)"
},
{
"state": "on",
"rule": "(?:phpMyAdmin2|phpMyAdmin|phpmyadmin|dbadmin|pma|myadmin|admin|mysql)/scripts/setup%.php"
},
{
"state": "on",
"rule": "java\\.lang"
},
{
"state": "on",
"rule": "/(attachments|upimg|images|css|uploadfiles|html|uploads|templets|static|template|data|inc|forumdata|upload|includes|cache|avatar)/(\\\\w+).(php|jsp)"
},
{
"state": "on",
"rule": "wp-includes/wlwmanifest.xml"
},
{
"state": "on",
"rule": "<php>die(@md5(HelloThinkCMF))</php>"
},
{
"state": "on",
"rule": "/boaform/admin/formLogin"
}
]
"rules": []
}

View file

@ -1,14 +1,3 @@
{
"rules": [
{
"state": "on",
"action": "allow",
"rule": "/console/posts/editor"
},
{
"state": "on",
"action": "allow",
"rule": "/apis/api.console.halo.run/v1alpha1/posts"
}
]
"rules": []
}

View file

@ -53,8 +53,7 @@ local function init()
end
ngx.ctx.ua = ua
ngx.ctx.geoip = utils.get_geo_ip(ip)
ngx.ctx.ip_location = utils.get_ip_location(ip)
ngx.ctx.website_key = get_website_key()
ngx.ctx.method = ngx.req.get_method()
ngx.ctx.content_type = utils.get_header("content-type")
@ -132,26 +131,27 @@ if config.is_waf_on() then
if lib.is_white_ip() then
return true
end
lib.default_ip_black()
lib.black_ip()
lib.default_ip_black()
if lib.is_white_ua() then
return true
end
lib.default_ua_black()
lib.black_ua()
lib.default_ua_black()
lib.cc_url()
if lib.is_white_url() then
return true
end
lib.black_url()
lib.default_url_black()
lib.allow_location_check()
lib.acl()
lib.bot_check()
lib.method_check()
lib.acl()
lib.cc()
lib.bot_check()
lib.args_check()
lib.cookie_check()
lib.post_check()