mirror of https://github.com/Safe3/uuWAF
shuaiZend
7 months ago
committed by
GitHub
1 changed files with 133 additions and 0 deletions
@ -0,0 +1,133 @@
|
||||
--- |
||||
--- Generated by MC(https://www.magentochina.org/) |
||||
--- Created by Shua1. |
||||
--- DateTime: 2024/04/29 14:32 |
||||
--- |
||||
local log = require("waf.log") |
||||
local _M = { |
||||
version = 0.1, |
||||
name = "request-log2file" |
||||
} |
||||
-- 内存队列,用于缓存日志数据 |
||||
local logQueue = {} |
||||
-- 获取当前日期 |
||||
local function getCurrentDate() |
||||
return os.date("%Y-%m-%d") |
||||
end |
||||
-- 日志文件路径 |
||||
local logFilePath = "/uuwaf/logs/access_log_" .. getCurrentDate() .. ".json" |
||||
-- 记录的请求数量阈值,降低IOPS |
||||
local LOG_THRESHOLD = 10 |
||||
-- 计数器,用于跟踪已记录的请求数量 |
||||
local requestCounter = 0 |
||||
|
||||
-- 将日志信息写入文件 |
||||
local function logToFile(filename, logs) |
||||
local file = io.open(filename, "a") |
||||
if not file then |
||||
ngx.log(ngx.ERR, "Failed to open log file: ", filename) |
||||
return |
||||
end |
||||
|
||||
for _, info in ipairs(logs) do |
||||
local json_str = log.encodeJson(info) |
||||
file:write(json_str .. "\n") |
||||
end |
||||
|
||||
file:close() |
||||
end |
||||
|
||||
-- 判断是否应该记录该请求 |
||||
local function shouldLogRequest(waf) |
||||
-- 如果是POST请求,则无论URI是否匹配静态文件,都记录 |
||||
if ngx.var.request_method == "POST" then |
||||
return true |
||||
end |
||||
-- 排除以静态文件格式为结尾的请求,可根据自身需求修改 |
||||
local uri = ngx.var.uri |
||||
if uri:match("/[^/]*%.(js|css|jpg|jpeg|png|gif|svg|webp)$") then |
||||
return false |
||||
end |
||||
return true |
||||
end |
||||
|
||||
-- 将日志信息写入内存队列 |
||||
local function logToMemory(info) |
||||
table.insert(logQueue, info) |
||||
-- 写入文件 |
||||
logToFile(logFilePath, logQueue) |
||||
end |
||||
|
||||
-- 将内存队列中的日志写入文件 |
||||
local function flushLogsToFile(premature, filename) |
||||
if not premature then |
||||
if #logQueue > 0 then |
||||
logToFile(filename, logQueue) |
||||
logQueue = {} -- 清空内存队列 |
||||
end |
||||
end |
||||
end |
||||
|
||||
-- 截断字符串到指定长度并进行Base64处理 |
||||
local function truncateString(str, length) |
||||
if str and #str > length then |
||||
str = str:sub(1, length) |
||||
end |
||||
return ngx.encode_base64(str) |
||||
end |
||||
|
||||
-- 请求阶段后过滤 |
||||
function _M.log_pre_filter(waf) |
||||
-- 判断是否应该记录该请求 |
||||
if shouldLogRequest(waf) then |
||||
local request_body_short = "" |
||||
local block_action = "" |
||||
local waf_rule_id = "" |
||||
if ngx.var.request_method == "POST" and waf.reqContentLength > 2 then |
||||
local body_data = (waf.form and waf.form["RAW"]) or '' |
||||
if body_data then |
||||
request_body_short = truncateString(body_data, 1000) -- 截断 request_body_short 并进行 Base64 处理 |
||||
end |
||||
end |
||||
if waf.msg then |
||||
block_action = "uuWaf" |
||||
waf_rule_id = waf.rule_id |
||||
end |
||||
local info = { |
||||
["block_action"] = block_action, |
||||
["waf_rule_id"] = waf_rule_id, |
||||
["time"] = ngx.var.time_iso8601, |
||||
["server_addr"] = ngx.var.server_addr, |
||||
["remote_addr"] = ngx.var.http_x_forwarded_for, |
||||
["scheme"] = ngx.var.scheme, |
||||
["request_method"] = ngx.var.request_method, |
||||
["request_uri"] = ngx.var.request_uri, |
||||
["request_length"] = ngx.var.request_length, |
||||
["uri"] = ngx.var.uri, |
||||
["request_time"] = ngx.var.request_time, |
||||
["body_bytes_sent"] = ngx.var.body_bytes_sent, |
||||
["request_body"] = request_body_short, |
||||
["bytes_sent"] = ngx.var.bytes_sent, |
||||
["status"] = ngx.var.status, |
||||
["upstream_time"] = ngx.var.upstream_response_time, |
||||
["upstream_host"] = ngx.var.upstream_addr, |
||||
["upstream_status"] = ngx.var.upstream_status, |
||||
["host"] = ngx.var.host, |
||||
["http_referer"] = ngx.var.http_referer, |
||||
["http_user_agent"] = ngx.var.http_user_agent, |
||||
["http_cookie"] = ngx.var.http_cookie |
||||
} |
||||
-- 将日志信息存入内存队列 |
||||
table.insert(logQueue, info) |
||||
-- 更新计数器 |
||||
requestCounter = requestCounter + 1 |
||||
-- 如果达到记录阈值,则执行写入操作,并重置计数器 |
||||
if requestCounter >= LOG_THRESHOLD then |
||||
logToFile(logFilePath, logQueue) |
||||
logQueue = {} -- 清空内存队列 |
||||
requestCounter = 0 -- 重置计数器 |
||||
end |
||||
end |
||||
end |
||||
|
||||
return _M |
Loading…
Reference in new issue