mdserver-web/plugins/op_waf/waf/lua/init.lua

749 lines
22 KiB
Lua
Raw Permalink Normal View History

2022-10-20 13:33:35 -04:00
2019-04-26 03:58:58 -04:00
local json = require "cjson"
2019-04-26 11:47:48 -04:00
local ngx_match = ngx.re.find
2019-04-26 03:12:57 -04:00
2023-02-10 16:28:54 -05:00
local __WAF = require "waf_common"
2022-10-20 13:25:57 -04:00
2022-10-20 13:33:35 -04:00
-- print(json.encode(__C))
2022-10-21 00:08:43 -04:00
local C = __WAF:getInstance()
2022-10-09 09:29:40 -04:00
2022-10-20 11:40:28 -04:00
local config = require "waf_config"
local site_config = require "waf_site"
local config_domains = require "waf_domains"
2022-10-13 09:29:28 -04:00
2019-04-27 04:44:46 -04:00
C:setConfData(config, site_config)
2022-10-11 03:22:28 -04:00
C:setDebug(true)
2022-08-13 10:30:30 -04:00
-- C:D("config:"..C:to_json(config))
2022-10-09 09:29:40 -04:00
2022-10-13 09:29:28 -04:00
local get_html = require "html_get"
local post_html = require "html_post"
2022-10-22 01:19:35 -04:00
local other_html = require "html_other"
2022-10-13 09:29:28 -04:00
local user_agent_html = require "html_user_agent"
local cc_safe_js_html = require "html_safe_js"
2022-10-24 08:56:18 -04:00
local cookie_html = require "html_cookie"
2022-10-13 09:03:26 -04:00
2022-10-13 09:05:06 -04:00
local args_rules = require "rule_args"
local ip_white_rules = require "rule_ip_white"
local ip_black_rules = require "rule_ip_black"
local ipv6_black_rules = require "rule_ipv6_black"
local scan_black_rules = require "rule_scan_black"
local user_agent_rules = require "rule_user_agent"
local post_rules = require "rule_post"
local cookie_rules = require "rule_cookie"
2022-10-22 08:25:46 -04:00
local url_rules = require "rule_url"
2022-10-24 11:12:45 -04:00
local url_white_rules = require "rule_url_white"
2022-10-09 09:29:40 -04:00
2023-08-15 14:53:29 -04:00
local waf_area_limit = require "waf_area_limit"
2023-02-11 04:45:17 -05:00
-- local server_name = string.gsub(C:get_sn(config_domains),'_','.')
local server_name = C:get_sn(config_domains)
2022-10-12 01:49:57 -04:00
local function initParams()
2019-04-27 04:44:46 -04:00
local data = {}
2022-10-10 23:41:32 -04:00
data['server_name'] = server_name
2022-10-11 03:22:28 -04:00
data['ip'] = C:get_real_ip(server_name)
data['ipn'] = C:arrip(data['ip'])
2019-04-27 04:44:46 -04:00
data['request_header'] = ngx.req.get_headers()
2022-10-24 08:38:24 -04:00
data['uri'] = tostring(ngx.unescape_uri(ngx.var.uri))
2019-04-27 04:44:46 -04:00
data['uri_request_args'] = ngx.req.get_uri_args()
2019-05-06 01:11:00 -04:00
data['method'] = ngx.req.get_method()
2022-10-24 08:39:07 -04:00
data['request_uri'] = tostring(ngx.var.request_uri)
2022-10-20 11:40:28 -04:00
data['status_code'] = ngx.status
2022-10-21 05:34:38 -04:00
data['user_agent'] = data['request_header']['user-agent']
2022-10-09 09:29:40 -04:00
data['cookie'] = ngx.var.http_cookie
2022-10-20 11:40:28 -04:00
data['time'] = ngx.time()
2023-08-11 00:56:07 -04:00
2019-04-27 04:44:46 -04:00
return data
end
2019-04-26 06:03:12 -04:00
2019-04-27 04:44:46 -04:00
local params = initParams()
2023-08-11 00:56:07 -04:00
-- C:D(C:to_json(params))
2019-04-27 04:44:46 -04:00
C:setParams(params)
2019-04-27 05:54:09 -04:00
2022-10-14 00:41:32 -04:00
local cpu_percent = ngx.shared.waf_limit:get("cpu_usage")
2022-10-20 11:40:28 -04:00
if not cpu_percent then
cpu_percent = 0
end
2022-10-12 01:49:57 -04:00
local function get_return_state(rstate,rmsg)
2019-05-06 02:35:15 -04:00
result = {}
result['status'] = rstate
result['msg'] = rmsg
return result
end
2022-10-14 09:41:25 -04:00
local function get_waf_drop_ip()
2022-10-22 01:19:35 -04:00
local data = ngx.shared.waf_drop_ip:get_keys(0)
2019-05-06 02:35:15 -04:00
return data
end
2022-10-15 07:13:01 -04:00
local function return_json(status,msg)
ngx.header.content_type = "application/json"
result = {}
result['status'] = status
result['msg'] = msg
ngx.say(json.encode(data))
ngx.exit(200)
end
2022-10-12 01:49:57 -04:00
local function is_chekc_table(data,strings)
2019-05-06 02:35:15 -04:00
if type(data) ~= 'table' then return 1 end
if not data then return 1 end
2022-10-12 05:18:51 -04:00
data = chekc_ip_timeout(data)
2019-05-06 02:35:15 -04:00
for k,v in pairs(data)
do
2022-10-13 09:29:28 -04:00
if strings == v['ip'] then
2019-05-06 02:35:15 -04:00
return 3
end
end
return 2
end
2022-10-22 09:36:12 -04:00
local function remove_waf_drop_ip()
ngx.header.content_type = "application/json"
local ip = params['uri_request_args']['ip']
if not ip or not C:is_ipaddr(ip) then
local data = get_return_state(-1, "格式错误")
ngx.say(json.encode(data))
ngx.exit(200)
return true
2019-05-06 02:35:15 -04:00
end
2022-10-22 09:36:12 -04:00
local sign = "remove_waf_drop_ip"
if C:is_working(sign) then
local data = get_return_state(-1, "fail")
ngx.say(json.encode(data))
ngx.exit(200)
return true
2019-05-06 02:35:15 -04:00
end
2022-10-22 09:36:12 -04:00
C:lock_working(sign)
ngx.shared.waf_drop_ip:delete(ip)
C:unlock_working(sign)
local data = get_return_state(0, "ok")
ngx.say(json.encode(data))
ngx.exit(200)
2019-05-06 02:35:15 -04:00
end
2022-10-14 05:50:26 -04:00
local function clean_waf_drop_ip()
2022-10-22 09:36:12 -04:00
ngx.header.content_type = "application/json"
local sign = "clean_waf_drop_ip"
if C:is_working(sign) then
local data = get_return_state(-1, "fail")
ngx.say(json.encode(data))
ngx.exit(200)
return true
2019-05-06 02:35:15 -04:00
end
2022-10-22 09:36:12 -04:00
C:lock_working(sign)
ngx.shared.waf_drop_ip:flush_all()
C:unlock_working(sign)
local data = get_return_state(0, "ok")
ngx.say(json.encode(data))
ngx.exit(200)
2019-05-06 02:35:15 -04:00
end
2022-10-12 01:49:57 -04:00
local function min_route()
2022-10-10 01:01:27 -04:00
if ngx.var.remote_addr ~= '127.0.0.1' then return false end
2022-10-22 09:36:12 -04:00
local uri = params['uri']
2022-10-14 05:50:26 -04:00
if uri == '/get_waf_drop_ip' then
2022-10-22 09:36:12 -04:00
ngx.header.content_type = "application/json"
local data = get_return_state(0, get_waf_drop_ip())
ngx.say(json.encode(data))
ngx.exit(200)
2022-10-14 05:50:26 -04:00
elseif uri == '/remove_waf_drop_ip' then
2022-10-22 09:36:12 -04:00
remove_waf_drop_ip()
elseif uri == '/clean_waf_drop_ip' then
clean_waf_drop_ip()
2019-05-06 02:35:15 -04:00
end
end
2019-04-26 21:30:52 -04:00
2022-10-12 01:49:57 -04:00
local function waf_get_args()
2019-04-27 01:02:21 -04:00
if not config['get']['open'] or not C:is_site_config('get') then return false end
2022-10-22 01:19:35 -04:00
-- C:D("waf_get_args:"..C:to_json(args_rules)..":"..json.encode(params['uri_request_args']))
2022-10-13 10:18:57 -04:00
if C:ngx_match_list(args_rules, params['uri_request_args']) then
2019-04-27 04:44:46 -04:00
C:write_log('args','regular')
C:return_html(config['get']['status'], get_html)
2019-04-26 06:03:12 -04:00
return true
end
return false
end
2019-04-22 09:21:49 -04:00
2019-04-27 05:54:09 -04:00
2022-10-12 01:49:57 -04:00
local function waf_ip_white()
2019-04-27 05:54:09 -04:00
for _,rule in ipairs(ip_white_rules)
do
if C:compare_ip(rule) then
return true
end
end
return false
end
2022-10-24 11:12:45 -04:00
local function waf_url_white()
if C:ngx_match_list(url_white_rules, params['uri']) then
return true
end
return false
end
2022-10-12 01:49:57 -04:00
local function waf_ip_black()
2022-10-11 04:35:44 -04:00
-- ipv4 ip black
2019-04-27 05:54:09 -04:00
for _,rule in ipairs(ip_black_rules)
do
if C:compare_ip(rule) then
ngx.exit(config['cc']['status'])
return true
end
end
2022-10-11 04:35:44 -04:00
-- ipv6 ip black
for _,rule in ipairs(ipv6_black_rules)
do
if rule == params['ip'] then
ngx.exit(config['cc']['status'])
return true
end
end
2019-04-27 05:54:09 -04:00
return false
end
2022-10-12 01:49:57 -04:00
local function waf_user_agent()
2022-10-09 09:29:40 -04:00
-- user_agent 过滤
2022-10-22 01:19:35 -04:00
-- if not config['user-agent']['open'] or not C:is_site_config('user-agent') then return false end
-- C:D("waf_user_agent;user_agent_rules:"..json.encode(user_agent_rules)..",ua:"..tostring(params['request_header']['user-agent']))
2022-10-24 02:49:20 -04:00
if C:ngx_match_list(user_agent_rules, params['request_header']['user-agent']) then
2022-10-22 01:19:35 -04:00
-- C:D("waf_user_agent........... true")
2019-04-27 05:54:09 -04:00
C:write_log('user_agent','regular')
2022-10-22 01:19:35 -04:00
C:return_html(config['user-agent']['status'], user_agent_html)
2019-04-27 05:54:09 -04:00
return true
end
2022-10-22 01:19:35 -04:00
-- C:D("waf_user_agent........... false")
2019-04-27 05:54:09 -04:00
return false
end
2022-10-10 00:13:45 -04:00
2022-10-22 01:19:35 -04:00
local function waf_drop_ip()
2022-10-15 05:38:42 -04:00
local ip = params['ip']
local count = ngx.shared.waf_drop_ip:get(ip)
2022-10-10 00:13:45 -04:00
if not count then return false end
2022-10-15 05:38:42 -04:00
2022-10-22 01:19:35 -04:00
local retry = config['retry']['retry']
-- C:D("waf_drop;count:"..tostring(count)..",retry:"..tostring(retry))
-- C:D("waf_drop;count > retry:"..tostring(count > retry))
if count > retry then
-- C:D("waf_drop_ip........... true")
2022-10-10 00:13:45 -04:00
ngx.exit(config['cc']['status'])
return true
end
2022-10-22 01:19:35 -04:00
-- C:D("waf_drop_ip........... false")
2022-10-10 00:13:45 -04:00
return false
end
2022-10-12 01:49:57 -04:00
local function waf_cc()
2023-01-08 00:49:42 -05:00
if not config['cc']['open'] then return false end
if not C:is_site_config('cc') then return false end
2022-10-09 14:14:31 -04:00
2022-10-22 01:19:35 -04:00
local ip = params['ip']
2022-10-09 14:14:31 -04:00
2022-10-22 01:19:35 -04:00
-- 多次cc才封禁。
-- local ip_lock = ngx.shared.waf_drop_ip:get(ip)
-- if ip_lock then
-- if ip_lock > 0 then
-- ngx.exit(config['cc']['status'])
-- return true
-- end
-- end
2022-10-10 00:13:45 -04:00
local request_uri = params['request_uri']
2022-07-30 11:47:54 -04:00
local token = ngx.md5(ip .. '_' .. request_uri)
2022-10-14 00:41:32 -04:00
local count = ngx.shared.waf_limit:get(token)
2022-10-09 14:14:31 -04:00
2022-10-14 05:50:26 -04:00
local endtime = config['cc']['endtime']
local waf_limit = config['cc']['limit']
2022-10-09 14:14:31 -04:00
local cycle = config['cc']['cycle']
2022-10-14 14:05:29 -04:00
2022-07-30 11:47:54 -04:00
if count then
2022-10-14 00:41:32 -04:00
if count > waf_limit then
2022-10-09 14:14:31 -04:00
2022-10-14 00:41:32 -04:00
local safe_count, _ = ngx.shared.waf_drop_sum:get(ip)
2022-07-30 11:47:54 -04:00
if not safe_count then
2022-10-14 11:45:43 -04:00
ngx.shared.waf_drop_sum:set(ip, 1, 86400)
2022-07-30 11:47:54 -04:00
safe_count = 1
else
2022-10-14 11:45:43 -04:00
ngx.shared.waf_drop_sum:incr(ip, 1)
2022-07-30 11:47:54 -04:00
end
local lock_time = (endtime * safe_count)
if lock_time > 86400 then lock_time = 86400 end
2022-10-09 14:14:31 -04:00
2022-10-14 12:34:14 -04:00
ngx.shared.waf_drop_ip:set(ip, 1, lock_time)
2022-10-22 01:19:35 -04:00
local reason = cycle..'秒内累计超过'..waf_limit..'次请求,封锁' .. lock_time .. ''
C:write_log('cc', reason)
C:log(params, 'cc',reason)
2022-08-02 06:00:24 -04:00
ngx.exit(config['cc']['status'])
return true
else
2022-10-14 12:34:14 -04:00
ngx.shared.waf_limit:incr(token, 1)
2022-08-01 01:32:14 -04:00
end
2022-08-02 06:00:24 -04:00
else
2022-10-14 12:34:14 -04:00
ngx.shared.waf_drop_sum:set(ip, 1, 86400)
2022-10-14 00:41:32 -04:00
ngx.shared.waf_limit:set(token, 1, cycle)
2022-08-02 06:00:24 -04:00
end
2022-10-10 00:13:45 -04:00
return false
2022-08-02 06:00:24 -04:00
end
2019-04-27 05:54:09 -04:00
2022-10-11 12:38:23 -04:00
-- 是否符合开强制验证条件
2022-10-12 01:49:57 -04:00
local function is_open_waf_cc_increase()
2022-10-11 12:38:23 -04:00
if config['safe_verify']['open'] then
return true
end
2022-10-24 07:11:48 -04:00
-- C:D("waf config:"..json.encode(config))
if config['safe_verify']['auto'] then
if cpu_percent >= config['safe_verify']['cpu'] then
2022-10-23 01:49:08 -04:00
return true
end
if site_config[server_name] and site_config[server_name]['safe_verify']['open'] then
if cpu_percent >= site_config[server_name]['safe_verify']['cpu'] then
return true
end
end
2022-10-12 01:49:57 -04:00
end
2022-10-11 12:38:23 -04:00
return false
end
2019-04-27 05:54:09 -04:00
--强制验证是否使用正常浏览器访问网站
2022-10-12 01:49:57 -04:00
local function waf_cc_increase()
if not is_open_waf_cc_increase() then return false end
2022-10-11 12:38:23 -04:00
local ip = params['ip']
local uri = params['uri']
2019-04-27 05:54:09 -04:00
local cache_token = ngx.md5(ip .. '_' .. server_name)
2022-10-11 12:38:23 -04:00
2019-04-27 05:54:09 -04:00
--判断是否已经通过验证
2022-10-14 00:41:32 -04:00
if ngx.shared.waf_limit:get(cache_token) then return false end
2022-10-11 12:38:23 -04:00
local cache_rand_key = ip..':rand'
2022-10-14 00:41:32 -04:00
local cache_rand = ngx.shared.waf_limit:get(cache_rand_key)
2022-10-11 12:38:23 -04:00
if not cache_rand then
2022-10-13 23:36:54 -04:00
cache_rand = C:get_random(8)
2022-10-14 00:41:32 -04:00
ngx.shared.waf_limit:set(cache_rand_key,cache_rand,30)
2022-10-11 12:38:23 -04:00
end
2022-10-14 15:16:02 -04:00
local make_token = "waf_unbind_"..cache_rand.."_"..cache_token
local make_uri_str = "?token="..make_token
local make_uri = "/"..make_uri_str
2022-10-12 02:51:46 -04:00
2023-08-11 00:56:07 -04:00
-- C:D("token:"..tostring(params['uri_request_args']['token']))
2022-10-12 02:51:46 -04:00
if params['uri_request_args']['token'] then
2023-03-05 05:03:41 -05:00
ngx.header.content_type = "application/json"
2022-10-12 02:51:46 -04:00
local args_token = params['uri_request_args']['token']
if args_token == make_token then
2023-03-05 04:37:01 -05:00
ngx.shared.waf_limit:set(cache_token, 1, tonumber(config['safe_verify']['time']))
2022-10-15 07:13:01 -04:00
local data = get_return_state(0, "ok")
ngx.say(json.encode(data))
ngx.exit(200)
2022-10-12 02:51:46 -04:00
end
2023-08-11 00:56:07 -04:00
local data = get_return_state(0, "unset")
ngx.say(json.encode(data))
ngx.exit(200)
2022-10-12 02:51:46 -04:00
end
2022-10-11 12:38:23 -04:00
2023-08-11 05:15:47 -04:00
if not config['safe_verify']['mode'] then return false end
2023-08-11 08:05:04 -04:00
-- C:D(C:to_json(params['uri_request_args']))
2023-08-11 05:15:47 -04:00
if config['safe_verify']['mode'] == 'url' then
2023-08-11 08:05:04 -04:00
local page = 'safe_verify_'..cache_token
local request_uri = params['request_uri']
local to_url = '/?'..page..'&f='..request_uri
2023-08-11 05:15:47 -04:00
local cache_url_key = cache_token..':url'
local cache_url_val = ngx.shared.waf_limit:get(cache_url_key)
2023-08-11 08:05:04 -04:00
if params['uri_request_args'][page] then
2023-08-11 05:15:47 -04:00
local cc_html = ngx.re.gsub(cc_safe_js_html, "{uri}", make_uri_str)
return C:return_html(200, cc_html)
end
if not cache_url_val then
ngx.shared.waf_limit:set(cache_url_key, request_uri,30)
return ngx.redirect(to_url)
end
end
if config['safe_verify']['mode'] == 'local' then
local cc_html = ngx.re.gsub(cc_safe_js_html, "{uri}", make_uri_str)
C:return_html(200, cc_html)
end
2019-04-27 05:54:09 -04:00
end
2022-10-12 01:49:57 -04:00
local function waf_url()
2019-04-27 05:54:09 -04:00
if not config['get']['open'] or not C:is_site_config('get') then return false end
--正则--
2022-10-22 08:25:46 -04:00
-- C:D("waf_url:"..json.encode(url_rules)..":uri:"..params["uri"])
if C:ngx_match_list(url_rules, params["uri"]) then
2019-04-27 05:54:09 -04:00
C:write_log('url','regular')
2022-10-16 12:44:04 -04:00
C:return_html(config['get']['status'], get_html)
2019-04-27 05:54:09 -04:00
return true
end
return false
end
2022-10-12 01:49:57 -04:00
local function waf_scan_black()
2022-10-09 09:29:40 -04:00
-- 扫描软件禁止
2019-04-27 05:54:09 -04:00
if not config['scan']['open'] or not C:is_site_config('scan') then return false end
2022-10-09 09:29:40 -04:00
if not params["cookie"] then
if C:ngx_match_string(scan_black_rules['cookie'], tostring(params["cookie"]),'scan') then
C:write_log('scan','regular')
ngx.exit(config['scan']['status'])
return true
end
2019-04-27 05:54:09 -04:00
end
2022-10-09 09:29:40 -04:00
if C:ngx_match_string(scan_black_rules['args'], params["request_uri"], 'scan') then
2019-04-27 05:54:09 -04:00
C:write_log('scan','regular')
ngx.exit(config['scan']['status'])
return true
end
2022-10-09 09:29:40 -04:00
2019-04-27 08:21:26 -04:00
for key,value in pairs(params["request_header"])
2019-04-27 05:54:09 -04:00
do
2022-10-09 09:29:40 -04:00
if C:ngx_match_string(scan_black_rules['header'], key, 'scan') then
2019-04-27 05:54:09 -04:00
C:write_log('scan','regular')
ngx.exit(config['scan']['status'])
return true
end
end
return false
end
2022-10-12 01:49:57 -04:00
local function waf_post()
2019-04-27 08:21:26 -04:00
if not config['post']['open'] or not C:is_site_config('post') then return false end
2019-05-06 01:11:00 -04:00
if params['method'] ~= "POST" then return false end
2022-10-22 01:19:35 -04:00
local content_length = tonumber(params["request_header"]['content-length'])
local max_len = 640 * 1020000
2019-04-27 05:54:09 -04:00
if content_length > max_len then return false end
2019-05-06 01:27:01 -04:00
if C:get_boundary() then return false end
2019-04-27 05:54:09 -04:00
ngx.req.read_body()
2022-10-22 01:19:35 -04:00
local request_args = params['uri_request_args']
if not request_args then return false end
2019-04-27 05:54:09 -04:00
2022-10-09 09:29:40 -04:00
for key, val in pairs(request_args) do
if type(val) == "table" then
if type(val[1]) == "boolean" then
return false
end
data = table.concat(val, ", ")
else
data = val
end
end
2022-10-22 01:19:35 -04:00
-- C:D("post:"..json.encode(data))
if C:ngx_match_list(post_rules, data) then
2019-04-27 05:54:09 -04:00
C:write_log('post','regular')
2022-10-22 01:19:35 -04:00
C:return_html(config['post']['status'], post_html)
2019-04-27 05:54:09 -04:00
return true
end
return false
end
2022-10-12 01:49:57 -04:00
local function X_Forwarded()
2022-10-15 05:38:42 -04:00
2019-05-06 01:11:00 -04:00
if params['method'] ~= "GET" then return false end
if not config['get']['open'] or not C:is_site_config('get') then return false end
2022-10-22 01:19:35 -04:00
if not params["request_header"]['X-forwarded-For'] then return false end
2022-10-15 05:38:42 -04:00
2022-10-22 01:19:35 -04:00
if C:ngx_match_list(args_rules, params["request_header"]['X-forwarded-For']) then
2019-04-27 08:21:26 -04:00
C:write_log('args','regular')
2022-10-22 01:19:35 -04:00
C:return_html(config['get']['status'], get_html)
2019-04-27 05:54:09 -04:00
return true
end
return false
end
2022-10-12 01:49:57 -04:00
local function post_X_Forwarded()
2019-05-06 01:11:00 -04:00
if not config['post']['open'] or not C:is_site_config('post') then return false end
if params['method'] ~= "POST" then return false end
2022-10-22 01:19:35 -04:00
if not params["request_header"]['X-forwarded-For'] then return false end
2022-10-23 23:57:46 -04:00
if C:ngx_match_list(post_rules, params["request_header"]['X-forwarded-For']) then
2019-04-27 08:21:26 -04:00
C:write_log('post','regular')
2022-10-22 01:19:35 -04:00
C:return_html(config['post']['status'], post_html)
2019-04-27 05:54:09 -04:00
return true
end
return false
end
2022-10-12 01:49:57 -04:00
local function url_ext()
2019-04-27 05:54:09 -04:00
if site_config[server_name] == nil then return false end
for _,rule in ipairs(site_config[server_name]['disable_ext'])
do
2022-10-10 12:35:13 -04:00
if C:ngx_match_string("\\."..rule.."$", params['uri'],'url_ext') then
2022-10-22 01:19:35 -04:00
if rule == "php" then
C:write_log('php_path','regular')
else
C:write_log('path','regular')
end
2022-10-10 12:35:13 -04:00
C:return_html(config['other']['status'], other_html)
2019-04-27 05:54:09 -04:00
return true
end
end
return false
end
2022-10-12 01:49:57 -04:00
local function disable_upload_ext(ext)
2019-05-06 01:11:00 -04:00
if not ext then return false end
2022-10-24 08:35:39 -04:00
local ext = string.lower(ext)
2022-10-22 01:19:35 -04:00
if C:is_key(site_config[server_name]['disable_upload_ext'], ext) then
C:write_log('upload_ext', '上传扩展名黑名单')
2019-05-06 01:11:00 -04:00
C:return_html(config['other']['status'],other_html)
return true
end
2022-10-22 08:25:46 -04:00
return false
2019-05-06 01:11:00 -04:00
end
2022-10-12 01:49:57 -04:00
local function post_data()
2019-05-06 01:11:00 -04:00
if params["method"] ~= "POST" then return false end
2022-10-22 08:25:46 -04:00
-- C:D("content-length:"..params["request_header"]['content-length'])
2022-10-22 01:19:35 -04:00
local content_length = tonumber(params["request_header"]['content-length'])
2019-05-06 01:11:00 -04:00
if not content_length then return false end
2022-10-22 01:19:35 -04:00
local max_len = 2560 * 1024000
2019-05-06 01:11:00 -04:00
if content_length > max_len then return false end
local boundary = C:get_boundary()
2022-10-22 08:25:46 -04:00
-- C:D("boundary:".. tostring( boundary) )
2019-05-06 01:11:00 -04:00
if boundary then
ngx.req.read_body()
local data = ngx.req.get_body_data()
if not data then return false end
local tmp = ngx.re.match(data,[[filename=\"(.+)\.(.*)\"]])
2022-10-22 08:25:46 -04:00
if not tmp or not tmp[2] then return false end
-- C:D("upload_ext:".. tostring(tmp[2]) )
2019-05-06 01:11:00 -04:00
disable_upload_ext(tmp[2])
end
return false
end
2022-10-12 01:49:57 -04:00
local function waf_cookie()
2019-05-06 01:27:01 -04:00
if not config['cookie']['open'] or not C:is_site_config('cookie') then return false end
if not params["request_header"]['cookie'] then return false end
if type(params["request_header"]['cookie']) ~= "string" then return false end
request_cookie = string.lower(params["request_header"]['cookie'])
2022-10-10 00:36:42 -04:00
if C:ngx_match_list(cookie_rules,request_cookie,'cookie') then
2019-05-06 01:27:01 -04:00
C:write_log('cookie','regular')
C:return_html(config['cookie']['status'],cookie_html)
return true
end
return false
end
2023-08-14 00:56:59 -04:00
local geo=nil
local waf_country=""
2023-08-13 06:32:30 -04:00
local function initmaxminddb()
2023-08-14 00:56:59 -04:00
if geo==nil then
2023-08-13 06:32:30 -04:00
maxminddb ,geo = pcall(function() return require 'waf_maxminddb' end)
if not maxminddb then
2023-08-14 00:56:59 -04:00
C:D("debug waf error on :"..tostring(geo))
2023-08-13 06:32:30 -04:00
return nil
end
end
if type(geo)=='number' then return nil end
local ok2,data=pcall(function()
if not geo.initted() then
geo.init("{$WAF_ROOT}/GeoLite2-City.mmdb")
end
end )
if not ok2 then
geo=nil
end
2023-08-14 00:56:59 -04:00
end
2023-08-13 06:32:30 -04:00
2023-08-14 00:56:59 -04:00
local function get_ip_country(ip)
2023-08-13 06:32:30 -04:00
initmaxminddb()
2023-08-14 00:56:59 -04:00
if type(geo)=='number' then return "2" end
if geo==nil then return "2" end
if geo.lookup==nil then return "2" end
local res,err=geo.lookup(ip or ngx.var.remote_addr)
2023-08-13 06:32:30 -04:00
if not res then
2023-08-14 00:56:59 -04:00
return "2"
2023-08-13 06:32:30 -04:00
else
2023-10-17 14:20:23 -04:00
-- C:D("res:"..tostring(res))
2023-08-13 06:32:30 -04:00
return res
end
end
2023-08-14 00:56:59 -04:00
local function get_country()
local ip = params['ip']
2023-10-17 14:02:44 -04:00
local ip_local = ngx.shared.waf_limit:get("get_country"..ip)
if ip_local then
return ip_local
2023-08-14 00:56:59 -04:00
end
local ip_postion=get_ip_country(ip)
if ip_postion=="2" then return false end
if ip_postion["country"]==nil then return false end
if ip_postion["country"]["names"]==nil then return false end
if ip_postion["country"]["names"]["zh-CN"]==nil then return false end
ngx.shared.waf_limit:set("get_country"..ip,ip_postion["country"]["names"]["zh-CN"],3600)
return ip_postion["country"]["names"]["zh-CN"]
end
2023-08-15 14:53:29 -04:00
local function area_limit(overall_country, server_name, status)
2023-08-15 15:25:46 -04:00
if not status then
return false
end
2023-08-15 14:53:29 -04:00
if overall_country and overall_country~="" and C:count_size(waf_area_limit)>=1 then
for k, val in pairs(waf_area_limit) do
-- C:D(tostring(k)..':'..tostring(val['site']['allsite']) ..':'.. tostring(val['site']['allsite'] == '1') ..':'.. tostring(val['site']['allsite']))
if val['site']['allsite'] and val['site']['allsite'] == '1' and val['types'] == 'refuse' then
for rk, reg_val in pairs(val['region']) do
if rk == overall_country then
ngx.exit(403)
return true
end
end
end
if val['site'][server_name] and val['site'][server_name] == '1' and val['types'] == 'refuse' then
for rk, reg_val in pairs(val['region']) do
if rk == overall_country then
ngx.exit(403)
return true
end
end
end
if val['site']['allsite'] and val['site']['allsite'] == '1' and val['types'] == 'accept' then
for rk, reg_val in pairs(val['region']) do
if rk == overall_country then
return false
end
end
ngx.exit(403)
return true
end
if val['site'][server_name] and val['site'][server_name] == '1' and val['types'] == 'accept' then
for rk, reg_val in pairs(val['region']) do
if rk == overall_country then
return false
end
end
ngx.exit(403)
return true
end
end
end
return false
end
2019-05-06 01:27:01 -04:00
2023-08-14 00:56:59 -04:00
function run_app_waf()
2019-05-06 02:35:15 -04:00
min_route()
2023-02-10 15:43:30 -05:00
-- C:D("min_route")
2023-10-17 14:02:44 -04:00
2022-10-12 05:51:50 -04:00
if site_config[server_name] and site_config[server_name]['open'] then
2023-08-15 14:53:29 -04:00
-- white ip
if waf_ip_white() then return true end
-- C:D("waf_ip_white")
2023-08-14 00:56:59 -04:00
-- url white
if waf_url_white() then return true end
-- C:D("waf_url_white")
-- black ip
if waf_ip_black() then return true end
-- C:D("waf_ip_black")
-- 封禁ip返回
if waf_drop_ip() then return true end
-- C:D("waf_drop_ip")
2023-10-28 01:32:27 -04:00
-- country limit
if config['area_limit'] then
2023-10-28 01:32:45 -04:00
local waf_country = get_country()
2023-10-28 01:32:27 -04:00
if waf_country then
if area_limit(waf_country, server_name, site_config[server_name]['open']) then return true end
end
end
-- ua check
if waf_user_agent() then return true end
-- C:D("waf_user_agent")
if waf_url() then return true end
-- C:D("waf_url")
-- cc setting
if waf_cc_increase() then return true end
-- C:D("waf_cc_increase")
if waf_cc() then return true end
-- C:D("waf_cc")
-- cookie检查
if waf_cookie() then return true end
-- C:D("waf_cookie")
-- args参数拦截
if waf_get_args() then return true end
-- C:D("waf_get_args")
-- 扫描软件禁止
if waf_scan_black() then return true end
-- C:D("waf_scan_black")
if waf_post() then return true end
-- C:D("waf_post")
--------------------------------------------------------
--------------------------------------------------------
2022-10-22 01:19:35 -04:00
if X_Forwarded() then return true end
2023-02-10 15:43:30 -05:00
-- C:D("X_Forwarded")
2022-10-22 01:19:35 -04:00
if post_X_Forwarded() then return true end
2023-02-10 15:43:30 -05:00
-- C:D("post_X_Forwarded")
2022-10-10 12:35:13 -04:00
if url_ext() then return true end
2023-02-10 15:43:30 -05:00
-- C:D("url_ext")
2022-10-22 01:19:35 -04:00
if post_data() then return true end
2023-02-10 15:43:30 -05:00
-- C:D("post_data")
2019-04-27 08:21:26 -04:00
end
2019-04-22 09:21:49 -04:00
end
2019-05-06 01:21:46 -04:00
2023-08-14 00:56:59 -04:00
local waf_run_status = nil
function waf()
if waf_run_status then
run_app_waf()
else
local ok,waf_err=pcall(function()
run_app_waf()
end)
if waf_err ~= nil then
C:D("----waf error-----"..tostring(waf_err))
end
if ok then
waf_run_status = true
end
end
end
2019-05-06 01:21:46 -04:00
waf()