From 7f2f7fa195e4abf9eda5239046455e81c6fd0322 Mon Sep 17 00:00:00 2001 From: zhengkunwang <31820853+zhengkunwang223@users.noreply.github.com> Date: Mon, 18 Mar 2024 21:16:10 +0800 Subject: [PATCH] =?UTF-8?q?feat(waf):=20=E4=BC=98=E5=8C=96=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=9B=B4=E6=96=B0=E6=8E=A5=E5=8F=A3=20(#4226)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/openresty/waf/conf/token | 0 plugins/openresty/waf/config.lua | 53 +++++++++++++---------- plugins/openresty/waf/lib/action.lua | 31 +++++++------ plugins/openresty/waf/lib/file.lua | 8 ++-- plugins/openresty/waf/log_and_traffic.lua | 3 ++ plugins/openresty/waf/waf.lua | 12 +++-- 6 files changed, 66 insertions(+), 41 deletions(-) create mode 100644 plugins/openresty/waf/conf/token diff --git a/plugins/openresty/waf/conf/token b/plugins/openresty/waf/conf/token new file mode 100644 index 000000000..e69de29bb diff --git a/plugins/openresty/waf/config.lua b/plugins/openresty/waf/config.lua index 5ec0b4a0c..38a716954 100644 --- a/plugins/openresty/waf/config.lua +++ b/plugins/openresty/waf/config.lua @@ -5,7 +5,7 @@ local utils = require "utils" local read_rule = file_utils.read_rule local read_file2string = file_utils.read_file2string local read_file2table = file_utils.read_file2table -local set_content_to_json_file = file_utils.set_content_to_json_file +local set_content_to_file = file_utils.set_content_to_file local list_dir = lfs.dir local attributes = lfs.attributes local match_str = string.match @@ -68,21 +68,16 @@ local function ini_waf_info() end end + + local function init_global_config() local global_config_file = config_dir .. 'global.json' global_config = file_utils.read_file2table(global_config_file) - local token = utils.random_string(20) - global_config["waf"]["token"] = token - - local waf_dict = ngx.shared.waf - waf_dict:set("token", token, 7200) - - set_content_to_json_file(global_config,global_config_file) config.global_config = global_config - config.isProtectionMode = global_config["mode"] == "protection" and true or false - + _M.get_token() + local rules = {} rules.uaBlack = read_rule(global_rule_dir, "uaBlack") rules.uaWhite = read_rule(global_rule_dir, "uaWhite") @@ -114,6 +109,21 @@ local function init_global_config() _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 + + + local waf_dict = ngx.shared.waf + waf_dict:set("config", config) +end + +local function get_config() + local waf_dict = ngx.shared.waf + local config_table = waf_dict:get("config") + if config_table == nil then + init_global_config() + return config + end + config = config_table + return config_table end function _M.load_config_file() @@ -123,35 +133,35 @@ function _M.load_config_file() end function _M.get_site_config(website_key) - return config.site_config[website_key] + return get_config().site_config[website_key] end function _M.get_site_rules(website_key) - return config.site_rules[website_key] + return get_config().site_rules[website_key] end function _M.get_global_config(name) - return config.global_config[name] + return get_config().global_config[name] end function _M.get_global_rules(name) - return config.global_rules[name] + return get_config().global_rules[name] end function _M.is_global_state_on(name) - return config.global_config[name]["state"] == "on" and true or false + return get_config().global_config[name]["state"] == "on" and true or false end function _M.is_site_state_on(name) - return config.site_config[name]["state"] == "on" and true or false + return get_config().site_config[name]["state"] == "on" and true or false end function _M.get_redis_config() - return config.global_config["redis"] + return get_config().global_config["redis"] end function _M.get_html_res(name) - return config.html_res[name] + return get_config().html_res[name] end function _M.is_waf_on() @@ -163,7 +173,7 @@ function _M.is_redis_on() end function _M.get_secret() - return config.global_config["waf"]["secret"] + return get_config().global_config["waf"]["secret"] end function _M.get_token() @@ -172,9 +182,8 @@ function _M.get_token() if not token then token = utils.random_string(20) waf_dict:set("token", token, 86400) - global_config["waf"]["token"] = token - local global_config_file = config_dir .. 'global.json' - set_content_to_json_file(global_config,global_config_file) + local token_path = config_dir .. 'token' + set_content_to_file(token,token_path) end return token end diff --git a/plugins/openresty/waf/lib/action.lua b/plugins/openresty/waf/lib/action.lua index 76b99c4c3..5d34fe998 100644 --- a/plugins/openresty/waf/lib/action.lua +++ b/plugins/openresty/waf/lib/action.lua @@ -5,11 +5,12 @@ local format_str = string.format local _M = {} local function deny(status_code, res) - if not status_code then + if status_code == nil then status_code = 403 end + ngx.status = status_code - if res then + if res ~= nil and res ~= "" then ngx.header.content_type = "text/html; charset=UTF-8" ngx.say(config.get_html_res(res)) end @@ -143,21 +144,25 @@ function _M.exec_action(rule_config, match_rule, data) attack_count(rule_config.type) - --local msg = "访问 IP " .. ngx.ctx.ip .. " 访问 URL" .. ngx.var.uri .. " 触发动作 " .. action .. " 规则类型 " .. rule_config.type - --if match_rule then - -- if match_rule.type then - -- msg = msg .. " 触发规则类型 " .. match_rule.type - -- else - -- msg = msg .. " 触发规则 " .. match_rule.rule - -- end - --end - -- - --ngx.log(ngx.ERR, msg) + local msg = "访问 IP " .. ngx.ctx.ip .. " 访问 URL" .. ngx.var.uri .. " 触发动作 " .. action .. " 规则类型 " .. rule_config.type + if match_rule then + if match_rule.type then + msg = msg .. " 触发规则类型 " .. match_rule.type + else + msg = msg .. " 触发规则 " .. match_rule.rule + end + end + + ngx.log(ngx.ERR, msg) if action == "allow" then return elseif action == "deny" then - deny(rule_config.code, rule_config.res) + if rule_config.code and rule_config.res then + deny(rule_config.code, rule_config.res) + else + ngx.exit(403) + end elseif action == "slide" then slide() diff --git a/plugins/openresty/waf/lib/file.lua b/plugins/openresty/waf/lib/file.lua index ecda723a0..736926e74 100644 --- a/plugins/openresty/waf/lib/file.lua +++ b/plugins/openresty/waf/lib/file.lua @@ -59,11 +59,13 @@ function _M.read_file2table(file_path) return decode(str) end -function _M.set_content_to_json_file(data, file_path) - local json_str = cjson.encode(data) +function _M.set_content_to_file(data, file_path) + if data == nil or file_path == nil then + return + end local file = open_file(file_path, "w") if file then - file:write(json_str) + file:write(data) file:close() end end diff --git a/plugins/openresty/waf/log_and_traffic.lua b/plugins/openresty/waf/log_and_traffic.lua index 6949c9431..556876db9 100644 --- a/plugins/openresty/waf/log_and_traffic.lua +++ b/plugins/openresty/waf/log_and_traffic.lua @@ -222,6 +222,9 @@ local function count_req_status(is_attack) end if config.is_waf_on() then + if ngx.ctx.is_waf_url then + return + end count_not_found() local is_attack = ngx.ctx.is_attack diff --git a/plugins/openresty/waf/waf.lua b/plugins/openresty/waf/waf.lua index 40c480450..b83f79772 100644 --- a/plugins/openresty/waf/waf.lua +++ b/plugins/openresty/waf/waf.lua @@ -97,10 +97,12 @@ local function waf_api() end end if uri == "/slide_check_" .. ngx.md5(ngx.ctx.ip) .. ".js" then + ngx.ctx.is_waf_url = true return_js("slide_js") end if uri == "/5s_check_" .. ngx.md5(ngx.ctx.ip) .. ".js" then + ngx.ctx.is_waf_url = true return_js("five_second_js") end local method = ngx.req.get_method() @@ -115,16 +117,21 @@ local function waf_api() if not body_data then return false end + ngx.log(ngx.ERR,"1111") local args if body_data then args = cjson.decode(body_data) end + ngx.log(ngx.ERR,"2222") if args == nil or args.token == nil then return false end + ngx.log(ngx.ERR,"token",args.token) + ngx.log(ngx.ERR,"config token",config.get_token()) if args.token ~= config.get_token() then return false end + ngx.ctx.is_waf_url = true if uri == '/reload_waf_config' then config.load_config_file() ngx.exit(200) @@ -158,7 +165,7 @@ if config.is_waf_on() then lib.black_ua() lib.default_ua_black() - lib.cc_url() + --lib.cc_url() if lib.is_white_url() then return true end @@ -169,10 +176,9 @@ if config.is_waf_on() then lib.method_check() lib.acl() lib.cc() - lib.bot_check() + --lib.bot_check() lib.args_check() lib.cookie_check() lib.post_check() lib.header_check() - end \ No newline at end of file