continue work on refactoring

This commit is contained in:
bunkerity 2023-04-11 18:13:06 +02:00
parent 8c29081577
commit 840c295684
12 changed files with 159 additions and 110 deletions

View File

@ -1,24 +1,22 @@
local datastore = require "datastore"
local utils = require "utils"
local cjson = require "cjson"
local plugins = require "plugins"
local upload = require "resty.upload"
local logger = require "logger"
local datastore = require "bunkerweb.datastore"
local utils = require "bunkerweb.utils"
local cjson = require "cjson"
local upload = require "resty.upload"
local api = { global = { GET = {}, POST = {}, PUT = {}, DELETE = {} } }
local api = { global = { GET = {}, POST = {}, PUT = {}, DELETE = {} } }
api.response = function(self, http_status, api_status, msg)
api.response = function(self, http_status, api_status, msg)
local resp = {}
resp["status"] = api_status
resp["msg"] = msg
return http_status, resp
end
api.global.GET["^/ping$"] = function(api)
api.global.GET["^/ping$"] = function(api)
return api:response(ngx.HTTP_OK, "success", "pong")
end
api.global.POST["^/reload$"] = function(api)
api.global.POST["^/reload$"] = function(api)
local status = os.execute("nginx -s reload")
if status == 0 then
return api:response(ngx.HTTP_OK, "success", "reload successful")
@ -26,7 +24,7 @@ api.global.POST["^/reload$"] = function(api)
return api:response(ngx.HTTP_INTERNAL_SERVER_ERROR, "error", "exit status = " .. tostring(status))
end
api.global.POST["^/stop$"] = function(api)
api.global.POST["^/stop$"] = function(api)
local status = os.execute("nginx -s quit")
if status == 0 then
return api:response(ngx.HTTP_OK, "success", "stop successful")
@ -34,7 +32,7 @@ api.global.POST["^/stop$"] = function(api)
return api:response(ngx.HTTP_INTERNAL_SERVER_ERROR, "error", "exit status = " .. tostring(status))
end
api.global.POST["^/confs$"] = function(api)
api.global.POST["^/confs$"] = function(api)
local tmp = "/var/tmp/bunkerweb/api_" .. ngx.var.uri:sub(2) .. ".tar.gz"
local destination = "/usr/share/bunkerweb/" .. ngx.var.uri:sub(2)
if ngx.var.uri == "/confs" then
@ -80,15 +78,15 @@ api.global.POST["^/confs$"] = function(api)
return api:response(ngx.HTTP_OK, "success", "saved data at " .. destination)
end
api.global.POST["^/data$"] = api.global.POST["^/confs$"]
api.global.POST["^/data$"] = api.global.POST["^/confs$"]
api.global.POST["^/cache$"] = api.global.POST["^/confs$"]
api.global.POST["^/cache$"] = api.global.POST["^/confs$"]
api.global.POST["^/custom_configs$"] = api.global.POST["^/confs$"]
api.global.POST["^/plugins$"] = api.global.POST["^/confs$"]
api.global.POST["^/plugins$"] = api.global.POST["^/confs$"]
api.global.POST["^/unban$"] = function(api)
api.global.POST["^/unban$"] = function(api)
ngx.req.read_body()
local data = ngx.req.get_body_data()
if not data then
@ -107,7 +105,7 @@ api.global.POST["^/unban$"] = function(api)
return api:response(ngx.HTTP_OK, "success", "ip " .. ip["ip"] .. " unbanned")
end
api.global.POST["^/ban$"] = function(api)
api.global.POST["^/ban$"] = function(api)
ngx.req.read_body()
local data = ngx.req.get_body_data()
if not data then
@ -126,7 +124,7 @@ api.global.POST["^/ban$"] = function(api)
return api:response(ngx.HTTP_OK, "success", "ip " .. ip["ip"] .. " banned")
end
api.global.GET["^/bans$"] = function(api)
api.global.GET["^/bans$"] = function(api)
local data = {}
for i, k in ipairs(datastore:keys()) do
if k:find("^bans_ip_") then
@ -147,7 +145,7 @@ api.global.GET["^/bans$"] = function(api)
return api:response(ngx.HTTP_OK, "success", data)
end
api.is_allowed_ip = function(self)
api.is_allowed_ip = function(self)
local data, err = datastore:get("api_whitelist_ip")
if not data then
return false, "can't access api_allowed_ips in datastore"
@ -158,7 +156,7 @@ api.is_allowed_ip = function(self)
return false, "IP is not in API_WHITELIST_IP"
end
api.do_api_call = function(self)
api.do_api_call = function(self)
if self.global[ngx.var.request_method] ~= nil then
for uri, api_fun in pairs(self.global[ngx.var.request_method]) do
if string.match(ngx.var.uri, uri) then
@ -177,7 +175,7 @@ api.do_api_call = function(self)
end
end
end
local list, err = plugins:list()
local list, err = datastore:get("plugins")
if not list then
local status, resp = self:response(ngx.HTTP_INTERNAL_SERVER_ERROR, "error", "can't list loaded plugins : " .. err)
return false, resp["msg"], ngx.HTTP_INTERNAL_SERVER_ERROR, resp

View File

@ -1,6 +1,6 @@
local M = {}
local redis = require "resty.redis"
local utils = require "utils"
local utils = require "bunkerweb.utils"
function M:connect()
-- Instantiate object

View File

@ -76,8 +76,4 @@ helpers.call_plugin = function(plugin, method)
return true, ret
end
helpers.get_plugins = function()
end
return helpers

View File

@ -1,9 +1,13 @@
local M = {}
local errlog = require "ngx.errlog"
local class = require "middleclass"
local logger = class("logger")
function M.log (level, prefix, msg)
errlog.raw_log(level, "[" .. prefix .. "] " .. msg)
function logger:new(prefix)
self.prefix = prefix
end
return M
function logger:log(level, msg)
errlog.raw_log(level, "[" .. self.prefix .. "] " .. msg)
end
return logger

View File

@ -0,0 +1,18 @@
local class = require "middleclass"
local plugin = class("plugin")
function plugin:new(id)
self.id = id
self.logger = require "bunkerweb.logger"
self.logger:new(id)
end
function plugin:get_id()
return self.id
end
function plugin:ret(ret, msg, status)
return {ret = ret, msg = msg, status = status}
end
return plugin

View File

@ -1,11 +1,13 @@
local datastore = require "datastore"
local datastore = require "bunkerweb.datastore"
local ipmatcher = require "resty.ipmatcher"
local cjson = require "cjson"
local resolver = require "resty.dns.resolver"
local mmdb = require "mmdb"
local logger = require "logger"
local mmdb = require "bunkerweb.mmdb"
local logger = require "bunkerweb.logger"
local session = require "resty.session"
logger:new("UTILS")
local utils = {}
utils.set_values = function()
@ -214,7 +216,7 @@ utils.get_integration = function()
end
local ok, err = datastore:set("misc_integration", integration)
if not ok then
logger.log(ngx.ERR, "UTILS", "Can't cache integration to datastore : " .. err)
logger:log(ngx.ERR, "can't cache integration to datastore : " .. err)
end
return integration
end
@ -226,14 +228,14 @@ utils.get_version = function()
end
local f, err = io.open("/usr/share/bunkerweb/VERSION", "r")
if not f then
logger.log(ngx.ERR, "UTILS", "Can't read VERSION file : " .. err)
logger:log(ngx.ERR, "can't read VERSION file : " .. err)
return "unknown"
end
version = f:read("*a")
f:close()
local ok, err = datastore:set("misc_version", version)
if not ok then
logger.log(ngx.ERR, "UTILS", "Can't cache version to datastore : " .. err)
logger:log(ngx.ERR, "can't cache version to datastore : " .. err)
end
return version
end
@ -360,7 +362,7 @@ utils.get_deny_status = function()
end
local status, err = datastore:get("variable_DENY_HTTP_STATUS")
if not status then
logger.log(ngx.ERR, "UTILS", "Can't get DENY_HTTP_STATUS variable " .. err)
logger:log(ngx.ERR, "can't get DENY_HTTP_STATUS variable " .. err)
return 403
end
return tonumber(status)
@ -372,7 +374,7 @@ utils.get_session = function()
end
local _session, err, exists = session.start()
if err then
logger.log(ngx.ERR, "UTILS", "can't start session : " .. err)
logger:log(ngx.ERR, "UTILS", "can't start session : " .. err)
end
ngx.ctx.session = _session
ngx.ctx.session_err = err
@ -390,7 +392,7 @@ utils.save_session = function()
ngx.ctx.session:set_data(ngx.ctx.session_data)
local ok, err = ngx.ctx.session:save()
if err then
logger.log(ngx.ERR, "UTILS", "can't save session : " .. err)
logger:log(ngx.ERR, "can't save session : " .. err)
return false, "can't save session : " .. err
end
ngx.ctx.session_saved = true
@ -411,7 +413,7 @@ end
utils.get_session = function(key)
if ngx.ctx.session and not ngx.ctx.session_err then
return true, "value set", ngx.ctx.session_data[key]
return true, "value get", ngx.ctx.session_data[key]
end
return false, "no session"
end

View File

@ -15,23 +15,24 @@ server {
# check IP and do the API call
access_by_lua_block {
local api = require "api"
local logger = require "logger"
local api = require "bunkerweb.api"
local logger = require "bunkerweb.logger"
logger:new("API")
if not ngx.var.http_host or ngx.var.http_host ~= "{{ API_SERVER_NAME }}" then
logger.log(ngx.WARN, "API", "Wrong Host header from IP " .. ngx.var.remote_addr)
logger.log(ngx.WARN, "wrong Host header from IP " .. ngx.var.remote_addr)
return ngx.exit(ngx.HTTP_CLOSE)
end
local ok, err = api:is_allowed_ip()
if not ok then
logger.log(ngx.WARN, "API", "Can't validate access from IP " .. ngx.var.remote_addr .. " : " .. err)
logger.log(ngx.WARN, "can't validate access from IP " .. ngx.var.remote_addr .. " : " .. err)
return ngx.exit(ngx.HTTP_CLOSE)
end
logger.log(ngx.NOTICE, "API", "Validated access from IP " .. ngx.var.remote_addr)
logger.log(ngx.NOTICE, "validated access from IP " .. ngx.var.remote_addr)
local ok, err, status, resp = api:do_api_call()
if not ok then
logger.log(ngx.WARN, "API", "Call from " .. ngx.var.remote_addr .. " on " .. ngx.var.uri .. " failed : " .. err)
logger.log(ngx.WARN, "call from " .. ngx.var.remote_addr .. " on " .. ngx.var.uri .. " failed : " .. err)
else
logger.log(ngx.NOTICE, "API", "Successful call from " .. ngx.var.remote_addr .. " on " .. ngx.var.uri .. " : " .. err)
logger.log(ngx.NOTICE, "successful call from " .. ngx.var.remote_addr .. " on " .. ngx.var.uri .. " : " .. err)
end
ngx.status = status
ngx.say(resp)

View File

@ -33,46 +33,54 @@ server {
log_by_lua_block {
local utils = require "utils"
local logger = require "logger"
local datastore = require "datastore"
local plugins = require "plugins"
local utils = require "bunkerweb.utils"
local logger = require "bunkerweb.logger"
local datastore = require "bunkerweb.datastore"
logger.log(ngx.INFO, "LOG", "Log phase started")
-- Start log phase
logger:new("LOG-DEFAULT")
datastore:new()
logger:log(ngx.INFO, "log_default phase started")
-- List all plugins
local list, err = plugins:list()
if not list then
logger.log(ngx.ERR, "LOG", "Can't list loaded plugins : " .. err)
list = {}
-- Get plugins
local plugins, err = datastore:get("plugins")
if not plugins then
logger:log(ngx.ERR, "can't get plugins from datastore : " .. err)
return false
end
-- Call log_default method of plugins
for i, plugin in ipairs(list) do
local ret, plugin_lua = pcall(require, plugin.id .. "/" .. plugin.id)
if ret then
local plugin_obj = plugin_lua.new()
if plugin_obj.log_default ~= nil then
logger.log(ngx.INFO, "LOG", "Executing log_default() of " .. plugin.id)
local ok, err = plugin_obj:log_default()
if not ok then
logger.log(ngx.ERR, "LOG", "Error while calling log_default() on plugin " .. plugin.id .. " : " .. err)
else
logger.log(ngx.INFO, "LOG", "Return value from " .. plugin.id .. ".log_default() is : " .. err)
end
-- Call log() methods
logger:log(ngx.INFO, "calling log_default() methods of plugins ...")
for i, plugin in ipairs(plugins) do
local plugin_lua, err = helpers.new_plugin(plugin.id)
if plugin_lua == false then
logger:log(ngx.ERR, err)
else
logger:log(ngx.INFO, err)
end
if plugin_lua ~= nil then
local ok, ret = helpers.call_plugin(plugin_lua, "log_default")
if ok == false then
logger:log(ngx.ERR, ret)
elseif ok == nil then
logger:log(ngx.INFO, ret)
else
logger.log(ngx.INFO, "LOG", "log_default() method not found in " .. plugin.id .. ", skipped execution")
if ret.ret then
logger:log(ngx.INFO, plugin.id .. ":log_default() call successful : " .. ret.msg)
else
logger:log(ngx.ERR, plugin.id .. ":log_default() call failed : " .. ret.msg)
end
end
end
end
logger:log(ngx.INFO, "called log_default() methods of plugins")
-- Display reason at info level
local reason = utils.get_reason()
if reason then
logger.log(ngx.INFO, "LOG", "Client was denied with reason : " .. reason)
if ngx.ctx.reason then
logger:log(ngx.INFO, "client was denied with reason : " .. reason)
end
logger.log(ngx.INFO, "LOG", "Log phase ended")
logger:log(ngx.INFO, "log_default phase ended")
}

View File

@ -54,9 +54,12 @@ for i, plugin in ipairs(plugins) do
if ret.status then
if ret.status == utils.get_deny_status() then
ngx.ctx.reason = plugin.id
return ngx.exit(ret.status)
logger:log(ngx.WARN, "denied access from " .. plugin.id .. " : " .. err)
else
logger:log(ngx.NOTICE, plugin.id .. " returned status " .. tostring(value) .. " : " .. err)
end
ngx.ctx.status = ret.status
break
end
else
logger:log(ngx.ERR, plugin.id .. ":access() call failed : " .. ret.msg)
@ -64,7 +67,20 @@ for i, plugin in ipairs(plugins) do
end
end
end
logger:log(ngx.NOTICE, "called set() methods of plugins")
logger:log(ngx.INFO, "called access() methods of plugins")
-- Save session if needed
local ok, err = utils.save_session()
if not ok then
logger:log(ngx.ERR, "can't save session : " .. err)
end
logger:log(ngx.INFO, "access phase ended")
-- Return status if needed
if ngx.ctx.status then
return ngx.exit(ret.status)
end
return true

View File

@ -1,44 +1,53 @@
log_by_lua_block {
local utils = require "utils"
local logger = require "logger"
local datastore = require "datastore"
local plugins = require "plugins"
local class = require "middleclass"
local clogger = require "bunkerweb.logger"
local helpers = require "bunkerweb.helpers"
local datastore = require "bunkerweb.datastore"
logger.log(ngx.INFO, "LOG", "Log phase started")
-- Start log phase
logger:new("LOG")
datastore:new()
logger:log(ngx.INFO, "log phase started")
-- List all plugins
local list, err = plugins:list()
if not list then
logger.log(ngx.ERR, "LOG", "Can't list loaded plugins : " .. err)
list = {}
-- Get plugins
local plugins, err = datastore:get("plugins")
if not plugins then
logger:log(ngx.ERR, "can't get plugins from datastore : " .. err)
return false
end
-- Call log method of plugins
for i, plugin in ipairs(list) do
local ret, plugin_lua = pcall(require, plugin.id .. "/" .. plugin.id)
if ret then
local plugin_obj = plugin_lua.new()
if plugin_obj.log ~= nil then
logger.log(ngx.INFO, "LOG", "Executing log() of " .. plugin.id)
local ok, err = plugin_obj:log()
if not ok then
logger.log(ngx.ERR, "LOG", "Error while calling log() on plugin " .. plugin.id .. " : " .. err)
else
logger.log(ngx.INFO, "LOG", "Return value from " .. plugin.id .. ".log() is : " .. err)
end
-- Call log() methods
logger:log(ngx.INFO, "calling log() methods of plugins ...")
for i, plugin in ipairs(plugins) do
local plugin_lua, err = helpers.new_plugin(plugin.id)
if plugin_lua == false then
logger:log(ngx.ERR, err)
else
logger:log(ngx.INFO, err)
end
if plugin_lua ~= nil then
local ok, ret = helpers.call_plugin(plugin_lua, "log")
if ok == false then
logger:log(ngx.ERR, ret)
elseif ok == nil then
logger:log(ngx.INFO, ret)
else
logger.log(ngx.INFO, "LOG", "log() method not found in " .. plugin.id .. ", skipped execution")
if ret.ret then
logger:log(ngx.INFO, plugin.id .. ":log() call successful : " .. ret.msg)
else
logger:log(ngx.ERR, plugin.id .. ":log() call failed : " .. ret.msg)
end
end
end
end
logger:log(ngx.INFO, "called log() methods of plugins")
-- Display reason at info level
local reason = utils.get_reason()
if reason then
logger.log(ngx.INFO, "LOG", "Client was denied with reason : " .. reason)
if ngx.ctx.reason then
logger:log(ngx.INFO, "client was denied with reason : " .. reason)
end
logger.log(ngx.INFO, "LOG", "Log phase ended")
logger:log(ngx.INFO, "log phase ended")
}

View File

@ -15,9 +15,6 @@ server {
include /etc/bunkerweb/configs/server-http/{{ SERVER_NAME.split(" ")[0] }}/*.conf;
{% endif %}
# reason variable
set $reason '';
# include LUA files
include {{ NGINX_PREFIX }}set-lua.conf;
include {{ NGINX_PREFIX }}access-lua.conf;

View File

@ -2,7 +2,7 @@ set $dummy_set "";
set_by_lua_block $dummy_set {
local class = require "middleclass"
local clogger = require "bunkerweb.logger"
local logger = require "bunkerweb.logger"
local helpers = require "bunkerweb.helpers"
local datastore = require "bunkerweb.datastore"
local cachestore = require "bunkerweb.cachestore"