mirror of https://github.com/1Panel-dev/1Panel
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
4.6 KiB
184 lines
4.6 KiB
local lib = require "lib"
|
|
local file_utils = require "file"
|
|
local config = require "config"
|
|
local cc = require "cc"
|
|
local utils = require "utils"
|
|
local cjson = require "cjson"
|
|
|
|
local ipairs = ipairs
|
|
local sub_str = string.sub
|
|
local find_str = string.find
|
|
local split_str = utils.split
|
|
local encode = cjson.encode
|
|
local read_file2table = file_utils.read_file2table
|
|
local tonumber = tonumber
|
|
local date = os.date
|
|
local format_str = string.format
|
|
|
|
local function get_website_key()
|
|
local s_name = ngx.var.server_name
|
|
local website_key = ngx.shared.waf:get(s_name)
|
|
if website_key then
|
|
return website_key
|
|
end
|
|
local websites = read_file2table(config.config_dir .. '/websites.json')
|
|
if not websites then
|
|
return s_name
|
|
end
|
|
for _, v in ipairs(websites)
|
|
do
|
|
for _, domain in ipairs(v['domains'])
|
|
do
|
|
if s_name == domain then
|
|
ngx.shared.waf:set(s_name, v['key'], 3600)
|
|
return v['key']
|
|
end
|
|
end
|
|
end
|
|
if s_name == '_' then
|
|
s_name = "unknown"
|
|
end
|
|
return s_name
|
|
end
|
|
|
|
|
|
|
|
local function init()
|
|
local ip = utils.get_real_ip()
|
|
ngx.ctx.ip = ip
|
|
local ua = utils.get_header("user-agent")
|
|
if not ua then
|
|
ua = ""
|
|
end
|
|
|
|
ngx.ctx.ua = ua
|
|
ngx.ctx.ip_location = utils.get_ip_location(ip)
|
|
ngx.ctx.website_key = get_website_key()
|
|
ngx.ctx.method = ngx.req.get_method()
|
|
ngx.ctx.content_type = utils.get_header("content-type")
|
|
if ngx.ctx.content_type then
|
|
ngx.ctx.content_length = tonumber(utils.get_header("content-length"))
|
|
end
|
|
ngx.ctx.today = date("%Y-%m-%d")
|
|
end
|
|
|
|
local function return_js(js_type)
|
|
ngx.header.content_type = "text/html;charset=utf8"
|
|
ngx.header.Cache_Control = "no-cache"
|
|
local host = ngx.var.scheme .. "://" .. ngx.var.host
|
|
local set_access_url = host .. "/set_access_token"
|
|
local secret = config.get_secret()
|
|
local key = ngx.md5(ngx.ctx.ip .. ngx.var.server_name .. ngx.ctx.website_key
|
|
.. ngx.ctx.ua .. ngx.ctx.today .. secret)
|
|
local value = ngx.md5(ngx.time() .. ngx.ctx.ip)
|
|
local js = config.get_html_res(js_type)
|
|
ngx.say(format_str(js, set_access_url, key, value))
|
|
ngx.status = 200
|
|
ngx.exit(200)
|
|
end
|
|
|
|
local function return_json(data)
|
|
ngx.header.content_type = "application/json;"
|
|
ngx.header.Cache_Control = "no-cache"
|
|
ngx.status = 200
|
|
ngx.say(data)
|
|
ngx.exit(200)
|
|
end
|
|
|
|
local function waf_api()
|
|
local uri = ngx.var.uri
|
|
local prefix = sub_str(uri, 1, 15)
|
|
if find_str(prefix, "/set_access_token") then
|
|
local kvs = split_str(uri, "-")
|
|
if kvs[2] and kvs[3] then
|
|
cc.set_access_token(kvs[2], kvs[3])
|
|
else
|
|
ngx.exit(444)
|
|
end
|
|
end
|
|
if uri == "/slide_check_" .. ngx.md5(ngx.ctx.ip) .. ".js" then
|
|
ngx.ctx.is_waf_url = true
|
|
return_js("slide_js")
|
|
end
|
|
|
|
if uri == "/5s_check_" .. ngx.md5(ngx.ctx.ip) .. ".js" then
|
|
ngx.ctx.is_waf_url = true
|
|
return_js("five_second_js")
|
|
end
|
|
local method = ngx.req.get_method()
|
|
if method ~= 'POST' then
|
|
return false
|
|
end
|
|
if ngx.var.remote_addr ~= '127.0.0.1' then
|
|
return false
|
|
end
|
|
ngx.req.read_body()
|
|
local body_data = ngx.req.get_body_data()
|
|
if not body_data then
|
|
return false
|
|
end
|
|
ngx.log(ngx.ERR,"1111")
|
|
local args
|
|
if body_data then
|
|
args = cjson.decode(body_data)
|
|
end
|
|
ngx.log(ngx.ERR,"2222")
|
|
if args == nil or args.token == nil then
|
|
return false
|
|
end
|
|
ngx.log(ngx.ERR,"token",args.token)
|
|
ngx.log(ngx.ERR,"config token",config.get_token())
|
|
if args.token ~= config.get_token() then
|
|
return false
|
|
end
|
|
ngx.ctx.is_waf_url = true
|
|
if uri == '/reload_waf_config' then
|
|
config.load_config_file()
|
|
ngx.exit(200)
|
|
end
|
|
if uri == '/get_black_ip' then
|
|
--TODO 从 redis 获取黑名单
|
|
local data = ngx.shared.waf_black_ip:get_keys(0)
|
|
return_json(encode(data))
|
|
end
|
|
end
|
|
|
|
|
|
if config.is_waf_on() then
|
|
init()
|
|
waf_api()
|
|
|
|
if ngx.ctx.website_key == "unknown" then
|
|
ngx.exit(403)
|
|
return
|
|
end
|
|
|
|
if lib.is_white_ip() then
|
|
return true
|
|
end
|
|
lib.black_ip()
|
|
lib.default_ip_black()
|
|
|
|
if lib.is_white_ua() then
|
|
return true
|
|
end
|
|
lib.black_ua()
|
|
lib.default_ua_black()
|
|
|
|
--lib.cc_url()
|
|
if lib.is_white_url() then
|
|
return true
|
|
end
|
|
lib.black_url()
|
|
lib.default_url_black()
|
|
|
|
lib.allow_location_check()
|
|
lib.method_check()
|
|
lib.acl()
|
|
lib.cc()
|
|
--lib.bot_check()
|
|
lib.args_check()
|
|
lib.cookie_check()
|
|
lib.post_check()
|
|
lib.header_check()
|
|
end |