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.
1Panel/plugins/openresty/waf/lib/utils.lua

186 lines
4.1 KiB

local geoip = require "geoip"
local sub_str = string.sub
local pairs = pairs
local insert_table = table.insert
local tonumber = tonumber
local ipairs = ipairs
local type = type
local find_str = string.find
local gmatch_str = string.gmatch
local pcall = pcall
local cjson = require "cjson"
local _M = {}
function _M.split(input_string, delimiter)
local result = {}
for part in input_string:gmatch("([^" .. delimiter .. "]+)") do
insert_table(result, part)
end
return result
end
function _M.get_cookie_list(cookie_str)
local cookies = {}
for cookie in cookie_str:gmatch("([^;]+)") do
local key, value = cookie:match("^%s*([^=]+)=(.*)$")
if key and value then
cookies[key] = value
end
end
return cookies
end
function _M.unescape_uri(str)
local newStr = str
for t = 1, 2 do
local temp = ngx.unescape_uri(newStr)
if not temp then
break
end
newStr = temp
end
return newStr
end
function _M.get_expire_time()
local localtime = ngx.localtime()
local hour = sub_str(localtime, 12, 13)
local expire_time = (24 - tonumber(hour)) * 3600
return expire_time
end
function _M.get_date_hour()
local localtime = ngx.localtime()
local hour = sub_str(localtime, 1, 13)
return hour
end
function _M.getHours()
local hours = {}
local today = ngx.today()
local hour = nil
for i = 0, 23 do
if i < 10 then
hour = today .. ' 0' .. i
else
hour = today .. ' ' .. i
end
hours[i + 1] = hour
end
return hours
end
function _M.ipv4_to_int(ip)
local ipInt = 0
for i, octet in ipairs({ ip:match("(%d+)%.(%d+)%.(%d+)%.(%d+)") }) do
ipInt = ipInt + tonumber(octet) * 256 ^ (4 - i)
end
return ipInt
end
function _M.is_ipv6(ip)
if find_str(ip, ':') then
return true
end
return false
end
function _M.is_ip_in_array(ip, ipStart, ipEnd)
if ip >= ipStart and ip <= ipEnd then
return true
end
return false
end
function _M.get_real_ip()
local var = ngx.var
local ips = {
var.http_x_forwarded_for,
var.http_proxy_client_ip,
var.http_wl_proxy_client_ip,
var.http_http_client_ip,
var.http_http_x_forwarded_for,
var.remote_addr
}
for _, ip in pairs(ips) do
if ip and ip ~= "" then
if type(ip) == "table" then
ip = ip[1]
end
return ip
end
end
return "unknown"
end
function _M.get_ip_location(ip)
if _M.is_intranet_address(ip) then
return {
country = { ["zh"] = "内网", ["en"] = "Intranet" },
longitude = 0,
latitude = 0,
iso = "Local"
}
else
geoip.init()
local geo_res = geoip.lookup(ip)
local msg = "访问 IP " .. ip
if geo_res.country then
msg = msg .. " 国家 " .. cjson.encode(geo_res.country)
end
if geo_res.province then
msg = msg .. " 省份 " .. cjson.encode(geo_res.province)
end
ngx.log(ngx.ERR, msg)
return geo_res
end
end
function _M.get_header(headerKey)
return ngx.req.get_headers(20000)[headerKey]
end
function _M.get_headers()
return ngx.req.get_headers(20000)
end
function _M.is_intranet_address(ip_addr)
if not ip_addr then
return false
end
if ip_addr == "unknown" then
return false
end
if find_str(ip_addr, ':') then
return false
end
local parts = {}
for part in gmatch_str(ip_addr, "%d+") do
insert_table(parts, tonumber(part))
end
if parts[1] == 10 or
(parts[1] == 192 and parts[2] == 168) or
(parts[1] == 172 and parts[2] >= 16 and parts[2] <= 31) then
return true
else
return false
end
end
function _M.get_wafdb(waf_db_path)
local ok, sqlite3 = pcall(function()
return require "lsqlite3"
end)
if not ok then
return nil
end
return sqlite3.open(waf_db_path)
end
return _M