modify
parent
8802cd6ac7
commit
e3b48f7ae4
|
@ -111,6 +111,9 @@ nginx安装路径假设为:/usr/local/nginx/conf/
|
||||||
post是只在post请求过滤的规则
|
post是只在post请求过滤的规则
|
||||||
whitelist是白名单,里面的url匹配到不做过滤
|
whitelist是白名单,里面的url匹配到不做过滤
|
||||||
user-agent是对user-agent的过滤规则
|
user-agent是对user-agent的过滤规则
|
||||||
|
ipwhitelist是IP白名单,一行一个IP
|
||||||
|
ipblacklist是IP黑名单,一行一个IP
|
||||||
|
ccrate是CC防护的动态规则,修改后生效
|
||||||
|
|
||||||
|
|
||||||
默认开启了get和post过滤,需要开启cookie过滤的,编辑waf.lua取消部分--注释即可
|
默认开启了get和post过滤,需要开启cookie过滤的,编辑waf.lua取消部分--注释即可
|
||||||
|
|
63
config.lua
63
config.lua
|
@ -1,45 +1,40 @@
|
||||||
RulePath = "/usr/local/nginx/conf/waf/wafconf/"
|
RulePath = "/app/openresty-xwjr/nginx/conf/waf/wafconf/"
|
||||||
attacklog = "on"
|
attacklog = "on"
|
||||||
logdir = "/usr/local/nginx/logs/hack/"
|
logdir = "/var/log/nginx/hack/"
|
||||||
UrlDeny="on"
|
UrlDeny="on"
|
||||||
Redirect="on"
|
Redirect="on"
|
||||||
CookieMatch="on"
|
CookieMatch="on"
|
||||||
postMatch="on"
|
postMatch="on"
|
||||||
whiteModule="on"
|
whiteModule="on"
|
||||||
black_fileExt={"php","jsp"}
|
black_fileExt={"php","jsp"}
|
||||||
ipWhitelist={"127.0.0.1"}
|
uriWhitelist={"assets", "ccc"}
|
||||||
ipBlocklist={"1.0.0.1"}
|
path403 = "403"
|
||||||
CCDeny="on"
|
CCDeny="on"
|
||||||
CCrate="100/60"
|
CCrate="240/60"
|
||||||
html=[[
|
html=[[
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml"><head>
|
<!DOCTYPE html>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
<html>
|
||||||
<title>网站防火墙</title>
|
<head>
|
||||||
<style>
|
<meta charset="utf-8">
|
||||||
p {
|
<meta http-equiv="refresh" content="0.1;url=/403">
|
||||||
line-height:20px;
|
<script>window.location.href="/403";<script>
|
||||||
}
|
|
||||||
ul{ list-style-type:none;}
|
|
||||||
li{ list-style-type:none;}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
|
<body>
|
||||||
<body style=" padding:0; margin:0; font:14px/1.5 Microsoft Yahei, 宋体,sans-serif; color:#555;">
|
<h1>WARNING</h1>
|
||||||
|
<body>
|
||||||
<div style="margin: 0 auto; width:1000px; padding-top:70px; overflow:hidden;">
|
<html>
|
||||||
|
]]
|
||||||
|
html503=[[
|
||||||
<div style="width:600px; float:left;">
|
<!DOCTYPE html>
|
||||||
<div style=" height:40px; line-height:40px; color:#fff; font-size:16px; overflow:hidden; background:#6bb3f6; padding-left:20px;">网站防火墙 </div>
|
<html>
|
||||||
<div style="border:1px dashed #cdcece; border-top:none; font-size:14px; background:#fff; color:#555; line-height:24px; height:220px; padding:20px 20px 0 20px; overflow-y:auto;background:#f3f7f9;">
|
<head>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; color:#fc4f03;">您的请求带有不合法参数,已被网站管理员设置拦截!</span></p>
|
<meta charset="utf-8">
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">可能原因:您提交的内容包含危险的攻击请求</p>
|
<meta http-equiv="refresh" content="0.1;url=/503">
|
||||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:1; text-indent:0px;">如何解决:</p>
|
<script>window.location.href="/503";<script>
|
||||||
<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1)检查提交内容;</li>
|
</head>
|
||||||
<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">2)如网站托管,请联系空间提供商;</li>
|
<body>
|
||||||
<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">3)普通网站访客,请联系网站管理员;</li></ul>
|
<h1>WARNING</h1>
|
||||||
</div>
|
<body>
|
||||||
</div>
|
<html>
|
||||||
</div>
|
|
||||||
</body></html>
|
|
||||||
]]
|
]]
|
||||||
|
|
126
init.lua
126
init.lua
|
@ -15,14 +15,24 @@ attacklog = optionIsOn(attacklog)
|
||||||
CCDeny = optionIsOn(CCDeny)
|
CCDeny = optionIsOn(CCDeny)
|
||||||
Redirect=optionIsOn(Redirect)
|
Redirect=optionIsOn(Redirect)
|
||||||
function getClientIp()
|
function getClientIp()
|
||||||
IP = ngx.req.get_headers()["X-Real-IP"]
|
IP = ngx.req.get_headers()["X-Real-IP"]
|
||||||
if IP == nil then
|
if IP == nil then
|
||||||
IP = ngx.var.remote_addr
|
IP = ngx.var.remote_addr
|
||||||
end
|
end
|
||||||
if IP == nil then
|
if IP == nil then
|
||||||
IP = "unknown"
|
IP = "unknown"
|
||||||
end
|
end
|
||||||
return IP
|
return IP
|
||||||
|
end
|
||||||
|
function getSLBIP()
|
||||||
|
IP = ngx.req.get_headers()["x_forwarded_for"]
|
||||||
|
if IP == nil then
|
||||||
|
IP = ngx.var.remote_addr
|
||||||
|
end
|
||||||
|
if IP == nil then
|
||||||
|
IP = "unknown"
|
||||||
|
end
|
||||||
|
return IP
|
||||||
end
|
end
|
||||||
function write(logfile,msg)
|
function write(logfile,msg)
|
||||||
local fd = io.open(logfile,"ab")
|
local fd = io.open(logfile,"ab")
|
||||||
|
@ -34,13 +44,14 @@ end
|
||||||
function log(method,url,data,ruletag)
|
function log(method,url,data,ruletag)
|
||||||
if attacklog then
|
if attacklog then
|
||||||
local realIp = getClientIp()
|
local realIp = getClientIp()
|
||||||
|
local xTransIP = getSLBIP()
|
||||||
local ua = ngx.var.http_user_agent
|
local ua = ngx.var.http_user_agent
|
||||||
local servername=ngx.var.server_name
|
local servername=ngx.var.server_name
|
||||||
local time=ngx.localtime()
|
local time=ngx.localtime()
|
||||||
if ua then
|
if ua then
|
||||||
line = realIp.." ["..time.."] \""..method.." "..servername..url.."\" \""..data.."\" \""..ua.."\" \""..ruletag.."\"\n"
|
line = realIp.." "..xTransIP.." ["..time.."] \""..method.." "..servername..url.."\" \""..data.."\" \""..ua.."\" \""..ruletag.."\"\n"
|
||||||
else
|
else
|
||||||
line = realIp.." ["..time.."] \""..method.." "..servername..url.."\" \""..data.."\" - \""..ruletag.."\"\n"
|
line = realIp.." "..xTransIP.." ["..time.."] \""..method.." "..servername..url.."\" \""..data.."\" - \""..ruletag.."\"\n"
|
||||||
end
|
end
|
||||||
local filename = logpath..'/'..servername.."_"..ngx.today().."_sec.log"
|
local filename = logpath..'/'..servername.."_"..ngx.today().."_sec.log"
|
||||||
write(filename,line)
|
write(filename,line)
|
||||||
|
@ -67,6 +78,13 @@ wturlrules=read_rule('whiteurl')
|
||||||
postrules=read_rule('post')
|
postrules=read_rule('post')
|
||||||
ckrules=read_rule('cookie')
|
ckrules=read_rule('cookie')
|
||||||
|
|
||||||
|
function getWhiteList()
|
||||||
|
return read_rule("ipwhitelist")
|
||||||
|
end
|
||||||
|
|
||||||
|
function getBlackList()
|
||||||
|
return read_rule("ipblacklist")
|
||||||
|
end
|
||||||
|
|
||||||
function say_html()
|
function say_html()
|
||||||
if Redirect then
|
if Redirect then
|
||||||
|
@ -77,13 +95,23 @@ function say_html()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function say_html_503()
|
||||||
|
if Redirect then
|
||||||
|
ngx.header.content_type = "text/html"
|
||||||
|
ngx.status = ngx.HTTP_SERVICE_UNAVAILABLE
|
||||||
|
ngx.say(html503)
|
||||||
|
ngx.exit(ngx.status)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function whiteurl()
|
function whiteurl()
|
||||||
if WhiteCheck then
|
if WhiteCheck then
|
||||||
if wturlrules ~=nil then
|
if wturlrules ~=nil then
|
||||||
for _,rule in pairs(wturlrules) do
|
for _,rule in pairs(wturlrules) do
|
||||||
if ngxmatch(ngx.var.uri,rule,"isjo") then
|
if ngxmatch(ngx.var.uri,rule,"isjo") then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -95,17 +123,17 @@ function fileExtCheck(ext)
|
||||||
if ext then
|
if ext then
|
||||||
for rule in pairs(items) do
|
for rule in pairs(items) do
|
||||||
if ngx.re.match(ext,rule,"isjo") then
|
if ngx.re.match(ext,rule,"isjo") then
|
||||||
log('POST',ngx.var.request_uri,"-","file attack with ext "..ext)
|
log('POST',ngx.var.request_uri,"-","file attack with ext "..ext)
|
||||||
say_html()
|
say_html()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
function Set (list)
|
function Set (list)
|
||||||
local set = {}
|
local set = {}
|
||||||
for _, l in ipairs(list) do set[l] = true end
|
for _, l in ipairs(list) do set[l] = true end
|
||||||
return set
|
return set
|
||||||
end
|
end
|
||||||
|
|
||||||
function args()
|
function args()
|
||||||
|
@ -127,7 +155,6 @@ function args()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function url()
|
function url()
|
||||||
if UrlDeny then
|
if UrlDeny then
|
||||||
for _,rule in pairs(urlrules) do
|
for _,rule in pairs(urlrules) do
|
||||||
|
@ -148,7 +175,7 @@ function ua()
|
||||||
if rule ~="" and ngxmatch(ua,rule,"isjo") then
|
if rule ~="" and ngxmatch(ua,rule,"isjo") then
|
||||||
log('UA',ngx.var.request_uri,"-",rule)
|
log('UA',ngx.var.request_uri,"-",rule)
|
||||||
say_html()
|
say_html()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -171,7 +198,7 @@ function cookie()
|
||||||
if rule ~="" and ngxmatch(ck,rule,"isjo") then
|
if rule ~="" and ngxmatch(ck,rule,"isjo") then
|
||||||
log('Cookie',ngx.var.request_uri,"-",rule)
|
log('Cookie',ngx.var.request_uri,"-",rule)
|
||||||
say_html()
|
say_html()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -180,6 +207,17 @@ end
|
||||||
|
|
||||||
function denycc()
|
function denycc()
|
||||||
if CCDeny then
|
if CCDeny then
|
||||||
|
-- Yep, use wafconfig
|
||||||
|
ccconf = read_rule("ccrate")
|
||||||
|
if next(ccconf) ~= nil then
|
||||||
|
for _, conf in pairs(ccconf) do
|
||||||
|
CCrate = conf
|
||||||
|
conf = nil
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ccconf = nil
|
||||||
|
-- Done
|
||||||
local uri=ngx.var.uri
|
local uri=ngx.var.uri
|
||||||
CCcount=tonumber(string.match(CCrate,'(.*)/'))
|
CCcount=tonumber(string.match(CCrate,'(.*)/'))
|
||||||
CCseconds=tonumber(string.match(CCrate,'/(.*)'))
|
CCseconds=tonumber(string.match(CCrate,'/(.*)'))
|
||||||
|
@ -188,10 +226,13 @@ function denycc()
|
||||||
local req,_=limit:get(token)
|
local req,_=limit:get(token)
|
||||||
if req then
|
if req then
|
||||||
if req > CCcount then
|
if req > CCcount then
|
||||||
ngx.exit(503)
|
-- ngx.say(html503)
|
||||||
|
-- ngx.exit(503)
|
||||||
|
log('CC',ngx.var.request_uri,"-","We are under attack!")
|
||||||
|
say_html_503()
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
limit:incr(token,1)
|
limit:incr(token,1)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
limit:set(token,1,CCseconds)
|
limit:set(token,1,CCseconds)
|
||||||
|
@ -219,6 +260,7 @@ function get_boundary()
|
||||||
end
|
end
|
||||||
|
|
||||||
function whiteip()
|
function whiteip()
|
||||||
|
ipWhitelist = getWhiteList()
|
||||||
if next(ipWhitelist) ~= nil then
|
if next(ipWhitelist) ~= nil then
|
||||||
for _,ip in pairs(ipWhitelist) do
|
for _,ip in pairs(ipWhitelist) do
|
||||||
if getClientIp()==ip then
|
if getClientIp()==ip then
|
||||||
|
@ -226,17 +268,39 @@ function whiteip()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function blockip()
|
function blockip()
|
||||||
if next(ipBlocklist) ~= nil then
|
ipBlocklist = getBlackList()
|
||||||
for _,ip in pairs(ipBlocklist) do
|
if next(ipBlocklist) ~= nil then
|
||||||
if getClientIp()==ip then
|
for _,ip in pairs(ipBlocklist) do
|
||||||
ngx.exit(403)
|
if getClientIp()==ip then
|
||||||
return true
|
if path403 == nil then
|
||||||
end
|
path403 = "403"
|
||||||
end
|
end
|
||||||
end
|
if string.match(ngx.var.request_uri, '/(.*)') ~= path403 then
|
||||||
return false
|
p = string.match(ngx.var.request_uri, '/([a-zA-Z0-9]*)')
|
||||||
|
if next(uriWhitelist) ~= nil and p ~= nil then
|
||||||
|
deny = true
|
||||||
|
for _,uri in pairs(uriWhitelist) do
|
||||||
|
if ngx.re.match(p,uri,"isjo") then
|
||||||
|
deny = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if deny == true then
|
||||||
|
log('DENY',ngx.var.request_uri,"-","GO HELL!")
|
||||||
|
say_html()
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
2
ngx.conf
2
ngx.conf
|
@ -1,4 +1,4 @@
|
||||||
lua_package_path "waf/?.lua";
|
lua_package_path "/app/openresty-xwjr/nginx/conf/waf/?.lua";
|
||||||
lua_shared_dict limit 10m;
|
lua_shared_dict limit 10m;
|
||||||
init_by_lua_file conf/waf/init.lua;
|
init_by_lua_file conf/waf/init.lua;
|
||||||
access_by_lua_file conf/waf/waf.lua;
|
access_by_lua_file conf/waf/waf.lua;
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
\:\$
|
\:\$
|
||||||
\$\{
|
\$\{
|
||||||
select.+(from|limit)
|
select.+(from|limit)
|
||||||
|
delete from
|
||||||
|
update.+set.+\=
|
||||||
(?:(union(.*?)select))
|
(?:(union(.*?)select))
|
||||||
having|rongjitest
|
having|rongjitest
|
||||||
sleep\((\s*)(\d*)(\s*)\)
|
sleep\((\s*)(\d*)(\s*)\)
|
||||||
|
@ -20,3 +22,7 @@ java\.lang
|
||||||
\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[
|
\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[
|
||||||
\<(iframe|script|body|img|layer|div|meta|style|base|object|input)
|
\<(iframe|script|body|img|layer|div|meta|style|base|object|input)
|
||||||
(onmouseover|onerror|onload)\=
|
(onmouseover|onerror|onload)\=
|
||||||
|
drop (table|database).+
|
||||||
|
truncate table
|
||||||
|
insert into.+(select|values)
|
||||||
|
create (table|database)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
240/60
|
|
@ -2,6 +2,8 @@
|
||||||
\:\$
|
\:\$
|
||||||
\$\{
|
\$\{
|
||||||
select.+(from|limit)
|
select.+(from|limit)
|
||||||
|
delete from
|
||||||
|
update.+set.+\=
|
||||||
(?:(union(.*?)select))
|
(?:(union(.*?)select))
|
||||||
having|rongjitest
|
having|rongjitest
|
||||||
sleep\((\s*)(\d*)(\s*)\)
|
sleep\((\s*)(\d*)(\s*)\)
|
||||||
|
@ -18,3 +20,7 @@ xwork\.MethodAccessor
|
||||||
(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/
|
(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/
|
||||||
java\.lang
|
java\.lang
|
||||||
\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[
|
\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[
|
||||||
|
drop (table|database).+
|
||||||
|
truncate table
|
||||||
|
insert into.+(select|values)
|
||||||
|
create (table|database)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
127.0.0.1
|
|
@ -1,4 +1,6 @@
|
||||||
select.+(from|limit)
|
select.+(from|limit)
|
||||||
|
delete from
|
||||||
|
update.+set.+\=
|
||||||
(?:(union(.*?)select))
|
(?:(union(.*?)select))
|
||||||
having|rongjitest
|
having|rongjitest
|
||||||
sleep\((\s*)(\d*)(\s*)\)
|
sleep\((\s*)(\d*)(\s*)\)
|
||||||
|
@ -17,3 +19,7 @@ java\.lang
|
||||||
\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[
|
\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[
|
||||||
\<(iframe|script|body|img|layer|div|meta|style|base|object|input)
|
\<(iframe|script|body|img|layer|div|meta|style|base|object|input)
|
||||||
(onmouseover|onerror|onload)\=
|
(onmouseover|onerror|onload)\=
|
||||||
|
drop (table|database).+
|
||||||
|
truncate table
|
||||||
|
insert into.+(select|values)
|
||||||
|
create (table|database)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
(HTTrack|harvest|audit|dirbuster|pangolin|nmap|sqln|-scan|hydra|Parser|libwww|BBBike|sqlmap|w3af|owasp|Nikto|fimap|havij|PycURL|zmeu|BabyKrokodil|netsparker|httperf|bench| SF/)
|
(HTTrack|harvest|audit|dirbuster|pangolin|nmap|sqln|-scan|hydra|Parser|libwww|BBBike|sqlmap|w3af|owasp|Nikto|fimap|havij|PycURL|zmeu|BabyKrokodil|netsparker|httperf| SF/)
|
||||||
|
|
Loading…
Reference in New Issue