Mini Shell
local ipset = require "ipset_message_pb"
local ipset_socket = "unix:/var/run/imunify360/libiplists-daemon.sock"
local function write_size(little_endian, format, ...)
local res = ''
local values = {...}
for i=1,#format do
local size = tonumber(format:sub(i,i))
local value = values[i]
local str = ""
for j=1,size do
str = str .. string.char(value % 256)
value = math.floor(value / 256)
end
if not little_endian then
str = string.reverse(str)
end
res = res .. str
end
return res
end
local function read_size(big_endian, format, ...)
values = {...}
local total = 0
for i=1,#format do
local size = tonumber(format:sub(i,i))
local value = values[i]
if not big_endian then
value = value:reverse()
end
local res = 0
for j=1,size do
res = res * 256 + string.byte(value:sub(j,j))
print(res)
end
total = total + res
end
return total
end
local function composeMessage(ip)
local msg = ipset.Request()
msg.ip = ngx.var.remote_addr
msg.ua = "-"
msg.url = "-"
msg.uid = "-"
msg.captcha = "-"
msg.host = "-"
msg.proxyname = ngx.var.remote_proxy
msg.port = ngx.var.server_port
msg.realip = ip
if ngx.var.domain_whitelisted == "1" then
msg.wldomain = true
end
local serialized = msg:SerializeToString()
return write_size(false, "2", string.len(serialized)) .. serialized
end
local function decomposeMessage(pb_msg)
local status_map = {
[0] = "NOT_FOUND",
[10] = "WHITE",
[11] = "REMOTE_PROXY",
[12] = "WHITE_STATIC",
[20] = "BLACK",
[21] = "COUNTRY_BLACK",
[22] = "BLACK_LOCAL",
[30] = "GRAY",
[40] = "SPLASH"
}
local msg = ipset.Response()
msg:ParseFromString(pb_msg)
if msg == nil then
return {["ip"] = nil, ["verdict"] = "ERROR"}
end
local verdict = status_map[msg.action]
if verdict == nil and msg.status == 1 then
return {["ip"] = msg.ip, ["verdict"] = "ERROR"}
end
return {["ip"] = msg.ip, ["verdict"] = verdict}
end
local function query_peer(ip)
local sock = ngx.socket.tcp()
sock:settimeout(1000)
local ok, err = sock:connect(ipset_socket)
if not ok then
ngx.log(ngx.ERR, "Could not connect to ipset socket: ", err)
return
end
local sent, err = sock:send(composeMessage(ip))
if not sent then
ngx.log(ngx.ERR, "Could not send to ipset socket: ", err)
return
end
local raw_size, err = sock:receive(2)
if not raw_size then
ngx.log(ngx.ERR, "Could not read size from ipset socket: ", err)
return
end
local expected_size = read_size(true, "2", raw_size)
local data, err = sock:receive(expected_size)
if not data then
ngx.log(ngx.ERR, "Could not read data from ipset socket: ", err)
return
end
sock:close()
return decomposeMessage(data)
end
local function check()
local remote_addr = ngx.var.remote_addr
if remote_addr == "127.0.0.1" or remote_addr == "::1" then
ngx.var.webshield_ip_status = "NOT_FOUND"
return
end
local remote_address = ngx.var.wsuserip or remote_addr
local response = query_peer(remote_address)
if response == nil then
ngx.log(ngx.WARN, "Got empty response from IPSET daemon")
ngx.var.webshield_ip_status = "NOT_FOUND"
return
end
ngx.var.webshield_ip_status = response.verdict
end
if ngx.var.access_check_enabled == "0" then
return check()
end
Zerion Mini Shell 1.0