Update init.lua

pull/136/head
weakestan 2018-08-07 08:24:52 +08:00 committed by GitHub
parent 9d03dd8f1d
commit 02d0adcaba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 126 additions and 17 deletions

143
init.lua
View File

@ -1,19 +1,52 @@
require 'config'
local match = string.match
local ngxmatch=ngx.re.match
--ngx_lua如果是0.9.2以上版本建议正则过滤函数改为ngx.re.find匹配效率会提高三倍左右。
--因nginx和lua一起的关系正则表达式使用\d\w\s会出问题
--local ngxmatch=ngx.re.match
local ngxmatch=ngx.re.find
local unescape=ngx.unescape_uri
local get_headers = ngx.req.get_headers
local optionIsOn = function (options) return options == "on" and true or false end
loghack=optionIsOn(loghack)
--载入socket.lua用于发送log到独立syslog服务器。
local logger = require "socket"
if loghack then
if not logger.initted() then
local ok, err = logger.init{
--host = '192.168.0.1',
host = 'logserver.local',
port = 514,
sock_type = "udp", --udp协议
flush_limit = 1, --立即发送
--drop_limit = 5678,
pool_size = 100,--连接池大小
}
if not ok then
ngx.log(ngx.ERR, "failed to initialize the logger: ",
err)
return
end
end
end
logpath = logdir
rulepath = RulePath
logtofile = optionIsOn(logtofile)
logtoserver = optionIsOn(logtoserver)
UrlDeny = optionIsOn(UrlDeny)
PostCheck = optionIsOn(postMatch)
CookieCheck = optionIsOn(cookieMatch)
WhiteCheck = optionIsOn(whiteModule)
PathInfoFix = optionIsOn(PathInfoFix)
attacklog = optionIsOn(attacklog)
hackipdeny = optionIsOn(hackipdeny)
CCDeny = optionIsOn(CCDeny)
Redirect=optionIsOn(Redirect)
local file = io.open('config')
function getClientIp()
IP = ngx.var.remote_addr
if IP == nil then
@ -28,19 +61,38 @@ function write(logfile,msg)
fd:flush()
fd:close()
end
function swrite(msg)
--保存警告等级要高于nginx error_log的默认等级。
ngx.log(ngx.CRIT,msg)
end
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"
else
line = realIp.." ["..time.."] \""..method.." "..servername..url.."\" \""..data.."\" - \""..ruletag.."\"\n"
if ua == nil then
ua="null"
end
local servername=ngx.var.host
local time=ngx.localtime()
if logtofile then
local filename = logpath..'/'..servername.."_"..ngx.today().."_sec.log"
line=realIp.." ["..time.."]".."\""..method.." "..servername..url.."\""..data.."\""..ua.."\""..ruletag.."\"".."\n"
write(filename,line)
end
if logtoserver then
line=realIp.."\""..method.." "..servername..url.."\""..data.."\""..ua.."\""..ruletag.."\""
--line="lua_waf:"..line
swrite(line)
end
--发送ip到独立syslog服务器。
if loghack then local bytes, err = logger.log(getClientIp()) end
--只要log记录说明被攻击利用denyhackip将ip记录。
if hackipdeny then denyhackip(0) end
end
end
------------------------------------规则读取函数-------------------------------------------------------------------
@ -78,21 +130,35 @@ function whiteurl()
if WhiteCheck then
if wturlrules ~=nil then
for _,rule in pairs(wturlrules) do
if ngxmatch(ngx.var.uri,rule,"isjo") then
--针对site:开始的进行域名匹配。增加白名单用处。
local sitemod,_=string.find(rule,"site:")
if sitemod==1 then
rule=string.gsub(rule,"site:","",1)
--调试whiteurl
--if ngx.var.host=='domino.cqhrss.gov.cn' then
-- log('debug',ngx.var.uri,"",rule)
--end
if ngxmatch(ngx.var.host..ngx.var.uri,rule,"isjo") then
return true
end
end
else
if ngxmatch(ngx.var.uri,rule,"isjo") then
return true
end
end
end
end
end
return false
end
function fileExtCheck(ext)
local items = Set(black_fileExt)
ext=string.lower(ext)
if ext then
for rule in pairs(items) do
if ngx.re.match(ext,rule,"isjo") then
log('POST',ngx.var.request_uri,"-","file attack with ext "..ext)
for rule,_ in pairs(items) do
if ngxmatch(ext,rule,"isjo") then
log('POST',ngx.var.request_uri,"-","file attack with ext "..ext)
say_html()
end
end
@ -184,17 +250,25 @@ end
function denycc()
if CCDeny then
local uri=ngx.var.uri
CCcount=tonumber(string.match(CCrate,'(.*)/'))
CCseconds=tonumber(string.match(CCrate,'/(.*)'))
local m, err = ngx.re.match(CCrate,'([0-9]+)/([0-9]+)/([0-9]+)')
local CCcount=tonumber(m[1]) --计数器上限
local CCseconds=tonumber(m[2]) --计时器
local CClimits=tonumber(m[3]) --阻止访问时间
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(404)
return true
else
limit:incr(token,1)
if req == CCcount then limit:set(token,CCcount+1,CClimits) end
limit:incr(token,1)
--调试在syslog日志中查看
--swrite('计数器:'..token..'当前计数器'..req..'阻止访问时间:'..CClimits)
end
else
limit:set(token,1,CCseconds)
@ -203,6 +277,41 @@ function denycc()
return false
end
--chk为1表示检测值不增加不创建返回检测结果。
function denyhackip(chk)
if hackipdeny then
local m, err = ngx.re.match(hackrate,'([0-9]+)/([0-9]+)/([0-9]+)')
local hicount=tonumber(m[1]) --计数器上限
local hiseconds=tonumber(m[2]) --计时器
local hilimits=tonumber(m[3]) --阻止访问时间
local token = "hackip"..getClientIp()
local limit = ngx.shared.limit
local req,_=limit:get(token) --计数器当前值
if req then
if req > hicount then
ngx.exit(404)
return true
else
if req == hicount then
limit:set(token,hicount+1,hilimits)
swrite("ip:"..getClientIp().."因攻击被暂停访问"..hilimits.."秒。")
end
if chk ~=1 then limit:incr(token,1) end
--调试在syslog日志中查看
--swrite("计数器:"..token.."检测状态:"..chk.."当前计数器"..req.."阻止访问时间:"..hilimits)
end
else
if chk ~=1 then limit:set(token,1,hiseconds) end
end
end
return false
end
function get_boundary()
local header = get_headers()["content-type"]
if not header then