Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 85 additions & 80 deletions init.lua
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
require 'config'
require'config'
local match = string.match
local ngxmatch=ngx.re.match
local unescape=ngx.unescape_uri
local ngxmatch = ngx.re.match
local unescape = ngx.unescape_uri
local get_headers = ngx.req.get_headers
local optionIsOn = function (options) return options == "on" and true or false end
logpath = logdir
local optionIsOn = function(options) return options == "on" and true or false end
logpath = logdir
rulepath = RulePath
UrlDeny = optionIsOn(UrlDeny)
PostCheck = optionIsOn(postMatch)
Expand All @@ -13,59 +13,62 @@ WhiteCheck = optionIsOn(whiteModule)
PathInfoFix = optionIsOn(PathInfoFix)
attacklog = optionIsOn(attacklog)
CCDeny = optionIsOn(CCDeny)
Redirect=optionIsOn(Redirect)
Redirect = optionIsOn(Redirect)
function getClientIp()
IP = ngx.req.get_headers()["X-Real-IP"]
if IP == nil then
IP = ngx.var.remote_addr
end
if IP == nil then
IP = "unknown"
end
return IP
IP = ngx.req.get_headers()["X-Real-IP"]
if IP == nil then
IP = ngx.var.remote_addr
end
if IP == nil then
IP = "unknown"
end
return IP
end
function write(logfile,msg)
local fd = io.open(logfile,"ab")

function write(logfile, msg)
local fd = io.open(logfile, "ab")
if fd == nil then return end
fd:write(msg)
fd:flush()
fd:close()
end
function log(method,url,data,ruletag)

function log(method, url, data, ruletag)
if attacklog then
local realIp = getClientIp()
local ua = ngx.var.http_user_agent
local servername=ngx.var.server_name
local time=ngx.localtime()
if ua then
line = realIp.." ["..time.."] \""..method.." "..servername..url.."\" \""..data.."\" \""..ua.."\" \""..ruletag.."\"\n"
local servername = ngx.var.server_name
local time = ngx.localtime()
if ua then
line = realIp .. " [" .. time .. "] \"" .. method .. " " .. servername .. url .. "\" \"" .. data .. "\" \"" .. ua .. "\" \"" .. ruletag .. "\"\n"
else
line = realIp.." ["..time.."] \""..method.." "..servername..url.."\" \""..data.."\" - \""..ruletag.."\"\n"
line = realIp .. " [" .. time .. "] \"" .. method .. " " .. servername .. url .. "\" \"" .. data .. "\" - \"" .. ruletag .. "\"\n"
end
local filename = logpath..'/'..servername.."_"..ngx.today().."_sec.log"
write(filename,line)
local filename = logpath .. '/' .. servername .. "_" .. ngx.today() .. "_sec.log"
write(filename, line)
end
end
------------------------------------规则读取函数-------------------------------------------------------------------

------------------------------------ 规则读取函数-------------------------------------------------------------------
function read_rule(var)
file = io.open(rulepath..'/'..var,"r")
if file==nil then
file = io.open(rulepath .. '/' .. var, "r")
if file == nil then
return
end
t = {}
for line in file:lines() do
table.insert(t,line)
table.insert(t, line)
end
file:close()
return(t)
return (t)
end

urlrules=read_rule('url')
argsrules=read_rule('args')
uarules=read_rule('user-agent')
wturlrules=read_rule('whiteurl')
postrules=read_rule('post')
ckrules=read_rule('cookie')
urlrules = read_rule('url')
argsrules = read_rule('args')
uarules = read_rule('user-agent')
wturlrules = read_rule('whiteurl')
postrules = read_rule('post')
ckrules = read_rule('cookie')


function say_html()
Expand All @@ -78,30 +81,30 @@ end

function whiteurl()
if WhiteCheck then
if wturlrules ~=nil then
for _,rule in pairs(wturlrules) do
if ngxmatch(ngx.var.request_uri,rule,"imjo") then
return true
end
if wturlrules ~= nil then
for _, rule in pairs(wturlrules) do
if ngxmatch(ngx.var.request_uri, rule, "imjo") then
return true
end
end
end
end
return false
end

function args()
for _,rule in pairs(argsrules) do
for _, rule in pairs(argsrules) do
local args = ngx.req.get_uri_args()
for key, val in pairs(args) do
if type(val)=='table' then
if type(val) == 'table' then
if val == false then
data=table.concat(val, " ")
data = table.concat(val, " ")
end
else
data=val
data = val
end
if data and type(data) ~= "boolean" and rule ~="" and ngxmatch(unescape(data),rule,"imjo") then
log('GET',ngx.var.request_uri,"-",rule)
if data and type(data) ~= "boolean" and rule ~= "" and ngxmatch(unescape(data), rule, "imjo") then
log('GET', ngx.var.request_uri, "-", rule)
say_html()
return true
end
Expand All @@ -113,9 +116,9 @@ end

function url()
if UrlDeny then
for _,rule in pairs(urlrules) do
if rule ~="" and ngxmatch(ngx.var.request_uri,rule,"imjo") then
log('GET',ngx.var.request_uri,"-",rule)
for _, rule in pairs(urlrules) do
if rule ~= "" and ngxmatch(ngx.var.request_uri, rule, "imjo") then
log('GET', ngx.var.request_uri, "-", rule)
say_html()
return true
end
Expand All @@ -127,34 +130,36 @@ end
function ua()
local ua = ngx.var.http_user_agent
if ua ~= nil then
for _,rule in pairs(uarules) do
if rule ~="" and ngxmatch(ua,rule,"imjo") then
log('UA',ngx.var.request_uri,"-",rule)
for _, rule in pairs(uarules) do
if rule ~= "" and ngxmatch(ua, rule, "imjo") then
log('UA', ngx.var.request_uri, "-", rule)
say_html()
return true
return true
end
end
end
return false
end

function body(data)
for _,rule in pairs(postrules) do
if rule ~="" and data~="" and ngxmatch(unescape(data),rule,"imjo") then
log('POST',ngx.var.request_uri,data,rule)
for _, rule in pairs(postrules) do
if rule ~= "" and data ~= "" and ngxmatch(unescape(data), rule, "imjo") then
log('POST', ngx.var.request_uri, data, rule)
say_html()
return true
end
end
return false
end

function cookie()
local ck = ngx.var.http_cookie
if CookieCheck and ck then
for _,rule in pairs(ckrules) do
if rule ~="" and ngxmatch(ck,rule,"imjo") then
log('Cookie',ngx.var.request_uri,"-",rule)
for _, rule in pairs(ckrules) do
if rule ~= "" and ngxmatch(ck, rule, "imjo") then
log('Cookie', ngx.var.request_uri, "-", rule)
say_html()
return true
return true
end
end
end
Expand All @@ -163,21 +168,21 @@ end

function denycc()
if CCDeny then
local uri=ngx.var.uri
CCcount=tonumber(string.match(CCrate,'(.*)/'))
CCseconds=tonumber(string.match(CCrate,'/(.*)'))
local token = getClientIp()..uri
local uri = ngx.var.uri
CCcount = tonumber(string.match(CCrate, '(.*)/'))
CCseconds = tonumber(string.match(CCrate, '/(.*)'))
local token = getClientIp() .. uri
local limit = ngx.shared.limit
local req,_=limit:get(token)
local req, _ = limit:get(token)
if req then
if req > CCcount then
ngx.exit(503)
ngx.exit(503)
return true
else
limit:incr(token,1)
limit:incr(token, 1)
end
else
limit:set(token,1,CCseconds)
limit:set(token, 1, CCseconds)
end
end
return false
Expand All @@ -203,23 +208,23 @@ end

function whiteip()
if next(ipWhitelist) ~= nil then
for _,ip in pairs(ipWhitelist) do
if getClientIp()==ip then
for _, ip in pairs(ipWhitelist) do
if getClientIp() == ip then
return true
end
end
end
return false
return false
end

function blockip()
if next(ipBlocklist) ~= nil then
for _,ip in pairs(ipBlocklist) do
if getClientIp()==ip then
ngx.exit(403)
return true
end
end
end
return false
if next(ipBlocklist) ~= nil then
for _, ip in pairs(ipBlocklist) do
if getClientIp() == ip then
ngx.exit(403)
return true
end
end
end
return false
end
96 changes: 48 additions & 48 deletions waf.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
local content_length=tonumber(ngx.req.get_headers()['content-length'])
local method=ngx.req.get_method()
local content_length = tonumber(ngx.req.get_headers()['content-length'])
local method = ngx.req.get_method()
if whiteip() then
elseif blockip() then
elseif denycc() then
Expand All @@ -13,57 +13,57 @@ elseif url() then
elseif args() then
elseif cookie() then
elseif PostCheck then
if method=="POST" then
local boundary = get_boundary()
if boundary then
local len = string.len
if method == "POST" then
local boundary = get_boundary()
if boundary then
local len = string.len
local sock, err = ngx.req.socket()
if not sock then
return
if not sock then
return
end
ngx.req.init_body(128 * 1024)
ngx.req.init_body(128 * 1024)
sock:settimeout(0)
local content_length = nil
content_length=tonumber(ngx.req.get_headers()['content-length'])
local chunk_size = 4096
local content_length = nil
content_length = tonumber(ngx.req.get_headers()['content-length'])
local chunk_size = 4096
if content_length < chunk_size then
chunk_size = content_length
end
chunk_size = content_length
end
local size = 0
while size < content_length do
local data, err, partial = sock:receive(chunk_size)
data = data or partial
if not data then
return
end
ngx.req.append_body(data)
if body(data) then
return true
end
size = size + len(data)
local less = content_length - size
if less < chunk_size then
chunk_size = less
end
end
ngx.req.finish_body()
else
ngx.req.read_body()
local args = ngx.req.get_post_args()
if not args then
return
end
for key, val in pairs(args) do
if type(val) == "table" then
data=table.concat(val, ", ")
else
data=val
end
if data and type(data) ~= "boolean" and body(data) then
return true
end
end
end
while size < content_length do
local data, err, partial = sock:receive(chunk_size)
data = data or partial
if not data then
return
end
ngx.req.append_body(data)
if body(data) then
return true
end
size = size + len(data)
local less = content_length - size
if less < chunk_size then
chunk_size = less
end
end
ngx.req.finish_body()
else
ngx.req.read_body()
local args = ngx.req.get_post_args()
if not args then
return
end
for key, val in pairs(args) do
if type(val) == "table" then
data = table.concat(val, ", ")
else
data = val
end
if data and type(data) ~= "boolean" and body(data) then
return true
end
end
end
end
else
return
Expand Down