pull/216/head
midoks 3 years ago
parent e7c318e560
commit 735cf9b872
  1. 7
      plugins/op_waf/conf/luawaf.conf
  2. 52
      plugins/op_waf/waf/lua/common.lua
  3. 68
      plugins/op_waf/waf/lua/init.lua
  4. 15
      plugins/op_waf/waf/lua/init_worker.lua

@ -1,9 +1,8 @@
lua_shared_dict limit 30m; lua_shared_dict waf_limit 30m;
lua_shared_dict drop_ip 10m; lua_shared_dict waf_drop_ip 10m;
lua_shared_dict drop_sum 10m; lua_shared_dict waf_drop_sum 10m;
lua_package_path "{$WAF_PATH}/html/?.lua;{$WAF_PATH}/conf/?.lua;{$WAF_PATH}/lua/?.lua;{$ROOT_PATH}/openresty/lualib/?.lua;;"; lua_package_path "{$WAF_PATH}/html/?.lua;{$WAF_PATH}/conf/?.lua;{$WAF_PATH}/lua/?.lua;{$ROOT_PATH}/openresty/lualib/?.lua;;";
init_worker_by_lua_file {$WAF_PATH}/lua/init_worker.lua; init_worker_by_lua_file {$WAF_PATH}/lua/init_worker.lua;
access_by_lua_file {$WAF_PATH}/lua/init.lua; access_by_lua_file {$WAF_PATH}/lua/init.lua;

@ -178,7 +178,7 @@ end
function _M.read_file_body(self, filename) function _M.read_file_body(self, filename)
local key = "file_config_"..filename local key = "file_config_"..filename
local fbody = ngx.shared.limit:get(key, fbody) local fbody = ngx.shared.waf_limit:get(key, fbody)
if fbody then if fbody then
return fbody return fbody
end end
@ -192,14 +192,14 @@ function _M.read_file_body(self, filename)
if fbody == '' then if fbody == '' then
return nil return nil
end end
ngx.shared.limit:set(key,fbody) ngx.shared.waf_limit:set(key,fbody)
return fbody return fbody
end end
function _M.read_file(self, name) function _M.read_file(self, name)
f = self.rpath .. name .. '.json' f = self.rpath .. name .. '.json'
local key = "read_file_"..name local key = "read_file_"..name
local fbody = ngx.shared.limit:get(key, fbody) local fbody = ngx.shared.waf_limit:get(key, fbody)
if fbody then if fbody then
return fbody return fbody
end end
@ -209,19 +209,19 @@ function _M.read_file(self, name)
end end
local data = json.decode(fbody) local data = json.decode(fbody)
ngx.shared.limit:set(key,data) ngx.shared.waf_limit:set(key,data)
return data return data
end end
function _M.read_file_table( self, name ) function _M.read_file_table( self, name )
local key = "read_file_table"..name local key = "read_file_table"..name
fbody = ngx.shared.limit:get(key, fbody) fbody = ngx.shared.waf_limit:get(key, fbody)
if fbody then if fbody then
return fbody return fbody
end end
local data = self:select_rule(self:read_file(name)) local data = self:select_rule(self:read_file(name))
ngx.shared.limit:set(key,data) ngx.shared.waf_limit:set(key,data)
return data return data
end end
@ -242,8 +242,8 @@ function _M.write_file_clear(self, filename, body)
end end
function _M.write_drop_ip(self, is_drop, drop_time) function _M.write_waf_waf_drop_ip(self, is_drop, drop_time)
local filename = self.logdir .. 'drop_ip.log' local filename = self.logdir .. 'waf_waf_drop_ip.log'
local fp = io.open(filename,'ab') local fp = io.open(filename,'ab')
local server_name = self.params["server_name"] local server_name = self.params["server_name"]
@ -304,12 +304,12 @@ end
function _M.read_file_body_decode(self, name) function _M.read_file_body_decode(self, name)
local key = "read_file_body_decode"..name local key = "read_file_body_decode"..name
local fbody = ngx.shared.limit:get(key, fbody) local fbody = ngx.shared.waf_limit:get(key, fbody)
if fbody then if fbody then
return fbody return fbody
end end
local data = json.decode(self:read_file_body(name)) local data = json.decode(self:read_file_body(name))
ngx.shared.limit:set(key,data) ngx.shared.waf_limit:set(key,data)
return data return data
end end
@ -327,7 +327,7 @@ end
local function timer_at_inc_log(premature) local function timer_at_inc_log(premature)
local total_path = cpath .. 'total.json' local total_path = cpath .. 'total.json'
local tbody = ngx.shared.limit:get(total_path) local tbody = ngx.shared.waf_limit:get(total_path)
if not tbody then if not tbody then
return false return false
end end
@ -338,7 +338,7 @@ function _M.inc_log(self, name, rule)
local server_name = self.params['server_name'] local server_name = self.params['server_name']
local total_path = self.cpath .. 'total.json' local total_path = self.cpath .. 'total.json'
local tbody = ngx.shared.limit:get(total_path) local tbody = ngx.shared.waf_limit:get(total_path)
if not tbody then if not tbody then
tbody = self:read_file_body(total_path) tbody = self:read_file_body(total_path)
if not tbody then return false end if not tbody then return false end
@ -360,7 +360,7 @@ function _M.inc_log(self, name, rule)
local total_log = json.encode(total) local total_log = json.encode(total)
if not total_log then return false end if not total_log then return false end
ngx.shared.limit:set(total_path,total_log) ngx.shared.waf_limit:set(total_path,total_log)
-- 异步执行 -- 异步执行
-- 现在改再init_workder.lua 定时执行 -- 现在改再init_workder.lua 定时执行
@ -372,7 +372,7 @@ end
function _M.get_server_name(self) function _M.get_server_name(self)
local c_name = ngx.var.server_name local c_name = ngx.var.server_name
local my_name = ngx.shared.limit:get(c_name) local my_name = ngx.shared.waf_limit:get(c_name)
if my_name then return my_name end if my_name then return my_name end
local tmp = self:read_file_body(self.cpath .. 'domains.json') local tmp = self:read_file_body(self.cpath .. 'domains.json')
if not tmp then return c_name end if not tmp then return c_name end
@ -382,7 +382,7 @@ function _M.get_server_name(self)
for _,d_name in ipairs(v['domains']) for _,d_name in ipairs(v['domains'])
do do
if c_name == d_name then if c_name == d_name then
ngx.shared.limit:set(c_name,v['name'],3600) ngx.shared.waf_limit:set(c_name,v['name'],3600)
return v['name'] return v['name']
end end
end end
@ -526,11 +526,11 @@ function _M.write_log(self, name, rule)
local retry_time = config['retry']['retry_time'] local retry_time = config['retry']['retry_time']
local retry_cycle = config['retry']['retry_cycle'] local retry_cycle = config['retry']['retry_cycle']
local count, _ = ngx.shared.drop_ip:get(ip) local count, _ = ngx.shared.waf_waf_drop_ip:get(ip)
if count then if count then
ngx.shared.drop_ip:incr(ip,1) ngx.shared.waf_waf_drop_ip:incr(ip,1)
else else
ngx.shared.drop_ip:set(ip,1,retry_cycle) ngx.shared.waf_waf_drop_ip:set(ip,1,retry_cycle)
end end
if config['log'] ~= true or self:is_site_config('log') ~= true then return false end if config['log'] ~= true or self:is_site_config('log') ~= true then return false end
@ -542,21 +542,21 @@ function _M.write_log(self, name, rule)
local logtmp = {ngx.localtime(), ip, method, ngx.var.request_uri, ngx.var.http_user_agent, name, rule} local logtmp = {ngx.localtime(), ip, method, ngx.var.request_uri, ngx.var.http_user_agent, name, rule}
local logstr = json.encode(logtmp) .. "\n" local logstr = json.encode(logtmp) .. "\n"
local count,_ = ngx.shared.drop_ip:get(ip) local count,_ = ngx.shared.waf_waf_drop_ip:get(ip)
if count > retry and name ~= 'cc' then if count > retry and name ~= 'cc' then
local safe_count,_ = ngx.shared.drop_sum:get(ip) local safe_count,_ = ngx.shared.waf_drop_sum:get(ip)
if not safe_count then if not safe_count then
ngx.shared.drop_sum:set(ip,1,86400) ngx.shared.waf_drop_sum:set(ip,1,86400)
safe_count = 1 safe_count = 1
else else
ngx.shared.drop_sum:incr(ip,1) ngx.shared.waf_drop_sum:incr(ip,1)
end end
local lock_time = retry_time * safe_count local lock_time = retry_time * safe_count
if lock_time > 86400 then lock_time = 86400 end if lock_time > 86400 then lock_time = 86400 end
logtmp = {ngx.localtime(),ip,method,ngx.var.request_uri, ngx.var.http_user_agent,name,retry_cycle .. '秒以内累计超过'..retry..'次以上非法请求,封锁'.. lock_time ..''} logtmp = {ngx.localtime(),ip,method,ngx.var.request_uri, ngx.var.http_user_agent,name,retry_cycle .. '秒以内累计超过'..retry..'次以上非法请求,封锁'.. lock_time ..''}
logstr = logstr .. json.encode(logtmp) .. "\n" logstr = logstr .. json.encode(logtmp) .. "\n"
ngx.shared.drop_ip:set(ip,retry+1,lock_time) ngx.shared.waf_waf_drop_ip:set(ip,retry+1,lock_time)
self:write_drop_ip('inc',lock_time) self:write_waf_waf_drop_ip('inc',lock_time)
end end
self:write_to_file(logstr) self:write_to_file(logstr)
self:inc_log(name,rule) self:inc_log(name,rule)
@ -581,9 +581,9 @@ function _M.current_time_millis()
end end
function _M.bench(self, limit, sign, call) function _M.bench(self, waf_limit, sign, call)
local func_start = self.current_time_millis() local func_start = self.current_time_millis()
for i=1,limit do for i=1,waf_limit do
call() call()
end end
local func_end = self.current_time_millis() local func_end = self.current_time_millis()

@ -31,14 +31,14 @@ local cookie_rules = require "rule_cookie"
function get_server_name() function get_server_name()
local request_name = ngx.var.server_name local request_name = ngx.var.server_name
local cache_name = ngx.shared.limit:get(request_name) local cache_name = ngx.shared.waf_limit:get(request_name)
if cache_name then return cache_name end if cache_name then return cache_name end
for _,v in ipairs(config_domains) for _,v in ipairs(config_domains)
do do
for _,cd_name in ipairs(v['domains']) for _,cd_name in ipairs(v['domains'])
do do
if request_name == cd_name then if request_name == cd_name then
ngx.shared.limit:set(cd_name,v['name'], 86400) ngx.shared.waf_limit:set(cd_name,v['name'], 86400)
return v['name'] return v['name']
end end
end end
@ -65,7 +65,7 @@ end
local params = initParams() local params = initParams()
C:setParams(params) C:setParams(params)
local cpu_percent = ngx.shared.limit:get("cpu_usage") local cpu_percent = ngx.shared.waf_limit:get("cpu_usage")
local function get_return_state(rstate,rmsg) local function get_return_state(rstate,rmsg)
result = {} result = {}
@ -74,8 +74,8 @@ local function get_return_state(rstate,rmsg)
return result return result
end end
local function get_waf_drop_ip() local function get_waf_waf_waf_drop_ip()
local data = ngx.shared.drop_ip:get_keys(0) local data = ngx.shared.waf_waf_drop_ip:get_keys(0)
return data return data
end end
@ -107,7 +107,7 @@ local function save_ip_on(data)
end end
end end
local function remove_waf_drop_ip() local function remove_waf_waf_waf_drop_ip()
if not uri_request_args['ip'] or not C:is_ipaddr(uri_request_args['ip']) then return get_return_state(true,'格式错误') end if not uri_request_args['ip'] or not C:is_ipaddr(uri_request_args['ip']) then return get_return_state(true,'格式错误') end
if ngx.shared.btwaf:get(cpath2 .. 'stop_ip') then if ngx.shared.btwaf:get(cpath2 .. 'stop_ip') then
ret=ngx.shared.btwaf:get(cpath2 .. 'stop_ip') ret=ngx.shared.btwaf:get(cpath2 .. 'stop_ip')
@ -126,11 +126,11 @@ local function remove_waf_drop_ip()
end end
save_ip_on(ip_data2) save_ip_on(ip_data2)
end end
ngx.shared.drop_ip:delete(uri_request_args['ip']) ngx.shared.waf_waf_drop_ip:delete(uri_request_args['ip'])
return get_return_state(true,uri_request_args['ip'] .. '已解封') return get_return_state(true,uri_request_args['ip'] .. '已解封')
end end
local function clean_waf_drop_ip() local function clean_waf_waf_waf_drop_ip()
if ngx.shared.btwaf:get(cpath2 .. 'stop_ip') then if ngx.shared.btwaf:get(cpath2 .. 'stop_ip') then
ret2=ngx.shared.btwaf:get(cpath2 .. 'stop_ip') ret2=ngx.shared.btwaf:get(cpath2 .. 'stop_ip')
ip_data2=json.decode(ret2) ip_data2=json.decode(ret2)
@ -141,22 +141,22 @@ local function clean_waf_drop_ip()
save_ip_on(ip_data2) save_ip_on(ip_data2)
os.execute("sleep " .. 2) os.execute("sleep " .. 2)
end end
local data = get_btwaf_drop_ip() local data = get_btwaf_waf_waf_drop_ip()
for _,value in ipairs(data) for _,value in ipairs(data)
do do
ngx.shared.drop_ip:delete(value) ngx.shared.waf_waf_drop_ip:delete(value)
end end
return get_return_state(true,'已解封所有封锁IP') return get_return_state(true,'已解封所有封锁IP')
end end
local function min_route() local function min_route()
if ngx.var.remote_addr ~= '127.0.0.1' then return false end if ngx.var.remote_addr ~= '127.0.0.1' then return false end
if uri == '/get_waf_drop_ip' then if uri == '/get_waf_waf_waf_drop_ip' then
return_message(200,get_waf_drop_ip()) return_message(200,get_waf_waf_waf_drop_ip())
elseif uri == '/remove_waf_drop_ip' then elseif uri == '/remove_waf_waf_waf_drop_ip' then
return_message(200,remove_waf_drop_ip()) return_message(200,remove_waf_waf_waf_drop_ip())
elseif uri == '/clean_waf_drop_ip' then elseif uri == '/clean_waf_waf_waf_drop_ip' then
return_message(200,clean_waf_drop_ip()) return_message(200,clean_waf_waf_waf_drop_ip())
end end
end end
@ -217,7 +217,7 @@ end
local function waf_drop() local function waf_drop()
local count , _ = ngx.shared.drop_ip:get(ip) local count , _ = ngx.shared.waf_drop_ip:get(ip)
if not count then return false end if not count then return false end
if count > config['retry'] then if count > config['retry'] then
ngx.exit(config['cc']['status']) ngx.exit(config['cc']['status'])
@ -229,7 +229,7 @@ end
local function waf_cc() local function waf_cc()
local ip = params['ip'] local ip = params['ip']
local ip_lock = ngx.shared.drop_ip:get(ip) local ip_lock = ngx.shared.waf_drop_ip:get(ip)
if ip_lock then if ip_lock then
if ip_lock > 0 then if ip_lock > 0 then
ngx.exit(config['cc']['status']) ngx.exit(config['cc']['status'])
@ -244,37 +244,37 @@ local function waf_cc()
local endtime = config['cc']['endtime'] local endtime = config['cc']['endtime']
local token = ngx.md5(ip .. '_' .. request_uri) local token = ngx.md5(ip .. '_' .. request_uri)
local count = ngx.shared.limit:get(token) local count = ngx.shared.waf_limit:get(token)
local limit = config['cc']['limit'] local waf_limit = config['cc']['waf_limit']
local cycle = config['cc']['cycle'] local cycle = config['cc']['cycle']
if count then if count then
if count > limit then if count > waf_limit then
local safe_count, _ = ngx.shared.drop_sum:get(ip) local safe_count, _ = ngx.shared.waf_drop_sum:get(ip)
if not safe_count then if not safe_count then
ngx.shared.drop_sum:set(ip,1,86400) ngx.shared.waf_drop_sum:set(ip,1,86400)
safe_count = 1 safe_count = 1
else else
ngx.shared.drop_sum:incr(ip,1) ngx.shared.waf_drop_sum:incr(ip,1)
end end
local lock_time = (endtime * safe_count) local lock_time = (endtime * safe_count)
if lock_time > 86400 then lock_time = 86400 end if lock_time > 86400 then lock_time = 86400 end
-- lock_time = 10 -- lock_time = 10
ngx.shared.drop_ip:set(ip,1,lock_time) ngx.shared.waf_waf_drop_ip:set(ip,1,lock_time)
C:write_log('cc',cycle..'秒内累计超过'..limit..'次请求,封锁' .. lock_time .. '') C:write_log('cc',cycle..'秒内累计超过'..waf_limit..'次请求,封锁' .. lock_time .. '')
C:write_drop_ip('cc',lock_time) C:write_waf_waf_drop_ip('cc',lock_time)
ngx.exit(config['cc']['status']) ngx.exit(config['cc']['status'])
return true return true
else else
ngx.shared.limit:incr(token,1) ngx.shared.waf_limit:incr(token,1)
end end
else else
ngx.shared.drop_sum:set(ip,1,86400) ngx.shared.waf_drop_sum:set(ip,1,86400)
ngx.shared.limit:set(token, 1, cycle) ngx.shared.waf_limit:set(token, 1, cycle)
end end
return false return false
end end
@ -311,13 +311,13 @@ local function waf_cc_increase()
local cache_token = ngx.md5(ip .. '_' .. server_name) local cache_token = ngx.md5(ip .. '_' .. server_name)
--判断是否已经通过验证 --判断是否已经通过验证
if ngx.shared.limit:get(cache_token) then return false end if ngx.shared.waf_limit:get(cache_token) then return false end
local cache_rand_key = ip..':rand' local cache_rand_key = ip..':rand'
local cache_rand = ngx.shared.limit:get(cache_rand_key) local cache_rand = ngx.shared.waf_limit:get(cache_rand_key)
if not cache_rand then if not cache_rand then
cache_rand = C:get_random(8) cache_rand = C:get_random(8)
ngx.shared.limit:set(cache_rand_key,cache_rand,30) ngx.shared.waf_limit:set(cache_rand_key,cache_rand,30)
end end
make_token = "waf_unbind_"..cache_rand.."_"..cache_token make_token = "waf_unbind_"..cache_rand.."_"..cache_token
@ -327,7 +327,7 @@ local function waf_cc_increase()
if params['uri_request_args']['token'] then if params['uri_request_args']['token'] then
local args_token = params['uri_request_args']['token'] local args_token = params['uri_request_args']['token']
if args_token == make_token then if args_token == make_token then
ngx.shared.limit:set(cache_token,1, config['safe_verify']['time']) ngx.shared.waf_limit:set(cache_token,1, config['safe_verify']['time'])
C:return_message(200, get_return_state(0,'ok')) C:return_message(200, get_return_state(0,'ok'))
end end
end end

@ -1,4 +1,5 @@
local json = require "cjson"
local waf_root = "{$WAF_ROOT}" local waf_root = "{$WAF_ROOT}"
local cpath = waf_root.."/waf/" local cpath = waf_root.."/waf/"
@ -19,7 +20,7 @@ end
local function timer_at_inc_log(premature) local function timer_at_inc_log(premature)
local total_path = cpath .. 'total.json' local total_path = cpath .. 'total.json'
local tbody = ngx.shared.limit:get(total_path) local tbody = ngx.shared.waf_waf_limit:get(total_path)
if not tbody then if not tbody then
return false return false
end end
@ -27,19 +28,13 @@ local function timer_at_inc_log(premature)
end end
ngx.shared.waf_waf_limit:set("cpu_usage", 0, 10)
ngx.shared.limit:set("cpu_usage", 0, 10)
local function excute_cmd(cmd)
local t = io.popen(cmd)
local ret = t:read("*all")
return ret
end
function timer_every_get_cpu(premature) function timer_every_get_cpu(premature)
cpu_percent = 80 cpu_percent = 80
ngx.shared.limit:set("cpu_usage", cpu_percent, 10) ngx.shared.waf_waf_limit:set("cpu_usage", cpu_percent, 10)
end end
if 0 == ngx.worker.id() then if 0 == ngx.worker.id() then
ngx.timer.every(5, timer_every_get_cpu) ngx.timer.every(5, timer_every_get_cpu)

Loading…
Cancel
Save