Add checkcode
parent
855064926c
commit
d9198e1812
20
README.md
20
README.md
|
@ -1,5 +1,5 @@
|
||||||
### ngx_lua_waf
|
### ngx_lua_waf
|
||||||
ngx_lua_waf是一个基于lua-nginx-module的web应用防火墙
|
ngx_lua_waf是一个基于lua-nginx-module的web应用防火墙, 支持验证码验证
|
||||||
|
|
||||||
### OneinStack启用ngx_lua_waf
|
### OneinStack启用ngx_lua_waf
|
||||||
```
|
```
|
||||||
|
@ -26,6 +26,7 @@ export LUAJIT_INC=/usr/local/include/luajit-2.1
|
||||||
sed -i "s@^nginx_modules_options=.*@nginx_modules_options='--with-ld-opt=-Wl,-rpath,/usr/local/lib --add-module=../lua-nginx-module --add-module=../ngx_devel_kit'@" options.conf
|
sed -i "s@^nginx_modules_options=.*@nginx_modules_options='--with-ld-opt=-Wl,-rpath,/usr/local/lib --add-module=../lua-nginx-module --add-module=../ngx_devel_kit'@" options.conf
|
||||||
./install.sh --nginx_option 1
|
./install.sh --nginx_option 1
|
||||||
|
|
||||||
|
### 全局nginx新增waf
|
||||||
cat > /usr/local/nginx/conf/waf.conf << EOF
|
cat > /usr/local/nginx/conf/waf.conf << EOF
|
||||||
lua_shared_dict limit 20m;
|
lua_shared_dict limit 20m;
|
||||||
lua_package_path "/usr/local/nginx/conf/waf/?.lua;;";
|
lua_package_path "/usr/local/nginx/conf/waf/?.lua;;";
|
||||||
|
@ -36,6 +37,23 @@ EOF
|
||||||
#vi /usr/local/nginx/conf/nginx.conf
|
#vi /usr/local/nginx/conf/nginx.conf
|
||||||
#include vhost/*.conf;下一行新增,如下
|
#include vhost/*.conf;下一行新增,如下
|
||||||
include waf.conf;
|
include waf.conf;
|
||||||
|
|
||||||
|
### 单网站新增waf(推荐)
|
||||||
|
cat > /usr/local/nginx/conf/waf.conf << EOF
|
||||||
|
lua_shared_dict limit 20m;
|
||||||
|
lua_package_path "/usr/local/nginx/conf/waf/?.lua;;";
|
||||||
|
init_by_lua_file "/usr/local/nginx/conf/waf/init.lua";
|
||||||
|
EOF
|
||||||
|
|
||||||
|
#vi /usr/local/nginx/conf/vhost/www.example.com.conf
|
||||||
|
#location ~ [^/]\.php(/|$) {下一行新增,如下
|
||||||
|
access_by_lua_file "/usr/local/nginx/conf/waf/access.lua";
|
||||||
|
#注意:wordpress URL改成ngx.var.request_uri
|
||||||
|
66 local ATTACK_URL = ngx.var.host .. ngx.var.uri
|
||||||
|
67 -- local ATTACK_URL = ngx.var.host .. ngx.var.request_uri
|
||||||
|
#改成:
|
||||||
|
66 -- local ATTACK_URL = ngx.var.host .. ngx.var.uri
|
||||||
|
67 local ATTACK_URL = ngx.var.host .. ngx.var.request_uri
|
||||||
```
|
```
|
||||||
|
|
||||||
### Copyright
|
### Copyright
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
require 'init'
|
require "init"
|
||||||
|
|
||||||
function waf_main()
|
local function waf_main()
|
||||||
if black_ip_check() then
|
if black_ip_check() then
|
||||||
elseif white_ip_check() then
|
elseif white_ip_check() then
|
||||||
elseif white_url_check() then
|
elseif white_url_check() then
|
||||||
|
|
75
init.lua
75
init.lua
|
@ -1,20 +1,20 @@
|
||||||
--WAF Action
|
-- WAF Action
|
||||||
require 'config'
|
require "config"
|
||||||
require 'lib'
|
require "lib"
|
||||||
|
|
||||||
--args
|
-- args
|
||||||
local rulematch = ngx.re.find
|
local rulematch = ngx.re.find
|
||||||
local unescape = ngx.unescape_uri
|
local unescape = ngx.unescape_uri
|
||||||
|
|
||||||
--allow white ip
|
-- allow white ip
|
||||||
function white_ip_check()
|
function white_ip_check()
|
||||||
if config_white_ip_check == "on" then
|
if config_white_ip_check == "on" then
|
||||||
local IP_WHITE_RULE = get_rule('whiteip')
|
local IP_WHITE_RULE = get_rule("whiteip")
|
||||||
local WHITE_IP = get_client_ip()
|
local WHITE_IP = get_client_ip()
|
||||||
if IP_WHITE_RULE ~= nil then
|
if IP_WHITE_RULE ~= nil then
|
||||||
for _,rule in pairs(IP_WHITE_RULE) do
|
for _,rule in pairs(IP_WHITE_RULE) do
|
||||||
if rule ~= "" and rulematch(WHITE_IP,rule,"jo") then
|
if rule ~= "" and rulematch(WHITE_IP,rule,"jo") then
|
||||||
--log_record('White_IP',ngx.var_request_uri,"_","_")
|
-- log_record("White_IP",ngx.var_request_uri,"_","_")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -22,17 +22,18 @@ function white_ip_check()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--deny black ip
|
-- deny black ip
|
||||||
function black_ip_check()
|
function black_ip_check()
|
||||||
if config_black_ip_check == "on" then
|
if config_black_ip_check == "on" then
|
||||||
local IP_BLACK_RULE = get_rule('blackip')
|
local IP_BLACK_RULE = get_rule("blackip")
|
||||||
local BLACK_IP = get_client_ip()
|
local BLACK_IP = get_client_ip()
|
||||||
if IP_BLACK_RULE ~= nil then
|
if IP_BLACK_RULE ~= nil then
|
||||||
for _,rule in pairs(IP_BLACK_RULE) do
|
for _,rule in pairs(IP_BLACK_RULE) do
|
||||||
if rule ~= "" and rulematch(BLACK_IP,rule,"jo") then
|
if rule ~= "" and rulematch(BLACK_IP,rule,"jo") then
|
||||||
log_record('BlackList_IP',ngx.var_request_uri,"_","_")
|
log_record('BlackList_IP',ngx.var_request_uri,"_","_")
|
||||||
if config_waf_enable == "on" then
|
if config_waf_enable == "on" then
|
||||||
ngx.exit(403)
|
ngx.header.content_type = "text/html"
|
||||||
|
ngx.say('Your IP blacklist, Please contact the administrator! ')
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -41,10 +42,10 @@ function black_ip_check()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--allow white url
|
-- allow white url
|
||||||
function white_url_check()
|
function white_url_check()
|
||||||
if config_white_url_check == "on" then
|
if config_white_url_check == "on" then
|
||||||
local URL_WHITE_RULES = get_rule('whiteurl')
|
local URL_WHITE_RULES = get_rule("whiteurl")
|
||||||
local REQ_URI = string.lower(ngx.var.request_uri)
|
local REQ_URI = string.lower(ngx.var.request_uri)
|
||||||
if URL_WHITE_RULES ~= nil then
|
if URL_WHITE_RULES ~= nil then
|
||||||
for _,rule in pairs(URL_WHITE_RULES) do
|
for _,rule in pairs(URL_WHITE_RULES) do
|
||||||
|
@ -56,23 +57,31 @@ function white_url_check()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--deny cc attack
|
-- deny cc attack
|
||||||
function cc_attack_check()
|
function cc_attack_check()
|
||||||
if config_cc_check == "on" then
|
if config_cc_check == "on" then
|
||||||
local USER_AGENT = get_user_agent()
|
local USER_AGENT = get_user_agent()
|
||||||
--local ATTACK_URL = ngx.var.host .. ngx.var.request_uri
|
local ARGS = ngx.var.args or ""
|
||||||
|
|
||||||
local ATTACK_URL = ngx.var.host .. ngx.var.uri
|
local ATTACK_URL = ngx.var.host .. ngx.var.uri
|
||||||
|
-- local ATTACK_URL = ngx.var.host .. ngx.var.request_uri
|
||||||
|
-- local ATTACK_URL = ngx.var.host .. ngx.var.uri .. '?' .. ARGS
|
||||||
|
|
||||||
local CC_TOKEN = get_client_ip() .. "." .. ngx.md5(string.lower(ATTACK_URL) .. USER_AGENT)
|
local CC_TOKEN = get_client_ip() .. "." .. ngx.md5(string.lower(ATTACK_URL) .. USER_AGENT)
|
||||||
local limit = ngx.shared.limit
|
local limit = ngx.shared.limit
|
||||||
local CCcount=tonumber(string.match(config_cc_rate,'(.*)/'))
|
local CCcount=tonumber(string.match(config_cc_rate,'(.*)/'))
|
||||||
local CCseconds=tonumber(string.match(config_cc_rate,'/(.*)'))
|
local CCseconds=tonumber(string.match(config_cc_rate,'/(.*)'))
|
||||||
local req,_ = limit:get(CC_TOKEN)
|
local req,_ = limit:get(CC_TOKEN)
|
||||||
if req then
|
if req then
|
||||||
--write('/data/wwwlogs/info.log',CC_TOKEN ..'\t'.. ATTACK_URL .. '\t'.. 'req: ' .. req .. "\n")
|
-- write("/data/wwwlogs/info.log",CC_TOKEN .."\t".. ATTACK_URL .. "\t".. "req: " .. req .."\n")
|
||||||
if req > CCcount then
|
if req > CCcount then
|
||||||
log_record('CC_Attack',ngx.var.request_uri,"-","-")
|
log_record("CC_Attack",ATTACK_URL,"-","-")
|
||||||
if config_waf_enable == "on" then
|
if config_waf_enable == "on" then
|
||||||
ngx.exit(403)
|
local source = ngx.encode_base64(ngx.var.scheme.."://"..ngx.var.host..ngx.var.request_uri)
|
||||||
|
local dest = 'https://oneinstack.com/captcha.html' .. '?continue=' .. source
|
||||||
|
local CCcountcode,_ = math.modf(CCcount/2);
|
||||||
|
limit:set(CC_TOKEN,CCcountcode)
|
||||||
|
ngx.redirect(dest,302)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
limit:incr(CC_TOKEN,1)
|
limit:incr(CC_TOKEN,1)
|
||||||
|
@ -84,15 +93,15 @@ function cc_attack_check()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
--deny cookie
|
-- deny cookie
|
||||||
function cookie_attack_check()
|
function cookie_attack_check()
|
||||||
if config_cookie_check == "on" then
|
if config_cookie_check == "on" then
|
||||||
local COOKIE_RULES = get_rule('cookie')
|
local COOKIE_RULES = get_rule("cookie")
|
||||||
local USER_COOKIE = ngx.var.http_cookie
|
local USER_COOKIE = ngx.var.http_cookie
|
||||||
if USER_COOKIE ~= nil then
|
if USER_COOKIE ~= nil then
|
||||||
for _,rule in pairs(COOKIE_RULES) do
|
for _,rule in pairs(COOKIE_RULES) do
|
||||||
if rule ~="" and rulematch(USER_COOKIE,rule,"jo") then
|
if rule ~="" and rulematch(USER_COOKIE,rule,"jo") then
|
||||||
log_record('Deny_Cookie',ngx.var.request_uri,"-",rule)
|
log_record("Deny_Cookie",ngx.var.request_uri,"-",rule)
|
||||||
if config_waf_enable == "on" then
|
if config_waf_enable == "on" then
|
||||||
waf_output()
|
waf_output()
|
||||||
return true
|
return true
|
||||||
|
@ -104,14 +113,14 @@ function cookie_attack_check()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
--deny url
|
-- deny url
|
||||||
function url_attack_check()
|
function url_attack_check()
|
||||||
if config_url_check == "on" then
|
if config_url_check == "on" then
|
||||||
local URL_RULES = get_rule('blackurl')
|
local URL_RULES = get_rule("blackurl")
|
||||||
local REQ_URI = string.lower(ngx.var.request_uri)
|
local REQ_URI = string.lower(ngx.var.request_uri)
|
||||||
for _,rule in pairs(URL_RULES) do
|
for _,rule in pairs(URL_RULES) do
|
||||||
if rule ~="" and rulematch(REQ_URI,rule,"jo") then
|
if rule ~="" and rulematch(REQ_URI,rule,"jo") then
|
||||||
log_record('Deny_URL',REQ_URI,"-",rule)
|
log_record("Deny_URL",REQ_URI,"-",rule)
|
||||||
if config_waf_enable == "on" then
|
if config_waf_enable == "on" then
|
||||||
waf_output()
|
waf_output()
|
||||||
return true
|
return true
|
||||||
|
@ -122,20 +131,20 @@ function url_attack_check()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
--deny url args
|
-- deny url args
|
||||||
function url_args_attack_check()
|
function url_args_attack_check()
|
||||||
if config_url_args_check == "on" then
|
if config_url_args_check == "on" then
|
||||||
local ARGS_RULES = get_rule('args')
|
local ARGS_RULES = get_rule('args')
|
||||||
for _,rule in pairs(ARGS_RULES) do
|
for _,rule in pairs(ARGS_RULES) do
|
||||||
local REQ_ARGS = ngx.req.get_uri_args()
|
local REQ_ARGS = ngx.req.get_uri_args()
|
||||||
for key, val in pairs(REQ_ARGS) do
|
for key, val in pairs(REQ_ARGS) do
|
||||||
if type(val) == 'table' then
|
if type(val) == "table" then
|
||||||
ARGS_DATA = table.concat(val, " ")
|
local ARGS_DATA = table.concat(val, " ")
|
||||||
else
|
else
|
||||||
ARGS_DATA = val
|
local ARGS_DATA = val
|
||||||
end
|
end
|
||||||
if ARGS_DATA and type(ARGS_DATA) ~= "boolean" and rule ~="" and rulematch(unescape(ARGS_DATA),rule,"jo") then
|
if ARGS_DATA and type(ARGS_DATA) ~= "boolean" and rule ~="" and rulematch(unescape(ARGS_DATA),rule,"jo") then
|
||||||
log_record('Deny_URL_Args',ngx.var.request_uri,"-",rule)
|
log_record("Deny_URL_Args",ngx.var.request_uri,"-",rule)
|
||||||
if config_waf_enable == "on" then
|
if config_waf_enable == "on" then
|
||||||
waf_output()
|
waf_output()
|
||||||
return true
|
return true
|
||||||
|
@ -146,15 +155,15 @@ function url_args_attack_check()
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
--deny user agent
|
-- deny user agent
|
||||||
function user_agent_attack_check()
|
function user_agent_attack_check()
|
||||||
if config_user_agent_check == "on" then
|
if config_user_agent_check == "on" then
|
||||||
local USER_AGENT_RULES = get_rule('useragent')
|
local USER_AGENT_RULES = get_rule("useragent")
|
||||||
local USER_AGENT = ngx.var.http_user_agent
|
local USER_AGENT = ngx.var.http_user_agent
|
||||||
if USER_AGENT ~= nil then
|
if USER_AGENT ~= nil then
|
||||||
for _,rule in pairs(USER_AGENT_RULES) do
|
for _,rule in pairs(USER_AGENT_RULES) do
|
||||||
if rule ~="" and rulematch(USER_AGENT,rule,"jo") then
|
if rule ~="" and rulematch(USER_AGENT,rule,"jo") then
|
||||||
log_record('Deny_USER_AGENT',ngx.var.request_uri,"-",rule)
|
log_record("Deny_USER_AGENT",ngx.var.request_uri,"-",rule)
|
||||||
if config_waf_enable == "on" then
|
if config_waf_enable == "on" then
|
||||||
waf_output()
|
waf_output()
|
||||||
return true
|
return true
|
||||||
|
@ -166,10 +175,10 @@ function user_agent_attack_check()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
--deny post
|
-- deny post
|
||||||
function post_attack_check()
|
function post_attack_check()
|
||||||
if config_post_check == "on" then
|
if config_post_check == "on" then
|
||||||
local POST_RULES = get_rule('post')
|
local POST_RULES = get_rule("post")
|
||||||
for _,rule in pairs(ARGS_RULES) do
|
for _,rule in pairs(ARGS_RULES) do
|
||||||
local POST_ARGS = ngx.req.get_post_args()
|
local POST_ARGS = ngx.req.get_post_args()
|
||||||
end
|
end
|
||||||
|
|
26
lib.lua
26
lib.lua
|
@ -1,9 +1,9 @@
|
||||||
--waf core lib
|
-- waf core lib
|
||||||
require 'config'
|
require "config"
|
||||||
|
|
||||||
--Get the client IP
|
-- Get the client IP
|
||||||
function get_client_ip()
|
function get_client_ip()
|
||||||
CLIENT_IP = ngx.req.get_headers()["X_real_ip"]
|
local CLIENT_IP = ngx.req.get_headers()["X_real_ip"]
|
||||||
if CLIENT_IP == nil then
|
if CLIENT_IP == nil then
|
||||||
CLIENT_IP = ngx.req.get_headers()["X_Forwarded_For"]
|
CLIENT_IP = ngx.req.get_headers()["X_Forwarded_For"]
|
||||||
end
|
end
|
||||||
|
@ -16,24 +16,24 @@ function get_client_ip()
|
||||||
return CLIENT_IP
|
return CLIENT_IP
|
||||||
end
|
end
|
||||||
|
|
||||||
--Get the client user agent
|
-- Get the client user agent
|
||||||
function get_user_agent()
|
function get_user_agent()
|
||||||
USER_AGENT = ngx.var.http_user_agent
|
local USER_AGENT = ngx.var.http_user_agent
|
||||||
if USER_AGENT == nil then
|
if USER_AGENT == nil then
|
||||||
USER_AGENT = "unknown"
|
USER_AGENT = "unknown"
|
||||||
end
|
end
|
||||||
return USER_AGENT
|
return USER_AGENT
|
||||||
end
|
end
|
||||||
|
|
||||||
--Get WAF rule
|
-- Get WAF rule
|
||||||
function get_rule(rulefilename)
|
function get_rule(rulefilename)
|
||||||
local io = require 'io'
|
local io = require "io"
|
||||||
local RULE_PATH = config_rule_dir
|
local RULE_PATH = config_rule_dir
|
||||||
local RULE_FILE = io.open(RULE_PATH..'/'..rulefilename,"r")
|
local RULE_FILE = io.open(RULE_PATH..'/'..rulefilename,"r")
|
||||||
if RULE_FILE == nil then
|
if RULE_FILE == nil then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
RULE_TABLE = {}
|
local RULE_TABLE = {}
|
||||||
for line in RULE_FILE:lines() do
|
for line in RULE_FILE:lines() do
|
||||||
table.insert(RULE_TABLE,line)
|
table.insert(RULE_TABLE,line)
|
||||||
end
|
end
|
||||||
|
@ -41,10 +41,10 @@ function get_rule(rulefilename)
|
||||||
return(RULE_TABLE)
|
return(RULE_TABLE)
|
||||||
end
|
end
|
||||||
|
|
||||||
--WAF log record for json,(use logstash codec => json)
|
-- WAF log record for json,(use logstash codec => json)
|
||||||
function log_record(method,url,data,ruletag)
|
function log_record(method,url,data,ruletag)
|
||||||
local cjson = require("cjson")
|
local cjson = require("cjson")
|
||||||
local io = require 'io'
|
local io = require "io"
|
||||||
local LOG_PATH = config_log_dir
|
local LOG_PATH = config_log_dir
|
||||||
local CLIENT_IP = get_client_ip()
|
local CLIENT_IP = get_client_ip()
|
||||||
local USER_AGENT = get_user_agent()
|
local USER_AGENT = get_user_agent()
|
||||||
|
@ -71,7 +71,7 @@ function log_record(method,url,data,ruletag)
|
||||||
file:close()
|
file:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
--test log
|
-- test log
|
||||||
function write(logfile, msg)
|
function write(logfile, msg)
|
||||||
local fd,err = io.open(logfile,"a+")
|
local fd,err = io.open(logfile,"a+")
|
||||||
if fd == nil then
|
if fd == nil then
|
||||||
|
@ -83,7 +83,7 @@ function write(logfile, msg)
|
||||||
fd:close()
|
fd:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
--WAF return
|
-- WAF return
|
||||||
function waf_output()
|
function waf_output()
|
||||||
if config_waf_output == "redirect" then
|
if config_waf_output == "redirect" then
|
||||||
ngx.redirect(config_waf_redirect_url, 301)
|
ngx.redirect(config_waf_redirect_url, 301)
|
||||||
|
|
Loading…
Reference in New Issue