1Panel/plugins/openresty/waf/log_and_traffic.lua

172 lines
4.7 KiB
Lua
Raw Normal View History

2024-02-28 06:34:09 +00:00
local utils = require "utils"
local config = require "config"
local redis_util = require "redis_util"
local action = require "action"
local uuid = require"resty.uuid"
2024-02-28 06:34:09 +00:00
local upper_str = string.upper
local tonumber = tonumber
local pairs = pairs
2024-02-28 06:34:09 +00:00
local function writeAttackLog()
local rule_table = ngx.ctx.rule_table
local action = ngx.ctx.action
local rule = rule_table.rule
local rule_type = rule_table.type
if not rule_type then
rule_type = "default"
end
local real_ip = ngx.ctx.ip
2024-02-28 06:34:09 +00:00
local geoip = ngx.ctx.geoip
local country = geoip.country
if not country then
country["zh"] = "unknown"
country["en"] = "unknown"
end
local province = geoip.province
if not province then
province["zh"] = "unknown"
province["en"] = "unknown"
end
2024-02-28 06:34:09 +00:00
local longitude = geoip.longitude
local latitude = geoip.latitude
local iso = geoip.iso
2024-02-28 06:34:09 +00:00
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
value = v
end
logs_str = logs_str .. upper_str(k) .. ": " .. value .. "\n"
2024-02-28 06:34:09 +00:00
end
2024-02-28 06:34:09 +00:00
local isBlock = 0
local blocking_time = 0
if ngx.ctx.ipBlocked then
isBlock = 1
blocking_time = tonumber(rule_table.ipBlockTime)
end
local log_id = uuid()
local time = os.time()
local localtime = os.date("%Y-%m-%d %H:%M:%S", time)
local wafdb = utils.get_wafdb(config.waf_db_path)
if wafdb == nil then
return false
end
2024-02-28 06:34:09 +00:00
local insertQuery = [[
INSERT INTO attack_log (
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,
nginx_log, blocking_time, action, is_block
2024-02-28 06:34:09 +00:00
) 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,
:logs_str, :blocking_time, :action, :is_block
2024-02-28 06:34:09 +00:00
)
]]
local stmt = wafdb:prepare(insertQuery)
stmt:bind_names {
id = log_id,
iso = iso,
real_ip = real_ip,
country_zh = country["zh"],
country_en = country["en"],
province_zh = province["zh"],
province_en = province["en"],
2024-02-28 06:34:09 +00:00
longitude = longitude,
latitude = latitude,
time = time,
localtime = localtime,
2024-02-28 06:34:09 +00:00
host = host,
server_name = host,
2024-02-28 06:34:09 +00:00
website_key = website_key,
method = method,
uri = uri,
ua = ua,
rule_type = rule_type,
match_rule = rule,
match_value = "",
logs_str = logs_str,
2024-02-28 06:34:09 +00:00
blocking_time = blocking_time or 0,
action = action,
is_block = isBlock
}
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 .. " ")
2024-02-28 06:34:09 +00:00
end
end
end
local function count_not_found()
if ngx.status ~= 404 then
return
end
if config.is_global_state_on("notFoundCount") then
local ip = ngx.ctx.ip
local not_found_config = config.get_global_config("notFoundCount")
local key = ip
if config.is_redis_on() then
key = "cc_attack_count:" .. key
local count, _ = redis_util.incr(key, not_found_config.duration)
if not count then
redis_util.set(key, 1, not_found_config.duration)
elseif count >= not_found_config.threshold then
action.block_ip(ip, not_found_config)
return
end
else
key = ip .. "not_found"
local limit = ngx.shared.waf_limit
local count, _ = limit:incr(key, 1, 0, not_found_config.duration)
if not count then
limit:set(key, 1, not_found_config.duration)
elseif count >= not_found_config.threshold then
action.block_ip(ip, not_found_config)
return
end
end
end
end
if config.is_waf_on() then
count_not_found()
local isAttack = ngx.ctx.isAttack
if isAttack then
writeAttackLog()
end
end