mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
perf - ctx caching and per worker LRU for readonly variables
This commit is contained in:
parent
b27958a19c
commit
02d9403937
34 changed files with 647 additions and 559 deletions
|
|
@ -14,6 +14,16 @@ api.global = { GET = {}, POST = {}, PUT = {}, DELETE = {} }
|
|||
function api:initialize()
|
||||
self.datastore = datastore:new()
|
||||
self.logger = logger:new("API")
|
||||
self.ctx = ngx.ctx
|
||||
local data, err = utils.get_variable("API_WHITELIST_IP", false)
|
||||
self.ips = {}
|
||||
if not data then
|
||||
self.logger.log(ngx.ERR, "can't get API_WHITELIST_IP variable : " .. err)
|
||||
else
|
||||
for ip in data:gmatch("%S+") do
|
||||
table.insert(self.ips, ip)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function api:log_cmd(cmd, status, stdout, stderr)
|
||||
|
|
@ -71,17 +81,17 @@ api.global.POST["^/stop$"] = function(self)
|
|||
end
|
||||
|
||||
api.global.POST["^/confs$"] = function(self)
|
||||
local tmp = "/var/tmp/bunkerweb/api_" .. ngx.ctx.bw.uri:sub(2) .. ".tar.gz"
|
||||
local destination = "/usr/share/bunkerweb/" .. ngx.ctx.bw.uri:sub(2)
|
||||
if ngx.ctx.bw.uri == "/confs" then
|
||||
local tmp = "/var/tmp/bunkerweb/api_" .. self.ctx.bw.uri:sub(2) .. ".tar.gz"
|
||||
local destination = "/usr/share/bunkerweb/" .. self.ctx.bw.uri:sub(2)
|
||||
if self.ctx.bw.uri == "/confs" then
|
||||
destination = "/etc/nginx"
|
||||
elseif ngx.ctx.bw.uri == "/data" then
|
||||
elseif self.ctx.bw.uri == "/data" then
|
||||
destination = "/data"
|
||||
elseif ngx.ctx.bw.uri == "/cache" then
|
||||
elseif self.ctx.bw.uri == "/cache" then
|
||||
destination = "/var/cache/bunkerweb"
|
||||
elseif ngx.ctx.bw.uri == "/custom_configs" then
|
||||
elseif self.ctx.bw.uri == "/custom_configs" then
|
||||
destination = "/etc/bunkerweb/configs"
|
||||
elseif ngx.ctx.bw.uri == "/plugins" then
|
||||
elseif self.ctx.bw.uri == "/plugins" then
|
||||
destination = "/etc/bunkerweb/plugins"
|
||||
end
|
||||
local form, err = upload:new(4096)
|
||||
|
|
@ -186,20 +196,16 @@ api.global.GET["^/bans$"] = function(self)
|
|||
end
|
||||
|
||||
function api:is_allowed_ip()
|
||||
local data, err = self.datastore:get("api_whitelist_ip")
|
||||
if not data then
|
||||
return false, "can't access api_allowed_ips in datastore"
|
||||
end
|
||||
if utils.is_ip_in_networks(ngx.ctx.bw.remote_addr, cjson.decode(data)) then
|
||||
if utils.is_ip_in_networks(self.ctx.bw.remote_addr, self.ips) then
|
||||
return true, "ok"
|
||||
end
|
||||
return false, "IP is not in API_WHITELIST_IP"
|
||||
end
|
||||
|
||||
function api:do_api_call()
|
||||
if self.global[ngx.ctx.bw.request_method] ~= nil then
|
||||
for uri, api_fun in pairs(self.global[ngx.ctx.bw.request_method]) do
|
||||
if string.match(ngx.ctx.bw.uri, uri) then
|
||||
if self.global[self.ctx.bw.request_method] ~= nil then
|
||||
for uri, api_fun in pairs(self.global[self.ctx.bw.request_method]) do
|
||||
if string.match(self.ctx.bw.uri, uri) then
|
||||
local status, resp = api_fun(self)
|
||||
local ret = true
|
||||
if status ~= ngx.HTTP_OK then
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ if not cache then
|
|||
module_logger:log(ngx.ERR, "can't instantiate mlcache : " .. err)
|
||||
end
|
||||
|
||||
function cachestore:initialize(use_redis, new_cs)
|
||||
function cachestore:initialize(use_redis, new_cs, ctx)
|
||||
self.ctx = ctx
|
||||
self.cache = cache
|
||||
self.use_redis = use_redis or false
|
||||
self.logger = module_logger
|
||||
|
|
@ -50,7 +51,7 @@ function cachestore:initialize(use_redis, new_cs)
|
|||
self.clusterstore = clusterstore:new(false)
|
||||
self.shared_cs = false
|
||||
else
|
||||
self.clusterstore = utils.get_ctx_obj("clusterstore")
|
||||
self.clusterstore = utils.get_ctx_obj("clusterstore", self.ctx)
|
||||
self.shared_cs = true
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
local class = require "middleclass"
|
||||
local lrucache = require "resty.lrucache"
|
||||
local datastore = class("datastore")
|
||||
|
||||
local lru, err = lrucache.new(10000)
|
||||
if not lru then
|
||||
require "bunkerweb.logger":new("DATASTORE"):log(ngx.ERR, "failed to instantiate LRU cache : " .. (err or "unknown error"))
|
||||
end
|
||||
|
||||
function datastore:initialize()
|
||||
self.dict = ngx.shared.datastore
|
||||
if not self.dict then
|
||||
|
|
@ -8,7 +14,11 @@ function datastore:initialize()
|
|||
end
|
||||
end
|
||||
|
||||
function datastore:get(key)
|
||||
function datastore:get(key, worker)
|
||||
if worker then
|
||||
local value, err = lru:get(key)
|
||||
return value, err or "not found"
|
||||
end
|
||||
local value, err = self.dict:get(key)
|
||||
if not value and not err then
|
||||
err = "not found"
|
||||
|
|
@ -16,21 +26,35 @@ function datastore:get(key)
|
|||
return value, err
|
||||
end
|
||||
|
||||
function datastore:set(key, value, exptime)
|
||||
function datastore:set(key, value, exptime, worker)
|
||||
if worker then
|
||||
lru:set(key, value, exptime)
|
||||
return true, "success"
|
||||
end
|
||||
exptime = exptime or 0
|
||||
return self.dict:safe_set(key, value, exptime)
|
||||
end
|
||||
|
||||
function datastore:delete(key)
|
||||
function datastore:delete(key, worker)
|
||||
if worker then
|
||||
lru:delete(key)
|
||||
return true, "success"
|
||||
end
|
||||
self.dict:delete(key)
|
||||
return true, "success"
|
||||
end
|
||||
|
||||
function datastore:keys()
|
||||
function datastore:keys(worker)
|
||||
if worker then
|
||||
return lru:keys(0)
|
||||
end
|
||||
return self.dict:get_keys(0)
|
||||
end
|
||||
|
||||
function datastore:ttl(key)
|
||||
if worker then
|
||||
return false, "no supported for LRU"
|
||||
end
|
||||
local ttl, err = self.dict:ttl(key)
|
||||
if not ttl then
|
||||
return false, err
|
||||
|
|
@ -38,8 +62,13 @@ function datastore:ttl(key)
|
|||
return true, ttl
|
||||
end
|
||||
|
||||
function datastore:delete_all(pattern)
|
||||
local keys = self.dict:get_keys(0)
|
||||
function datastore:delete_all(pattern, worker)
|
||||
local keys = {}
|
||||
if worker then
|
||||
lru:keys(0)
|
||||
else
|
||||
local keys = self.dict:get_keys(0)
|
||||
end
|
||||
for i, key in ipairs(keys) do
|
||||
if key:match(pattern) then
|
||||
self.dict:delete(key)
|
||||
|
|
@ -48,4 +77,8 @@ function datastore:delete_all(pattern)
|
|||
return true, "success"
|
||||
end
|
||||
|
||||
function datastore:flush_lru()
|
||||
lru:flush_all()
|
||||
end
|
||||
|
||||
return datastore
|
||||
|
|
|
|||
|
|
@ -108,9 +108,9 @@ helpers.require_plugin = function(id)
|
|||
return plugin_lua, "require() call successful for plugin " .. id
|
||||
end
|
||||
|
||||
helpers.new_plugin = function(plugin_lua)
|
||||
helpers.new_plugin = function(plugin_lua, ctx)
|
||||
-- Require call
|
||||
local ok, plugin_obj = pcall(plugin_lua.new, plugin_lua)
|
||||
local ok, plugin_obj = pcall(plugin_lua.new, plugin_lua, ctx)
|
||||
if not ok then
|
||||
return false, "new error for plugin " .. plugin_lua.name .. " : " .. plugin_obj
|
||||
end
|
||||
|
|
@ -148,8 +148,9 @@ end
|
|||
helpers.fill_ctx = function()
|
||||
-- Return errors as table
|
||||
local errors = {}
|
||||
local ctx = ngx.ctx
|
||||
-- Check if ctx is already filled
|
||||
if not ngx.ctx.bw then
|
||||
if not ctx.bw then
|
||||
-- Instantiate bw table
|
||||
local data = {}
|
||||
-- Common vars
|
||||
|
|
@ -158,14 +159,18 @@ helpers.fill_ctx = function()
|
|||
data.kind = "stream"
|
||||
end
|
||||
data.remote_addr = ngx.var.remote_addr
|
||||
data.uri = ngx.var.uri
|
||||
data.request_uri = ngx.var.request_uri
|
||||
data.request_method = ngx.var.request_method
|
||||
data.http_user_agent = ngx.var.http_user_agent
|
||||
data.http_host = ngx.var.http_host
|
||||
data.server_name = ngx.var.server_name
|
||||
data.http_content_type = ngx.var.http_content_type
|
||||
data.http_origin = ngx.var.http_origin
|
||||
if data.kind == "http" then
|
||||
data.uri = ngx.var.uri
|
||||
data.request_uri = ngx.var.request_uri
|
||||
data.request_method = ngx.var.request_method
|
||||
data.http_user_agent = ngx.var.http_user_agent
|
||||
data.http_host = ngx.var.http_host
|
||||
data.server_name = ngx.var.server_name
|
||||
data.http_content_type = ngx.var.http_content_type
|
||||
data.http_content_length = ngx.var.http_content_length
|
||||
data.http_origin = ngx.var.http_origin
|
||||
data.http_version = ngx.req.http_version()
|
||||
end
|
||||
-- IP data : global
|
||||
local ip_is_global, err = utils.ip_is_global(data.remote_addr)
|
||||
if ip_is_global == nil then
|
||||
|
|
@ -180,17 +185,78 @@ helpers.fill_ctx = function()
|
|||
data.integration = utils.get_integration()
|
||||
data.version = utils.get_version()
|
||||
-- Fill ctx
|
||||
ngx.ctx.bw = data
|
||||
ctx.bw = data
|
||||
end
|
||||
-- Always create new objects for current phases in case of cosockets
|
||||
local use_redis, err = utils.get_variable("USE_REDIS", false)
|
||||
if not use_redis then
|
||||
table.insert(errors, "can't get variable from datastore : " .. err)
|
||||
end
|
||||
ngx.ctx.bw.datastore = require "bunkerweb.datastore":new()
|
||||
ngx.ctx.bw.clusterstore = require "bunkerweb.clusterstore":new()
|
||||
ngx.ctx.bw.cachestore = require "bunkerweb.cachestore":new(use_redis == "yes")
|
||||
return true, "ctx filled", errors
|
||||
ctx.bw.datastore = require "bunkerweb.datastore":new()
|
||||
ctx.bw.clusterstore = require "bunkerweb.clusterstore":new()
|
||||
ctx.bw.cachestore = require "bunkerweb.cachestore":new(use_redis == "yes")
|
||||
return true, "ctx filled", errors, ctx
|
||||
end
|
||||
|
||||
function helpers.load_variables(all_variables, plugins)
|
||||
-- Extract settings from plugins and global ones
|
||||
local all_settings = {}
|
||||
for i, plugin in ipairs(plugins) do
|
||||
if plugin.settings then
|
||||
for setting, data in pairs(plugin.settings) do
|
||||
all_settings[setting] = data
|
||||
end
|
||||
end
|
||||
end
|
||||
local file = io.open("/usr/share/bunkerweb/settings.json")
|
||||
if not file then
|
||||
return false, "can't open settings.json"
|
||||
end
|
||||
local ok, settings = pcall(cjson.decode, file:read("*a"))
|
||||
file:close()
|
||||
if not ok then
|
||||
return false, "invalid settings.json : " .. err
|
||||
end
|
||||
for setting, data in pairs(settings) do
|
||||
all_settings[setting] = data
|
||||
end
|
||||
-- Extract vars
|
||||
local variables = {["global"] = {}}
|
||||
local multisite = all_variables["MULTISITE"] == "yes"
|
||||
local server_names = {}
|
||||
if multisite then
|
||||
for server_name in all_variables["SERVER_NAME"]:gmatch("%S+") do
|
||||
variables[server_name] = {}
|
||||
table.insert(server_names, server_name)
|
||||
end
|
||||
end
|
||||
for setting, data in pairs(all_settings) do
|
||||
if all_variables[setting] then
|
||||
variables["global"][setting] = all_variables[setting]
|
||||
elseif multisite then
|
||||
for i, server_name in ipairs(server_names) do
|
||||
local key = server_name .. "_" .. setting
|
||||
if all_variables[key] then
|
||||
variables[server_name][setting] = all_variables[key]
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if data.multiple then
|
||||
for variable, value in pairs(all_variables) do
|
||||
local found, _, prefix = variable:find("^([^_]*)_?" .. variable .. "_[0-9]+$")
|
||||
if found then
|
||||
if multisite and prefix then
|
||||
variables[prefix][setting] = value
|
||||
break
|
||||
end
|
||||
variables["global"][setting] = prefix
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return true, variables
|
||||
end
|
||||
|
||||
return helpers
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ local utils = require "bunkerweb.utils"
|
|||
local cjson = require "cjson"
|
||||
local plugin = class("plugin")
|
||||
|
||||
function plugin:initialize(id)
|
||||
function plugin:initialize(id, ctx)
|
||||
-- Store common, values
|
||||
self.id = id
|
||||
local multisite = false
|
||||
|
|
@ -27,29 +27,40 @@ function plugin:initialize(id)
|
|||
end
|
||||
self.use_redis = use_redis == "yes"
|
||||
if self.is_request then
|
||||
self.datastore = utils.get_ctx_obj("datastore") or datastore:new()
|
||||
self.cachestore = utils.get_ctx_obj("cachestore") or cachestore:new(use_redis == "yes", true)
|
||||
self.clusterstore = utils.get_ctx_obj("clusterstore") or clusterstore:new(false)
|
||||
-- Store ctx
|
||||
self.ctx = ctx or ngx.ctx
|
||||
self.datastore = utils.get_ctx_obj("datastore", self.ctx) or datastore:new()
|
||||
self.cachestore = utils.get_ctx_obj("cachestore", self.ctx) or cachestore:new(use_redis == "yes", true, self.ctx)
|
||||
self.clusterstore = utils.get_ctx_obj("clusterstore", self.ctx) or clusterstore:new(false)
|
||||
else
|
||||
self.datastore = datastore:new()
|
||||
self.cachestore = cachestore:new(use_redis == "yes", true)
|
||||
self.clusterstore = clusterstore:new(false)
|
||||
end
|
||||
-- Get metadata
|
||||
local encoded_metadata, err = self.datastore:get("plugin_" .. id)
|
||||
if not encoded_metadata then
|
||||
local metadata, err = self.datastore:get("plugin_" .. id, true)
|
||||
if not metadata then
|
||||
self.logger:log(ngx.ERR, err)
|
||||
return
|
||||
end
|
||||
-- Store variables
|
||||
self.variables = {}
|
||||
local metadata = cjson.decode(encoded_metadata)
|
||||
self.multiples = {}
|
||||
for k, v in pairs(metadata.settings) do
|
||||
local value, err = utils.get_variable(k, v.context == "multisite" and multisite)
|
||||
if value == nil then
|
||||
self.logger:log(ngx.ERR, "can't get " .. k .. " variable : " .. err)
|
||||
end
|
||||
self.variables[k] = value
|
||||
-- if v.multiple then
|
||||
-- local multiples, err = utils.get_multiple_variables(k)
|
||||
-- if not multiples then
|
||||
-- self.logger:log(ngx.ERR, "can't get " .. k .. " multiple variable : " .. err)
|
||||
-- self.multiples[k] = {}
|
||||
-- else
|
||||
-- self.multiples[k] = multiples
|
||||
-- end
|
||||
-- end
|
||||
end
|
||||
-- Is loading
|
||||
local is_loading, err = utils.get_variable("IS_LOADING", false)
|
||||
|
|
|
|||
|
|
@ -20,49 +20,32 @@ utils.get_variable = function(var, site_search)
|
|||
site_search = true
|
||||
end
|
||||
-- Get global value
|
||||
local value, err = datastore:get("variable_" .. var)
|
||||
if not value then
|
||||
return nil, "can't access variable " .. var .. " from datastore : " .. err
|
||||
local variables, err = datastore:get('variables', true)
|
||||
if not variables then
|
||||
return nil, "can't access variables " .. var .. " from datastore : " .. err
|
||||
end
|
||||
local value = variables["global"][var]
|
||||
-- Site search case
|
||||
if site_search then
|
||||
-- Check if multisite is set to yes
|
||||
local multisite, err = datastore:get("variable_MULTISITE")
|
||||
if not multisite then
|
||||
return nil, "can't access variable MULTISITE from datastore : " .. err
|
||||
end
|
||||
-- Multisite case
|
||||
if multisite == "yes" and ngx.var.server_name then
|
||||
local value_site, err = datastore:get("variable_" .. ngx.var.server_name .. "_" .. var)
|
||||
if value_site then
|
||||
value = value_site
|
||||
end
|
||||
end
|
||||
local multisite = site_search and variables["global"]["MULTISITE"] == "yes" and ngx.var.server_name
|
||||
if multisite then
|
||||
value = variables[ngx.var.server_name][var]
|
||||
end
|
||||
return value, "success"
|
||||
end
|
||||
|
||||
utils.has_variable = function(var, value)
|
||||
-- Get global variable
|
||||
local check_value, err = datastore:get("variable_" .. var)
|
||||
if not value then
|
||||
return nil, "Can't access variable " .. var .. " from datastore : " .. err
|
||||
end
|
||||
-- Check if multisite is set to yes
|
||||
local multisite, err = datastore:get("variable_MULTISITE")
|
||||
if not multisite then
|
||||
return nil, "Can't access variable MULTISITE from datastore : " .. err
|
||||
local variables, err = datastore:get('variables', true)
|
||||
if not variables then
|
||||
return nil, "can't access variables " .. var .. " from datastore : " .. err
|
||||
end
|
||||
-- Multisite case
|
||||
if multisite == "yes" then
|
||||
local servers, err = datastore:get("variable_SERVER_NAME")
|
||||
if not servers then
|
||||
return nil, "Can't access variable SERVER_NAME from datastore : " .. err
|
||||
end
|
||||
local multisite = variables["global"]["MULTISITE"] == "yes"
|
||||
if multisite then
|
||||
local servers = variables["global"]["SERVER_NAME"]
|
||||
-- Check each server
|
||||
for server in servers:gmatch("%S+") do
|
||||
local check_value_site, err = datastore:get("variable_" .. server .. "_" .. var)
|
||||
if check_value_site and check_value_site == value then
|
||||
if variables[server][var] == "value" then
|
||||
return true, "success"
|
||||
end
|
||||
end
|
||||
|
|
@ -70,30 +53,22 @@ utils.has_variable = function(var, value)
|
|||
return false, "success"
|
||||
end
|
||||
end
|
||||
return check_value == value, "success"
|
||||
return variables["global"][var] == value, "success"
|
||||
end
|
||||
|
||||
utils.has_not_variable = function(var, value)
|
||||
utils.has_not_variable = function(var, value)
|
||||
-- Get global variable
|
||||
local check_value, err = datastore:get("variable_" .. var)
|
||||
if not value then
|
||||
return nil, "Can't access variable " .. var .. " from datastore : " .. err
|
||||
end
|
||||
-- Check if multisite is set to yes
|
||||
local multisite, err = datastore:get("variable_MULTISITE")
|
||||
if not multisite then
|
||||
return nil, "Can't access variable MULTISITE from datastore : " .. err
|
||||
local variables, err = datastore:get('variables', true)
|
||||
if not variables then
|
||||
return nil, "can't access variables " .. var .. " from datastore : " .. err
|
||||
end
|
||||
-- Multisite case
|
||||
if multisite == "yes" then
|
||||
local servers, err = datastore:get("variable_SERVER_NAME")
|
||||
if not servers then
|
||||
return nil, "Can't access variable SERVER_NAME from datastore : " .. err
|
||||
end
|
||||
local multisite = variables["global"]["MULTISITE"] == "yes"
|
||||
if multisite then
|
||||
local servers = variables["global"]["SERVER_NAME"]
|
||||
-- Check each server
|
||||
for server in servers:gmatch("%S+") do
|
||||
local check_value_site, err = datastore:get("variable_" .. server .. "_" .. var)
|
||||
if check_value_site and check_value_site ~= value then
|
||||
if variables[server][var] ~= "value" then
|
||||
return true, "success"
|
||||
end
|
||||
end
|
||||
|
|
@ -101,33 +76,24 @@ utils.has_not_variable = function(var, value)
|
|||
return false, "success"
|
||||
end
|
||||
end
|
||||
return check_value ~= value, "success"
|
||||
return variables["global"][var] ~= value, "success"
|
||||
end
|
||||
|
||||
utils.get_multiple_variables = function(vars)
|
||||
-- Get all keys
|
||||
local keys = datastore:keys()
|
||||
local variables, err = datastore:get('variables', true)
|
||||
if not variables then
|
||||
return nil, "can't access variables " .. var .. " from datastore : " .. err
|
||||
end
|
||||
local result = {}
|
||||
-- Loop on keys
|
||||
for i, key in ipairs(keys) do
|
||||
-- Loop on scoped vars
|
||||
for scope, scoped_vars in pairs(variables) do
|
||||
result[scope] = {}
|
||||
-- Loop on vars
|
||||
for j, var in ipairs(vars) do
|
||||
-- Filter on good ones
|
||||
local _, _, server, subvar = key:find("variable_(.*)_?(" .. var .. "_?%d*)")
|
||||
if subvar then
|
||||
if not server or server == "" then
|
||||
server = "global"
|
||||
else
|
||||
server = server:sub(1, -2)
|
||||
for variable, value in pairs(scoped_vars) do
|
||||
for i, var in ipairs(vars) do
|
||||
if variable:find("^" .. var .. "_?[0-9]*$") then
|
||||
result[scope][variable] = value
|
||||
end
|
||||
if result[server] == nil then
|
||||
result[server] = {}
|
||||
end
|
||||
local value, err = datastore:get(key)
|
||||
if not value then
|
||||
return nil, err
|
||||
end
|
||||
result[server][subvar] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -205,23 +171,25 @@ end
|
|||
|
||||
utils.get_integration = function()
|
||||
-- Check if already in datastore
|
||||
local integration, err = datastore:get("misc_integration")
|
||||
local integration, err = datastore:get("misc_integration", true)
|
||||
if integration then
|
||||
return integration
|
||||
end
|
||||
local variables, err = datastore:get("variables", true)
|
||||
if not variables then
|
||||
logger:log(ngx.ERR, "can't get variables from datastore : " .. err)
|
||||
return "unknown"
|
||||
end
|
||||
-- Swarm
|
||||
local var, err = datastore:get("variable_SWARM_MODE")
|
||||
if var == "yes" then
|
||||
if variables["global"]["SWARM_MODE"] == "yes" then
|
||||
integration = "swarm"
|
||||
else
|
||||
-- Kubernetes
|
||||
local var, err = datastore:get("variable_KUBERNETES_MODE")
|
||||
if var == "yes" then
|
||||
if variables["global"]["KUBERNETES_MODE"] == "yes" then
|
||||
integration = "kubernetes"
|
||||
else
|
||||
-- Autoconf
|
||||
local var, err = datastore:get("variable_AUTOCONF_MODE")
|
||||
if var == "yes" then
|
||||
if variables["global"]["AUTOCONF_MODE"] == "yes" then
|
||||
integration = "autoconf"
|
||||
else
|
||||
-- Already present (e.g. : linux)
|
||||
|
|
@ -247,7 +215,7 @@ utils.get_integration = function()
|
|||
end
|
||||
end
|
||||
-- Save integration
|
||||
local ok, err = datastore:set("misc_integration", integration)
|
||||
local ok, err = datastore:set("misc_integration", integration, nil, true)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't cache integration to datastore : " .. err)
|
||||
end
|
||||
|
|
@ -256,7 +224,7 @@ end
|
|||
|
||||
utils.get_version = function()
|
||||
-- Check if already in datastore
|
||||
local version, err = datastore:get("misc_version")
|
||||
local version, err = datastore:get("misc_version", true)
|
||||
if version then
|
||||
return version
|
||||
end
|
||||
|
|
@ -269,17 +237,17 @@ utils.get_version = function()
|
|||
version = f:read("*a"):gsub("[\n\r]", "")
|
||||
f:close()
|
||||
-- Save it to datastore
|
||||
local ok, err = datastore:set("misc_version", version)
|
||||
local ok, err = datastore:set("misc_version", version, nil, true)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't cache version to datastore : " .. err)
|
||||
end
|
||||
return version
|
||||
end
|
||||
|
||||
utils.get_reason = function()
|
||||
utils.get_reason = function(ctx)
|
||||
-- ngx.ctx
|
||||
if ngx.ctx.reason then
|
||||
return ngx.ctx.reason
|
||||
if ctx.bw.reason then
|
||||
return ctx.bw.reason
|
||||
end
|
||||
-- ngx.var
|
||||
if ngx.var.reason and ngx.var.reason ~= "" then
|
||||
|
|
@ -295,7 +263,7 @@ utils.get_reason = function()
|
|||
return banned
|
||||
end
|
||||
-- unknown
|
||||
if ngx.status == utils.get_deny_status() then
|
||||
if ngx.status == utils.get_deny_status(ctx) then
|
||||
return "unknown"
|
||||
end
|
||||
return nil
|
||||
|
|
@ -303,23 +271,23 @@ end
|
|||
|
||||
utils.get_resolvers = function()
|
||||
-- Get resolvers from datastore if existing
|
||||
local str_resolvers, err = datastore:get("misc_resolvers")
|
||||
if str_resolvers then
|
||||
return cjson.decode(str_resolvers)
|
||||
local resolvers, err = datastore:get("misc_resolvers", true)
|
||||
if resolvers then
|
||||
return resolvers
|
||||
end
|
||||
-- Otherwise extract DNS_RESOLVERS variable
|
||||
local var_resolvers, err = datastore:get("variable_DNS_RESOLVERS")
|
||||
if not var_resolvers then
|
||||
logger:log(ngx.ERR, "can't get variable DNS_RESOLVERS from datastore : " .. err)
|
||||
return nil, err
|
||||
local variables, err = datastore:get("variables", true)
|
||||
if not variables then
|
||||
logger:log(ngx.ERR, "can't get variables from datastore : " .. err)
|
||||
return "unknown"
|
||||
end
|
||||
-- Make table for resolver1 resolver2 ... string
|
||||
local resolvers = {}
|
||||
for str_resolver in var_resolvers:gmatch("%S+") do
|
||||
for str_resolver in variables["global"]["DNS_RESOLVERS"]:gmatch("%S+") do
|
||||
table.insert(resolvers, str_resolver)
|
||||
end
|
||||
-- Add it to the datastore
|
||||
local ok, err = datastore:set("misc_resolvers", cjson.encode(resolvers))
|
||||
local ok, err = datastore:set("misc_resolvers", resolvers, nil, true)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't save misc_resolvers to datastore : " .. err)
|
||||
end
|
||||
|
|
@ -497,24 +465,24 @@ utils.rand = function(nb, no_numbers)
|
|||
return result
|
||||
end
|
||||
|
||||
utils.get_deny_status = function()
|
||||
utils.get_deny_status = function(ctx)
|
||||
-- Stream case
|
||||
if ngx.ctx.bw and ngx.ctx.bw.kind == "stream" then
|
||||
if ctx.bw and ctx.bw.kind == "stream" then
|
||||
return 444
|
||||
end
|
||||
-- http case
|
||||
local status, err = datastore:get("variable_DENY_HTTP_STATUS")
|
||||
if not status then
|
||||
logger:log(ngx.ERR, "can't get DENY_HTTP_STATUS variable " .. err)
|
||||
local variables, err = datastore:get("variables", true)
|
||||
if not variables then
|
||||
logger:log(ngx.ERR, "can't get variables from datastore : " .. err)
|
||||
return 403
|
||||
end
|
||||
return tonumber(status)
|
||||
return tonumber(variables["global"]["DENY_HTTP_STATUS"])
|
||||
end
|
||||
|
||||
utils.check_session = function()
|
||||
utils.check_session = function(ctx)
|
||||
local _session, err, exists, refreshed = session.start({audience = "metadata"})
|
||||
if exists then
|
||||
for i, check in ipairs(ngx.ctx.bw.sessions_checks) do
|
||||
for i, check in ipairs(ctx.bw.sessions_checks) do
|
||||
local key = check[1]
|
||||
local value = check[2]
|
||||
if _session:get(key) ~= value then
|
||||
|
|
@ -524,11 +492,11 @@ utils.check_session = function()
|
|||
return false, "session:destroy() error : " .. err
|
||||
end
|
||||
logger:log(ngx.WARN, "session check " .. key .. " failed, destroying session")
|
||||
return utils.check_session()
|
||||
return utils.check_session(ctx)
|
||||
end
|
||||
end
|
||||
else
|
||||
for i, check in ipairs(ngx.ctx.bw.sessions_checks) do
|
||||
for i, check in ipairs(ctx.bw.sessions_checks) do
|
||||
_session:set(check[1], check[2])
|
||||
end
|
||||
local ok, err = _session:save()
|
||||
|
|
@ -537,15 +505,15 @@ utils.check_session = function()
|
|||
return false, "session:save() error : " .. err
|
||||
end
|
||||
end
|
||||
ngx.ctx.bw.sessions_is_checked = true
|
||||
ctx.bw.sessions_is_checked = true
|
||||
_session:close()
|
||||
return true, exists
|
||||
end
|
||||
|
||||
utils.get_session = function(audience)
|
||||
utils.get_session = function(audience, ctx)
|
||||
-- Check session
|
||||
if not ngx.ctx.bw.sessions_is_checked then
|
||||
local ok, err = utils.check_session()
|
||||
if not ctx.bw.sessions_is_checked then
|
||||
local ok, err = utils.check_session(ctx)
|
||||
if not ok then
|
||||
return false, "error while checking session, " .. err
|
||||
end
|
||||
|
|
@ -558,20 +526,20 @@ utils.get_session = function(audience)
|
|||
return _session
|
||||
end
|
||||
|
||||
utils.get_session_data = function(_session, site)
|
||||
utils.get_session_data = function(_session, site, ctx)
|
||||
local site_only = site == nil or site
|
||||
local data = _session:get_data()
|
||||
if site_only then
|
||||
return data[ngx.ctx.bw.server_name] or {}
|
||||
return data[ctx.bw.server_name] or {}
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
utils.set_session_data = function(_session, data, site)
|
||||
utils.set_session_data = function(_session, data, site, ctx)
|
||||
local site_only = site == nil or site
|
||||
if site_only then
|
||||
local all_data = _session:get_data()
|
||||
all_data[ngx.ctx.bw.server_name] = data
|
||||
all_data[ctx.bw.server_name] = data
|
||||
_session:set_data(all_data)
|
||||
return _session:save()
|
||||
end
|
||||
|
|
@ -734,9 +702,9 @@ utils.kill_all_threads = function(threads)
|
|||
end
|
||||
end
|
||||
|
||||
utils.get_ctx_obj = function(obj)
|
||||
if ngx.ctx and ngx.ctx.bw then
|
||||
return ngx.ctx.bw[obj]
|
||||
utils.get_ctx_obj = function(obj, ctx)
|
||||
if ctx and ctx.bw then
|
||||
return ctx.bw[obj]
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ server {
|
|||
|
||||
-- Fill ctx
|
||||
logger:log(ngx.INFO, "filling ngx.ctx ...")
|
||||
local ok, ret, errors = helpers.fill_ctx()
|
||||
local ok, ret, errors, ctx = helpers.fill_ctx()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
|
||||
elseif errors then
|
||||
|
|
@ -36,30 +36,33 @@ server {
|
|||
logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
|
||||
|
||||
-- Check host header
|
||||
if not ngx.ctx.bw.http_host or ngx.ctx.bw.http_host ~= "{{ API_SERVER_NAME }}" then
|
||||
logger:log(ngx.WARN, "wrong Host header from IP " .. ngx.ctx.bw.remote_addr)
|
||||
if not ctx.bw.http_host or ctx.bw.http_host ~= "{{ API_SERVER_NAME }}" then
|
||||
logger:log(ngx.WARN, "wrong Host header from IP " .. ctx.bw.remote_addr)
|
||||
return ngx.exit(ngx.HTTP_CLOSE)
|
||||
end
|
||||
|
||||
-- Check IP
|
||||
local ok, err = api:is_allowed_ip()
|
||||
if not ok then
|
||||
logger:log(ngx.WARN, "can't validate access from IP " .. ngx.ctx.bw.remote_addr .. " : " .. err)
|
||||
logger:log(ngx.WARN, "can't validate access from IP " .. ctx.bw.remote_addr .. " : " .. err)
|
||||
return ngx.exit(ngx.HTTP_CLOSE)
|
||||
end
|
||||
logger:log(ngx.NOTICE, "validated access from IP " .. ngx.ctx.bw.remote_addr)
|
||||
logger:log(ngx.NOTICE, "validated access from IP " .. ctx.bw.remote_addr)
|
||||
|
||||
-- Do API call
|
||||
local ok, err, status, resp = api:do_api_call()
|
||||
if not ok then
|
||||
logger:log(ngx.WARN, "call from " .. ngx.ctx.bw.remote_addr .. " on " .. ngx.ctx.bw.uri .. " failed : " .. err)
|
||||
logger:log(ngx.WARN, "call from " .. ctx.bw.remote_addr .. " on " .. ctx.bw.uri .. " failed : " .. err)
|
||||
else
|
||||
logger:log(ngx.NOTICE, "successful call from " .. ngx.ctx.bw.remote_addr .. " on " .. ngx.ctx.bw.uri .. " : " .. err)
|
||||
logger:log(ngx.NOTICE, "successful call from " .. ctx.bw.remote_addr .. " on " .. ctx.bw.uri .. " : " .. err)
|
||||
end
|
||||
|
||||
-- Start API handler
|
||||
logger:log(ngx.INFO, "API handler ended")
|
||||
|
||||
-- Save ctx
|
||||
ngx.ctx = ctx
|
||||
|
||||
-- Send response
|
||||
ngx.status = status
|
||||
ngx.say(resp)
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ server {
|
|||
|
||||
-- Fill ctx
|
||||
logger:log(ngx.INFO, "filling ngx.ctx ...")
|
||||
local ok, ret, errors = helpers.fill_ctx()
|
||||
local ok, ret, errors, ctx = helpers.fill_ctx()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
|
||||
elseif errors then
|
||||
|
|
@ -102,10 +102,13 @@ server {
|
|||
logger:log(ngx.INFO, "called log_default() methods of plugins")
|
||||
|
||||
-- Display reason at info level
|
||||
if ngx.ctx.reason then
|
||||
if ctx.reason then
|
||||
logger:log(ngx.INFO, "client was denied with reason : " .. reason)
|
||||
end
|
||||
|
||||
-- Save ctx
|
||||
ngx.ctx = ctx
|
||||
|
||||
logger:log(ngx.INFO, "log_default phase ended")
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ logger:log(ngx.NOTICE, "init phase started")
|
|||
|
||||
-- Remove previous data from the datastore
|
||||
logger:log(ngx.NOTICE, "deleting old keys from datastore ...")
|
||||
local data_keys = {"^plugin", "^variable_", "^api_", "^misc_"}
|
||||
datastore:flush_lru()
|
||||
local data_keys = {"^plugin", "^misc_"}
|
||||
for i, key in pairs(data_keys) do
|
||||
local ok, err = datastore:delete_all(key)
|
||||
if not ok then
|
||||
|
|
@ -24,58 +25,6 @@ for i, key in pairs(data_keys) do
|
|||
end
|
||||
logger:log(ngx.NOTICE, "deleted old keys from datastore")
|
||||
|
||||
-- Load variables into the datastore
|
||||
logger:log(ngx.NOTICE, "saving variables into datastore ...")
|
||||
local file = io.open("/etc/nginx/variables.env")
|
||||
if not file then
|
||||
logger:log(ngx.ERR, "can't open /etc/nginx/variables.env file")
|
||||
return false
|
||||
end
|
||||
file:close()
|
||||
for line in io.lines("/etc/nginx/variables.env") do
|
||||
local variable, value = line:match("^([^=]+)=(.*)$")
|
||||
local ok, err = datastore:set("variable_" .. variable, value)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't save variable " .. variable .. " into datastore : " .. err)
|
||||
return false
|
||||
end
|
||||
logger:log(ngx.INFO, "saved variable " .. variable .. "=" .. value .. " into datastore")
|
||||
end
|
||||
logger:log(ngx.NOTICE, "saved variables into datastore")
|
||||
|
||||
-- Purge cache
|
||||
local cachestore = require "bunkerweb.cachestore":new(false, true)
|
||||
local ok, err = cachestore:purge()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't purge cachestore : " .. err)
|
||||
end
|
||||
|
||||
-- Set API values into the datastore
|
||||
logger:log(ngx.NOTICE, "saving API values into datastore ...")
|
||||
local value, err = datastore:get("variable_USE_API")
|
||||
if not value then
|
||||
logger:log(ngx.ERR, "can't get variable USE_API from the datastore : " .. err)
|
||||
return false
|
||||
end
|
||||
if value == "yes" then
|
||||
local value, err = datastore:get("variable_API_WHITELIST_IP")
|
||||
if not value then
|
||||
logger:log(ngx.ERR, "can't get variable API_WHITELIST_IP from the datastore : " .. err)
|
||||
return false
|
||||
end
|
||||
local whitelists = {}
|
||||
for whitelist in value:gmatch("%S+") do
|
||||
table.insert(whitelists, whitelist)
|
||||
end
|
||||
local ok, err = datastore:set("api_whitelist_ip", cjson.encode(whitelists))
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't save API whitelist_ip to datastore : " .. err)
|
||||
return false
|
||||
end
|
||||
logger:log(ngx.INFO, "saved API whitelist_ip into datastore")
|
||||
end
|
||||
logger:log(ngx.NOTICE, "saved API values into datastore")
|
||||
|
||||
-- Load plugins into the datastore
|
||||
logger:log(ngx.NOTICE, "saving plugins into datastore ...")
|
||||
local plugins = {}
|
||||
|
|
@ -87,7 +36,7 @@ for i, plugin_path in ipairs(plugin_paths) do
|
|||
if not ok then
|
||||
logger:log(ngx.ERR, plugin)
|
||||
else
|
||||
local ok, err = datastore:set("plugin_" .. plugin.id, cjson.encode(plugin))
|
||||
local ok, err = datastore:set("plugin_" .. plugin.id, plugin, nil, true)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't save " .. plugin.id .. " into datastore : " .. err)
|
||||
else
|
||||
|
|
@ -97,12 +46,70 @@ for i, plugin_path in ipairs(plugin_paths) do
|
|||
end
|
||||
end
|
||||
end
|
||||
local ok, err = datastore:set("plugins", cjson.encode(plugins))
|
||||
local ok, err = datastore:set("plugins", plugins, nil, true)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't save plugins into datastore : " .. err)
|
||||
return false
|
||||
end
|
||||
|
||||
-- Load variables into the datastore
|
||||
logger:log(ngx.NOTICE, "saving variables into datastore ...")
|
||||
local file = io.open("/etc/nginx/variables.env")
|
||||
if not file then
|
||||
logger:log(ngx.ERR, "can't open /etc/nginx/variables.env file")
|
||||
return false
|
||||
end
|
||||
file:close()
|
||||
local all_variables = {}
|
||||
for line in io.lines("/etc/nginx/variables.env") do
|
||||
local variable, value = line:match("^([^=]+)=(.*)$")
|
||||
all_variables[variable] = value
|
||||
end
|
||||
local ok, variables = helpers.load_variables(all_variables, plugins)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "error while loading variables : " .. variables)
|
||||
return false
|
||||
end
|
||||
local ok, err = datastore:set("variables", variables, nil, true)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't save plugins into datastore : " .. err)
|
||||
return false
|
||||
end
|
||||
logger:log(ngx.NOTICE, "saved variables into datastore")
|
||||
|
||||
-- Purge cache
|
||||
local cachestore = require "bunkerweb.cachestore":new(false, true)
|
||||
local ok, err = cachestore:purge()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't purge cachestore : " .. err)
|
||||
end
|
||||
|
||||
-- Set API values into the datastore
|
||||
-- logger:log(ngx.NOTICE, "saving API values into datastore ...")
|
||||
-- local value, err = datastore:get("variable_USE_API")
|
||||
-- if not value then
|
||||
-- logger:log(ngx.ERR, "can't get variable USE_API from the datastore : " .. err)
|
||||
-- return false
|
||||
-- end
|
||||
-- if value == "yes" then
|
||||
-- local value, err = datastore:get("variable_API_WHITELIST_IP")
|
||||
-- if not value then
|
||||
-- logger:log(ngx.ERR, "can't get variable API_WHITELIST_IP from the datastore : " .. err)
|
||||
-- return false
|
||||
-- end
|
||||
-- local whitelists = {}
|
||||
-- for whitelist in value:gmatch("%S+") do
|
||||
-- table.insert(whitelists, whitelist)
|
||||
-- end
|
||||
-- local ok, err = datastore:set("api_whitelist_ip", cjson.encode(whitelists))
|
||||
-- if not ok then
|
||||
-- logger:log(ngx.ERR, "can't save API whitelist_ip to datastore : " .. err)
|
||||
-- return false
|
||||
-- end
|
||||
-- logger:log(ngx.INFO, "saved API whitelist_ip into datastore")
|
||||
-- end
|
||||
-- logger:log(ngx.NOTICE, "saved API values into datastore")
|
||||
|
||||
logger:log(ngx.NOTICE, "saving plugins order into datastore ...")
|
||||
local ok, order = helpers.order_plugins(plugins)
|
||||
if not ok then
|
||||
|
|
@ -112,7 +119,7 @@ end
|
|||
for phase, id_list in pairs(order) do
|
||||
logger:log(ngx.NOTICE, "plugins order for phase " .. phase .. " : " .. cjson.encode(id_list))
|
||||
end
|
||||
local ok, err = datastore:set("plugins_order", cjson.encode(order))
|
||||
local ok, err = datastore:set("plugins_order", order, nil, true)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't save plugins order into datastore : " .. err)
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ logger:log(ngx.NOTICE, "init-stream phase started")
|
|||
|
||||
-- Remove previous data from the datastore
|
||||
logger:log(ngx.NOTICE, "deleting old keys from datastore ...")
|
||||
local data_keys = {"^plugin", "^variable_", "^api_", "^misc_"}
|
||||
datastore:flush_lru()
|
||||
local data_keys = {"^plugin", "^misc_"}
|
||||
for i, key in pairs(data_keys) do
|
||||
local ok, err = datastore:delete_all(key)
|
||||
if not ok then
|
||||
|
|
@ -24,58 +25,6 @@ for i, key in pairs(data_keys) do
|
|||
end
|
||||
logger:log(ngx.NOTICE, "deleted old keys from datastore")
|
||||
|
||||
-- Load variables into the datastore
|
||||
logger:log(ngx.NOTICE, "saving variables into datastore ...")
|
||||
local file = io.open("/etc/nginx/variables.env")
|
||||
if not file then
|
||||
logger:log(ngx.ERR, "can't open /etc/nginx/variables.env file")
|
||||
return false
|
||||
end
|
||||
file:close()
|
||||
for line in io.lines("/etc/nginx/variables.env") do
|
||||
local variable, value = line:match("^([^=]+)=(.*)$")
|
||||
local ok, err = datastore:set("variable_" .. variable, value)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't save variable " .. variable .. " into datastore : " .. err)
|
||||
return false
|
||||
end
|
||||
logger:log(ngx.INFO, "saved variable " .. variable .. "=" .. value .. " into datastore")
|
||||
end
|
||||
logger:log(ngx.NOTICE, "saved variables into datastore")
|
||||
|
||||
-- Purge cache
|
||||
local cachestore = require "bunkerweb.cachestore":new(false, true)
|
||||
local ok, err = cachestore:purge()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't purge cachestore : " .. err)
|
||||
end
|
||||
|
||||
-- Set API values into the datastore
|
||||
logger:log(ngx.NOTICE, "saving API values into datastore ...")
|
||||
local value, err = datastore:get("variable_USE_API")
|
||||
if not value then
|
||||
logger:log(ngx.ERR, "can't get variable USE_API from the datastore : " .. err)
|
||||
return false
|
||||
end
|
||||
if value == "yes" then
|
||||
local value, err = datastore:get("variable_API_WHITELIST_IP")
|
||||
if not value then
|
||||
logger:log(ngx.ERR, "can't get variable API_WHITELIST_IP from the datastore : " .. err)
|
||||
return false
|
||||
end
|
||||
local whitelists = {}
|
||||
for whitelist in value:gmatch("%S+") do
|
||||
table.insert(whitelists, whitelist)
|
||||
end
|
||||
local ok, err = datastore:set("api_whitelist_ip", cjson.encode(whitelists))
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't save API whitelist_ip to datastore : " .. err)
|
||||
return false
|
||||
end
|
||||
logger:log(ngx.INFO, "saved API whitelist_ip into datastore")
|
||||
end
|
||||
logger:log(ngx.NOTICE, "saved API values into datastore")
|
||||
|
||||
-- Load plugins into the datastore
|
||||
logger:log(ngx.NOTICE, "saving plugins into datastore ...")
|
||||
local plugins = {}
|
||||
|
|
@ -87,7 +36,7 @@ for i, plugin_path in ipairs(plugin_paths) do
|
|||
if not ok then
|
||||
logger:log(ngx.ERR, plugin)
|
||||
else
|
||||
local ok, err = datastore:set("plugin_" .. plugin.id, cjson.encode(plugin))
|
||||
local ok, err = datastore:set("plugin_" .. plugin.id, plugin, true)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't save " .. plugin.id .. " into datastore : " .. err)
|
||||
else
|
||||
|
|
@ -97,12 +46,44 @@ for i, plugin_path in ipairs(plugin_paths) do
|
|||
end
|
||||
end
|
||||
end
|
||||
local ok, err = datastore:set("plugins", cjson.encode(plugins))
|
||||
local ok, err = datastore:set("plugins", plugins, nil, true)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't save plugins into datastore : " .. err)
|
||||
return false
|
||||
end
|
||||
|
||||
-- Load variables into the datastore
|
||||
logger:log(ngx.NOTICE, "saving variables into datastore ...")
|
||||
local file = io.open("/etc/nginx/variables.env")
|
||||
if not file then
|
||||
logger:log(ngx.ERR, "can't open /etc/nginx/variables.env file")
|
||||
return false
|
||||
end
|
||||
file:close()
|
||||
local all_variables = {}
|
||||
for line in io.lines("/etc/nginx/variables.env") do
|
||||
local variable, value = line:match("^([^=]+)=(.*)$")
|
||||
all_variables[variable] = value
|
||||
end
|
||||
local ok, variables = helpers.load_variables(all_variables, plugins)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "error while loading variables : " .. variables)
|
||||
return false
|
||||
end
|
||||
local ok, err = datastore:set("variables", variables, nil, true)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't save plugins into datastore : " .. err)
|
||||
return false
|
||||
end
|
||||
logger:log(ngx.NOTICE, "saved variables into datastore")
|
||||
|
||||
-- Purge cache
|
||||
local cachestore = require "bunkerweb.cachestore":new(false, true)
|
||||
local ok, err = cachestore:purge()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't purge cachestore : " .. err)
|
||||
end
|
||||
|
||||
logger:log(ngx.NOTICE, "saving plugins order into datastore ...")
|
||||
local ok, order = helpers.order_plugins(plugins)
|
||||
if not ok then
|
||||
|
|
@ -112,7 +93,7 @@ end
|
|||
for phase, id_list in pairs(order) do
|
||||
logger:log(ngx.NOTICE, "plugins order for phase " .. phase .. " : " .. cjson.encode(id_list))
|
||||
end
|
||||
local ok, err = datastore:set("plugins_order", cjson.encode(order))
|
||||
local ok, err = datastore:set("plugins_order", order, nil, true)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "can't save plugins order into datastore : " .. err)
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ local ready_work = function(premature)
|
|||
logger:log(ngx.INFO, "init_worker phase started")
|
||||
|
||||
-- Get plugins order
|
||||
local order, err = datastore:get("plugins_order")
|
||||
local order, err = datastore:get("plugins_order", true)
|
||||
if not order then
|
||||
logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
|
||||
local ok, err = lock:unlock()
|
||||
|
|
@ -66,7 +66,6 @@ local ready_work = function(premature)
|
|||
end
|
||||
return
|
||||
end
|
||||
order = cjson.decode(order)
|
||||
|
||||
-- Call init_worker() methods
|
||||
logger:log(ngx.INFO, "calling init_worker() methods of plugins ...")
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ logger:log(ngx.INFO, "access phase started")
|
|||
|
||||
-- Fill ctx
|
||||
logger:log(ngx.INFO, "filling ngx.ctx ...")
|
||||
local ok, ret, errors = helpers.fill_ctx()
|
||||
local ok, ret, errors, ctx = helpers.fill_ctx()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
|
||||
elseif errors then
|
||||
|
|
@ -32,23 +32,24 @@ end
|
|||
logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
|
||||
|
||||
-- Process bans as soon as possible
|
||||
local banned, reason, ttl = utils.is_banned(ngx.ctx.bw.remote_addr)
|
||||
if banned == nil then
|
||||
logger:log(ngx.ERR, "can't check if IP " .. ngx.ctx.bw.remote_addr .. " is banned : " .. reason)
|
||||
elseif banned then
|
||||
logger:log(ngx.WARN, "IP " .. ngx.ctx.bw.remote_addr .. " is banned with reason " .. reason .. " (" .. tostring(ttl) .. "s remaining)")
|
||||
return ngx.exit(utils.get_deny_status())
|
||||
else
|
||||
logger:log(ngx.INFO, "IP " .. ngx.ctx.bw.remote_addr .. " is not banned")
|
||||
if ctx.bw.is_whitelisted ~= "yes" then
|
||||
local banned, reason, ttl = utils.is_banned(ctx.bw.remote_addr)
|
||||
if banned == nil then
|
||||
logger:log(ngx.ERR, "can't check if IP " .. ctx.bw.remote_addr .. " is banned : " .. reason)
|
||||
elseif banned then
|
||||
logger:log(ngx.WARN, "IP " .. ctx.bw.remote_addr .. " is banned with reason " .. reason .. " (" .. tostring(ttl) .. "s remaining)")
|
||||
return ngx.exit(utils.get_deny_status(ctx))
|
||||
else
|
||||
logger:log(ngx.INFO, "IP " .. ctx.bw.remote_addr .. " is not banned")
|
||||
end
|
||||
end
|
||||
|
||||
-- Get plugins order
|
||||
local order, err = datastore:get("plugins_order")
|
||||
local order, err = datastore:get("plugins_order", true)
|
||||
if not order then
|
||||
logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
|
||||
return
|
||||
end
|
||||
order = cjson.decode(order)
|
||||
|
||||
-- Call access() methods
|
||||
logger:log(ngx.INFO, "calling access() methods of plugins ...")
|
||||
|
|
@ -65,7 +66,7 @@ for i, plugin_id in ipairs(order.access) do
|
|||
-- Check if plugin has access method
|
||||
if plugin_lua.access ~= nil then
|
||||
-- New call
|
||||
local ok, plugin_obj = helpers.new_plugin(plugin_lua)
|
||||
local ok, plugin_obj = helpers.new_plugin(plugin_lua, ctx)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, plugin_obj)
|
||||
else
|
||||
|
|
@ -78,8 +79,8 @@ for i, plugin_id in ipairs(order.access) do
|
|||
logger:log(ngx.INFO, plugin_id .. ":access() call successful : " .. ret.msg)
|
||||
end
|
||||
if ret.status then
|
||||
if ret.status == utils.get_deny_status() then
|
||||
ngx.ctx.reason = plugin_id
|
||||
if ret.status == utils.get_deny_status(ctx) then
|
||||
ctx.bw.reason = plugin_id
|
||||
logger:log(ngx.WARN, "denied access from " .. plugin_id .. " : " .. ret.msg)
|
||||
else
|
||||
logger:log(ngx.NOTICE, plugin_id .. " returned status " .. tostring(ret.status) .. " : " .. ret.msg)
|
||||
|
|
@ -99,13 +100,8 @@ for i, plugin_id in ipairs(order.access) do
|
|||
end
|
||||
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)
|
||||
-- else
|
||||
-- logger:log(ngx.INFO, "session save return : " .. err)
|
||||
-- end
|
||||
-- Save ctx
|
||||
ngx.ctx = ctx
|
||||
|
||||
logger:log(ngx.INFO, "access phase ended")
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ logger:log(ngx.INFO, "header phase started")
|
|||
|
||||
-- Fill ctx
|
||||
logger:log(ngx.INFO, "filling ngx.ctx ...")
|
||||
local ok, ret, errors = helpers.fill_ctx()
|
||||
local ok, ret, errors, ctx = helpers.fill_ctx()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
|
||||
elseif errors then
|
||||
|
|
@ -24,12 +24,11 @@ end
|
|||
logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
|
||||
|
||||
-- Get plugins order
|
||||
local order, err = datastore:get("plugins_order")
|
||||
local order, err = datastore:get("plugins_order", true)
|
||||
if not order then
|
||||
logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
|
||||
return
|
||||
end
|
||||
order = cjson.decode(order)
|
||||
|
||||
-- Call header() methods
|
||||
logger:log(ngx.INFO, "calling header() methods of plugins ...")
|
||||
|
|
@ -44,7 +43,7 @@ for i, plugin_id in ipairs(order.header) do
|
|||
-- Check if plugin has header method
|
||||
if plugin_lua.header ~= nil then
|
||||
-- New call
|
||||
local ok, plugin_obj = helpers.new_plugin(plugin_lua)
|
||||
local ok, plugin_obj = helpers.new_plugin(plugin_lua, ctx)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, plugin_obj)
|
||||
else
|
||||
|
|
@ -64,6 +63,9 @@ for i, plugin_id in ipairs(order.header) do
|
|||
end
|
||||
logger:log(ngx.INFO, "called header() methods of plugins")
|
||||
|
||||
-- Save ctx
|
||||
ngx.ctx = ctx
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@ logger:log(ngx.INFO, "log phase started")
|
|||
|
||||
-- Fill ctx
|
||||
logger:log(ngx.INFO, "filling ngx.ctx ...")
|
||||
local ok, ret, errors = helpers.fill_ctx()
|
||||
local ok, ret, errors, ctx = helpers.fill_ctx()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
|
||||
elseif errors then
|
||||
|
|
@ -24,12 +24,11 @@ end
|
|||
logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
|
||||
|
||||
-- Get plugins order
|
||||
local order, err = datastore:get("plugins_order")
|
||||
local order, err = datastore:get("plugins_order", true)
|
||||
if not order then
|
||||
logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
|
||||
return
|
||||
end
|
||||
order = cjson.decode(order)
|
||||
|
||||
-- Call log() methods
|
||||
logger:log(ngx.INFO, "calling log() methods of plugins ...")
|
||||
|
|
@ -44,7 +43,7 @@ for i, plugin_id in ipairs(order.log) do
|
|||
-- Check if plugin has log method
|
||||
if plugin_lua.log ~= nil then
|
||||
-- New call
|
||||
local ok, plugin_obj = helpers.new_plugin(plugin_lua)
|
||||
local ok, plugin_obj = helpers.new_plugin(plugin_lua, ctx)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, plugin_obj)
|
||||
else
|
||||
|
|
@ -65,10 +64,13 @@ end
|
|||
logger:log(ngx.INFO, "called log() methods of plugins")
|
||||
|
||||
-- Display reason at info level
|
||||
if ngx.ctx.reason then
|
||||
logger:log(ngx.INFO, "client was denied with reason : " .. ngx.ctx.reason)
|
||||
if ctx.reason then
|
||||
logger:log(ngx.INFO, "client was denied with reason : " .. ctx.reason)
|
||||
end
|
||||
|
||||
-- Save ctx
|
||||
ngx.ctx = ctx
|
||||
|
||||
logger:log(ngx.INFO, "log phase ended")
|
||||
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ end
|
|||
|
||||
-- Fill ctx
|
||||
logger:log(ngx.INFO, "filling ngx.ctx ...")
|
||||
local ok, ret, errors = helpers.fill_ctx()
|
||||
local ok, ret, errors, ctx = helpers.fill_ctx()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
|
||||
elseif errors then
|
||||
|
|
@ -39,12 +39,11 @@ end
|
|||
logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
|
||||
|
||||
-- Get plugins order
|
||||
local order, err = datastore:get("plugins_order")
|
||||
local order, err = datastore:get("plugins_order", true)
|
||||
if not order then
|
||||
logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
|
||||
return
|
||||
end
|
||||
order = cjson.decode(order)
|
||||
|
||||
-- Call set() methods
|
||||
logger:log(ngx.INFO, "calling set() methods of plugins ...")
|
||||
|
|
@ -59,7 +58,7 @@ for i, plugin_id in ipairs(order.set) do
|
|||
-- Check if plugin has set method
|
||||
if plugin_lua.set ~= nil then
|
||||
-- New call
|
||||
local ok, plugin_obj = helpers.new_plugin(plugin_lua)
|
||||
local ok, plugin_obj = helpers.new_plugin(plugin_lua, ctx)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, plugin_obj)
|
||||
else
|
||||
|
|
@ -79,6 +78,9 @@ for i, plugin_id in ipairs(order.set) do
|
|||
end
|
||||
logger:log(ngx.INFO, "called set() methods of plugins")
|
||||
|
||||
-- Save ctx
|
||||
ngx.ctx = ctx
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@ logger:log(ngx.INFO, "log phase started")
|
|||
|
||||
-- Fill ctx
|
||||
logger:log(ngx.INFO, "filling ngx.ctx ...")
|
||||
local ok, ret, errors = helpers.fill_ctx()
|
||||
local ok, ret, errors, ctx = helpers.fill_ctx()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
|
||||
elseif errors then
|
||||
|
|
@ -24,12 +24,11 @@ end
|
|||
logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
|
||||
|
||||
-- Get plugins order
|
||||
local order, err = datastore:get("plugins_order")
|
||||
local order, err = datastore:get("plugins_order", true)
|
||||
if not order then
|
||||
logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
|
||||
return
|
||||
end
|
||||
order = cjson.decode(order)
|
||||
|
||||
-- Call log_stream() methods
|
||||
logger:log(ngx.INFO, "calling log_stream() methods of plugins ...")
|
||||
|
|
@ -44,7 +43,7 @@ for i, plugin_id in ipairs(order.log_stream) do
|
|||
-- Check if plugin has log_stream method
|
||||
if plugin_lua.log_stream ~= nil then
|
||||
-- New call
|
||||
local ok, plugin_obj = helpers.new_plugin(plugin_lua)
|
||||
local ok, plugin_obj = helpers.new_plugin(plugin_lua, ctx)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, plugin_obj)
|
||||
else
|
||||
|
|
@ -65,10 +64,13 @@ end
|
|||
logger:log(ngx.INFO, "called log_stream() methods of plugins")
|
||||
|
||||
-- Display reason at info level
|
||||
if ngx.ctx.reason then
|
||||
logger:log(ngx.INFO, "client was denied with reason : " .. ngx.ctx.reason)
|
||||
if ctx.reason then
|
||||
logger:log(ngx.INFO, "client was denied with reason : " .. ctx.reason)
|
||||
end
|
||||
|
||||
-- Save ctx
|
||||
ngx.ctx = ctx
|
||||
|
||||
logger:log(ngx.INFO, "log phase ended")
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
preread_by_lua_block {
|
||||
|
||||
ngx.ctx
|
||||
local class = require "middleclass"
|
||||
local clogger = require "bunkerweb.logger"
|
||||
local helpers = require "bunkerweb.helpers"
|
||||
|
|
@ -15,7 +15,7 @@ logger:log(ngx.INFO, "preread phase started")
|
|||
|
||||
-- Fill ctx
|
||||
logger:log(ngx.INFO, "filling ngx.ctx ...")
|
||||
local ok, ret, errors = helpers.fill_ctx()
|
||||
local ok, ret, errors, ctx = helpers.fill_ctx()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
|
||||
elseif errors then
|
||||
|
|
@ -26,27 +26,24 @@ end
|
|||
logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
|
||||
|
||||
-- Process bans as soon as possible
|
||||
local banned, reason, ttl = utils.is_banned(ngx.ctx.bw.remote_addr)
|
||||
if banned == nil then
|
||||
logger:log(ngx.ERR, "can't check if IP " .. ngx.ctx.bw.remote_addr .. " is banned : " .. reason)
|
||||
elseif banned then
|
||||
logger:log(ngx.WARN, "IP " .. ngx.ctx.bw.remote_addr .. " is banned with reason " .. reason .. " (" .. tostring(ttl) .. "s remaining)")
|
||||
return ngx.exit(utils.get_deny_status())
|
||||
else
|
||||
logger:log(ngx.INFO, "IP " .. ngx.ctx.bw.remote_addr .. " is not banned")
|
||||
if ctx.bw.is_whitelisted ~= "yes" then
|
||||
local banned, reason, ttl = utils.is_banned(ctx.bw.remote_addr)
|
||||
if banned == nil then
|
||||
logger:log(ngx.ERR, "can't check if IP " .. ctx.bw.remote_addr .. " is banned : " .. reason)
|
||||
elseif banned then
|
||||
logger:log(ngx.WARN, "IP " .. ctx.bw.remote_addr .. " is banned with reason " .. reason .. " (" .. tostring(ttl) .. "s remaining)")
|
||||
return ngx.exit(utils.get_deny_status())
|
||||
else
|
||||
logger:log(ngx.INFO, "IP " .. ctx.bw.remote_addr .. " is not banned")
|
||||
end
|
||||
end
|
||||
|
||||
-- Get plugins order
|
||||
local order, err = datastore:get("plugins_order")
|
||||
local order, err = datastore:get("plugins_order", true)
|
||||
if not order then
|
||||
logger:log(ngx.ERR, "can't get plugins order from datastore : " .. err)
|
||||
local ok, err = lock:unlock()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "lock:unlock() failed : " .. err)
|
||||
end
|
||||
return
|
||||
end
|
||||
order = cjson.decode(order)
|
||||
|
||||
-- Call preread() methods
|
||||
logger:log(ngx.INFO, "calling preread() methods of plugins ...")
|
||||
|
|
@ -62,7 +59,7 @@ for i, plugin_id in ipairs(order.preread) do
|
|||
-- Check if plugin has preread method
|
||||
if plugin_lua.preread ~= nil then
|
||||
-- New call
|
||||
local ok, plugin_obj = helpers.new_plugin(plugin_lua)
|
||||
local ok, plugin_obj = helpers.new_plugin(plugin_lua, ctx)
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, plugin_obj)
|
||||
else
|
||||
|
|
@ -75,8 +72,8 @@ for i, plugin_id in ipairs(order.preread) do
|
|||
logger:log(ngx.INFO, plugin_id .. ":preread() call successful : " .. ret.msg)
|
||||
end
|
||||
if ret.status then
|
||||
if ret.status == utils.get_deny_status() then
|
||||
ngx.ctx.reason = plugin_id
|
||||
if ret.status == utils.get_deny_status(ctx) then
|
||||
ctx.bw.reason = plugin_id
|
||||
logger:log(ngx.WARN, "denied preread from " .. plugin_id .. " : " .. ret.msg)
|
||||
else
|
||||
logger:log(ngx.NOTICE, plugin_id .. " returned status " .. tostring(ret.status) .. " : " .. ret.msg)
|
||||
|
|
@ -92,6 +89,9 @@ for i, plugin_id in ipairs(order.preread) do
|
|||
end
|
||||
logger:log(ngx.INFO, "called preread() methods of plugins")
|
||||
|
||||
-- Save ctx
|
||||
ngx.ctx = ctx
|
||||
|
||||
logger:log(ngx.INFO, "preread phase ended")
|
||||
|
||||
-- Return status if needed
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ end
|
|||
|
||||
local antibot = class("antibot", plugin)
|
||||
|
||||
function antibot:initialize()
|
||||
function antibot:initialize(ctx)
|
||||
-- Call parent initialize
|
||||
plugin.initialize(self, "antibot")
|
||||
plugin.initialize(self, "antibot", ctx)
|
||||
end
|
||||
|
||||
function antibot:access()
|
||||
|
|
@ -27,18 +27,18 @@ function antibot:access()
|
|||
end
|
||||
|
||||
-- Get session data
|
||||
local session, err = utils.get_session("antibot")
|
||||
local session, err = utils.get_session("antibot", self.ctx)
|
||||
if not session then
|
||||
return self:ret(false, "can't get session : " .. err, ngx.HTTP_INTERNAL_SERVER_ERROR)
|
||||
end
|
||||
self.session = session
|
||||
self.session_data = utils.get_session_data(self.session)
|
||||
self.session_data = utils.get_session_data(self.session, self.ctx)
|
||||
-- Check if session is valid
|
||||
self:check_session()
|
||||
|
||||
-- Don't go further if client resolved the challenge
|
||||
if self.session_data.resolved then
|
||||
if ngx.ctx.bw.uri == self.variables["ANTIBOT_URI"] then
|
||||
if self.ctx.bw.uri == self.variables["ANTIBOT_URI"] then
|
||||
return self:ret(true, "client already resolved the challenge", nil, self.session_data.original_uri)
|
||||
end
|
||||
return self:ret(true, "client already resolved the challenge")
|
||||
|
|
@ -52,7 +52,7 @@ function antibot:access()
|
|||
end
|
||||
|
||||
-- Redirect to challenge page
|
||||
if ngx.ctx.bw.uri ~= self.variables["ANTIBOT_URI"] then
|
||||
if self.ctx.bw.uri ~= self.variables["ANTIBOT_URI"] then
|
||||
return self:ret(true, "redirecting client to the challenge uri", nil, self.variables["ANTIBOT_URI"])
|
||||
end
|
||||
|
||||
|
|
@ -62,13 +62,13 @@ function antibot:access()
|
|||
end
|
||||
|
||||
-- Display challenge needed
|
||||
if ngx.ctx.bw.request_method == "GET" then
|
||||
ngx.ctx.bw.antibot_display_content = true
|
||||
if self.ctx.bw.request_method == "GET" then
|
||||
self.ctx.bw.antibot_display_content = true
|
||||
return self:ret(true, "displaying challenge to client", ngx.OK)
|
||||
end
|
||||
|
||||
-- Check challenge
|
||||
if ngx.ctx.bw.request_method == "POST" then
|
||||
if self.ctx.bw.request_method == "POST" then
|
||||
local ok, err, redirect = self:check_challenge()
|
||||
local set_ok, set_err = self:set_session_data()
|
||||
if not set_ok then
|
||||
|
|
@ -87,12 +87,12 @@ function antibot:access()
|
|||
if not ok then
|
||||
return self:ret(false, "can't save session : " .. err, ngx.HTTP_INTERNAL_SERVER_ERROR)
|
||||
end
|
||||
ngx.ctx.bw.antibot_display_content = true
|
||||
self.ctx.bw.antibot_display_content = true
|
||||
return self:ret(true, "displaying challenge to client", ngx.OK)
|
||||
end
|
||||
|
||||
-- Method is suspicious, let's deny the request
|
||||
return self:ret(true, "unsupported HTTP method for antibot", utils.get_deny_status())
|
||||
return self:ret(true, "unsupported HTTP method for antibot", utils.get_deny_status(self.ctx))
|
||||
end
|
||||
|
||||
function antibot:content()
|
||||
|
|
@ -102,17 +102,17 @@ function antibot:content()
|
|||
end
|
||||
|
||||
-- Check if display content is needed
|
||||
if not ngx.ctx.bw.antibot_display_content then
|
||||
if not self.ctx.bw.antibot_display_content then
|
||||
return self:ret(true, "display content not needed", nil, "/")
|
||||
end
|
||||
|
||||
-- Get session data
|
||||
local session, err = utils.get_session("antibot")
|
||||
local session, err = utils.get_session("antibot", self.ctx)
|
||||
if not session then
|
||||
return self:ret(false, "can't get session : " .. err, ngx.HTTP_INTERNAL_SERVER_ERROR)
|
||||
end
|
||||
self.session = session
|
||||
self.session_data = utils.get_session_data(self.session)
|
||||
self.session_data = utils.get_session_data(self.session, self.ctx)
|
||||
|
||||
-- Direct access without session
|
||||
if not self.session_data.prepared then
|
||||
|
|
@ -155,7 +155,7 @@ end
|
|||
|
||||
function antibot:set_session_data()
|
||||
if self.session_updated then
|
||||
local ok, err = utils.set_session_data(self.session, self.session_data)
|
||||
local ok, err = utils.set_session_data(self.session, self.session_data, self.ctx)
|
||||
if not ok then
|
||||
return false, err
|
||||
end
|
||||
|
|
@ -172,8 +172,8 @@ function antibot:prepare_challenge()
|
|||
self.session_data.time_resolve = ngx.now()
|
||||
self.session_data.type = self.variables["USE_ANTIBOT"]
|
||||
self.session_data.resolved = false
|
||||
self.session_data.original_uri = ngx.ctx.bw.request_uri
|
||||
if ngx.ctx.bw.uri == self.variables["ANTIBOT_URI"] then
|
||||
self.session_data.original_uri = self.ctx.bw.request_uri
|
||||
if self.ctx.bw.uri == self.variables["ANTIBOT_URI"] then
|
||||
self.session_data.original_uri = "/"
|
||||
end
|
||||
if self.variables["USE_ANTIBOT"] == "cookie" then
|
||||
|
|
@ -295,7 +295,7 @@ function antibot:check_challenge()
|
|||
method = "POST",
|
||||
body = "secret=" ..
|
||||
self.variables["ANTIBOT_RECAPTCHA_SECRET"] ..
|
||||
"&response=" .. args["token"] .. "&remoteip=" .. ngx.ctx.bw.remote_addr,
|
||||
"&response=" .. args["token"] .. "&remoteip=" .. self.ctx.bw.remote_addr,
|
||||
headers = {
|
||||
["Content-Type"] = "application/x-www-form-urlencoded"
|
||||
}
|
||||
|
|
@ -331,7 +331,7 @@ function antibot:check_challenge()
|
|||
method = "POST",
|
||||
body = "secret=" ..
|
||||
self.variables["ANTIBOT_HCAPTCHA_SECRET"] ..
|
||||
"&response=" .. args["token"] .. "&remoteip=" .. ngx.ctx.bw.remote_addr,
|
||||
"&response=" .. args["token"] .. "&remoteip=" .. self.ctx.bw.remote_addr,
|
||||
headers = {
|
||||
["Content-Type"] = "application/x-www-form-urlencoded"
|
||||
}
|
||||
|
|
@ -366,7 +366,7 @@ function antibot:check_challenge()
|
|||
local data = {
|
||||
secret=self.variables["ANTIBOT_TURNSTILE_SECRET"],
|
||||
response=args["token"],
|
||||
remoteip=ngx.ctx.bw.remote_addr
|
||||
remoteip=self.ctx.bw.remote_addr
|
||||
}
|
||||
local res, err = httpc:request_uri("https://challenges.cloudflare.com/turnstile/v0/siteverify", {
|
||||
method = "POST",
|
||||
|
|
|
|||
|
|
@ -3,17 +3,24 @@ location {{ ANTIBOT_URI }} {
|
|||
default_type 'text/html';
|
||||
root /usr/share/bunkerweb/core/antibot/files;
|
||||
content_by_lua_block {
|
||||
|
||||
local cantibot = require "antibot.antibot"
|
||||
local clogger = require "bunkerweb.logger"
|
||||
local antibot = cantibot:new()
|
||||
local logger = clogger:new("ANTIBOT")
|
||||
local ret = antibot:content()
|
||||
local logger = require "bunkerweb.logger":new("ANTIBOT")
|
||||
local helpers = require "bunkerweb.helpers"
|
||||
local ok, ret, errors, ctx = helpers.fill_ctx()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "fill_ctx() failed : " .. ret)
|
||||
elseif errors then
|
||||
for i, error in ipairs(errors) do
|
||||
logger:log(ngx.ERR, "fill_ctx() error " .. tostring(i) .. " : " .. error)
|
||||
end
|
||||
end
|
||||
local antibot = require "antibot.antibot":new(ctx)
|
||||
local ret = antibot:content()
|
||||
if not ret.ret then
|
||||
logger:log(ngx.ERR, "antibot:content() failed : " .. ret.msg)
|
||||
else
|
||||
logger:log(ngx.INFO, "antibot:content() success : " .. ret.msg)
|
||||
end
|
||||
ngx.ctx = ctx
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
|
|
@ -4,14 +4,14 @@ local utils = require "bunkerweb.utils"
|
|||
|
||||
local badbehavior = class("badbehavior", plugin)
|
||||
|
||||
function badbehavior:initialize()
|
||||
function badbehavior:initialize(ctx)
|
||||
-- Call parent initialize
|
||||
plugin.initialize(self, "badbehavior")
|
||||
plugin.initialize(self, "badbehavior", ctx)
|
||||
end
|
||||
|
||||
function badbehavior:log()
|
||||
-- Check if we are whitelisted
|
||||
if ngx.ctx.bw.is_whitelisted == "yes" then
|
||||
if self.ctx.bw.is_whitelisted == "yes" then
|
||||
return self:ret(true, "client is whitelisted")
|
||||
end
|
||||
-- Check if bad behavior is activated
|
||||
|
|
@ -23,12 +23,12 @@ function badbehavior:log()
|
|||
return self:ret(true, "not increasing counter")
|
||||
end
|
||||
-- Check if we are already banned
|
||||
local banned, err = self.datastore:get("bans_ip_" .. ngx.ctx.bw.remote_addr)
|
||||
local banned, err = self.datastore:get("bans_ip_" .. self.ctx.bw.remote_addr)
|
||||
if banned then
|
||||
return self:ret(true, "already banned")
|
||||
end
|
||||
-- Call increase function later and with cosocket enabled
|
||||
local ok, err = ngx.timer.at(0, badbehavior.increase, ngx.ctx.bw.remote_addr,
|
||||
local ok, err = ngx.timer.at(0, badbehavior.increase, self.ctx.bw.remote_addr,
|
||||
tonumber(self.variables["BAD_BEHAVIOR_COUNT_TIME"]), tonumber(self.variables["BAD_BEHAVIOR_BAN_TIME"]),
|
||||
tonumber(self.variables["BAD_BEHAVIOR_THRESHOLD"]), self.use_redis)
|
||||
if not ok then
|
||||
|
|
|
|||
|
|
@ -8,17 +8,17 @@ local ipmatcher = require "resty.ipmatcher"
|
|||
|
||||
local blacklist = class("blacklist", plugin)
|
||||
|
||||
function blacklist:initialize()
|
||||
function blacklist:initialize(ctx)
|
||||
-- Call parent initialize
|
||||
plugin.initialize(self, "blacklist")
|
||||
plugin.initialize(self, "blacklist", ctx)
|
||||
-- Decode lists
|
||||
if ngx.get_phase() ~= "init" and self:is_needed() then
|
||||
local lists, err = self.datastore:get("plugin_blacklist_lists")
|
||||
local lists, err = self.datastore:get("plugin_blacklist_lists", true)
|
||||
if not lists then
|
||||
self.logger:log(ngx.ERR, err)
|
||||
self.lists = {}
|
||||
else
|
||||
self.lists = cjson.decode(lists)
|
||||
self.lists = lists
|
||||
end
|
||||
local kinds = {
|
||||
["IP"] = {},
|
||||
|
|
@ -49,7 +49,7 @@ function blacklist:is_needed()
|
|||
return false
|
||||
end
|
||||
-- Request phases (no default)
|
||||
if self.is_request and (ngx.ctx.bw.server_name ~= "_") then
|
||||
if self.is_request and (self.ctx.bw.server_name ~= "_") then
|
||||
return self.variables["USE_BLACKLIST"] == "yes"
|
||||
end
|
||||
-- Other cases : at least one service uses it
|
||||
|
|
@ -91,7 +91,7 @@ function blacklist:init()
|
|||
end
|
||||
end
|
||||
-- Load them into datastore
|
||||
local ok, err = self.datastore:set("plugin_blacklist_lists", cjson.encode(blacklists))
|
||||
local ok, err = self.datastore:set("plugin_blacklist_lists", blacklists, nil, true)
|
||||
if not ok then
|
||||
return self:ret(false, "can't store blacklist list into datastore : " .. err)
|
||||
end
|
||||
|
|
@ -105,13 +105,13 @@ function blacklist:access()
|
|||
end
|
||||
-- Check the caches
|
||||
local checks = {
|
||||
["IP"] = "ip" .. ngx.ctx.bw.remote_addr
|
||||
["IP"] = "ip" .. self.ctx.bw.remote_addr
|
||||
}
|
||||
if ngx.ctx.bw.http_user_agent then
|
||||
checks["UA"] = "ua" .. ngx.ctx.bw.http_user_agent
|
||||
if self.ctx.bw.http_user_agent then
|
||||
checks["UA"] = "ua" .. self.ctx.bw.http_user_agent
|
||||
end
|
||||
if ngx.ctx.bw.uri then
|
||||
checks["URI"] = "uri" .. ngx.ctx.bw.uri
|
||||
if self.ctx.bw.uri then
|
||||
checks["URI"] = "uri" .. self.ctx.bw.uri
|
||||
end
|
||||
local already_cached = {
|
||||
["IP"] = false,
|
||||
|
|
@ -123,7 +123,7 @@ function blacklist:access()
|
|||
if not ok then
|
||||
self.logger:log(ngx.ERR, "error while checking cache : " .. cached)
|
||||
elseif cached and cached ~= "ok" then
|
||||
return self:ret(true, k .. " is in cached blacklist (info : " .. cached .. ")", utils.get_deny_status())
|
||||
return self:ret(true, k .. " is in cached blacklist (info : " .. cached .. ")", utils.get_deny_status(self.ctx))
|
||||
end
|
||||
if ok and cached then
|
||||
already_cached[k] = true
|
||||
|
|
@ -145,7 +145,7 @@ function blacklist:access()
|
|||
self.logger:log(ngx.ERR, "error while adding element to cache : " .. err)
|
||||
end
|
||||
if blacklisted ~= "ok" then
|
||||
return self:ret(true, k .. " is blacklisted (info : " .. blacklisted .. ")", utils.get_deny_status())
|
||||
return self:ret(true, k .. " is blacklisted (info : " .. blacklisted .. ")", utils.get_deny_status(self.ctx))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -161,16 +161,16 @@ end
|
|||
|
||||
function blacklist:kind_to_ele(kind)
|
||||
if kind == "IP" then
|
||||
return "ip" .. ngx.ctx.bw.remote_addr
|
||||
return "ip" .. self.ctx.bw.remote_addr
|
||||
elseif kind == "UA" then
|
||||
return "ua" .. ngx.ctx.bw.http_user_agent
|
||||
return "ua" .. self.ctx.bw.http_user_agent
|
||||
elseif kind == "URI" then
|
||||
return "uri" .. ngx.ctx.bw.uri
|
||||
return "uri" .. self.ctx.bw.uri
|
||||
end
|
||||
end
|
||||
|
||||
function blacklist:is_in_cache(ele)
|
||||
local ok, data = self.cachestore:get("plugin_blacklist_" .. ngx.ctx.bw.server_name .. ele)
|
||||
local ok, data = self.cachestore:get("plugin_blacklist_" .. self.ctx.bw.server_name .. ele)
|
||||
if not ok then
|
||||
return false, data
|
||||
end
|
||||
|
|
@ -178,7 +178,7 @@ function blacklist:is_in_cache(ele)
|
|||
end
|
||||
|
||||
function blacklist:add_to_cache(ele, value)
|
||||
local ok, err = self.cachestore:set("plugin_blacklist_" .. ngx.ctx.bw.server_name .. ele, value, 86400)
|
||||
local ok, err = self.cachestore:set("plugin_blacklist_" .. self.ctx.bw.server_name .. ele, value, 86400)
|
||||
if not ok then
|
||||
return false, err
|
||||
end
|
||||
|
|
@ -202,7 +202,7 @@ function blacklist:is_blacklisted_ip()
|
|||
if not ipm then
|
||||
return nil, err
|
||||
end
|
||||
local match, err = ipm:match(ngx.ctx.bw.remote_addr)
|
||||
local match, err = ipm:match(self.ctx.bw.remote_addr)
|
||||
if err then
|
||||
return nil, err
|
||||
end
|
||||
|
|
@ -212,7 +212,7 @@ function blacklist:is_blacklisted_ip()
|
|||
if not ipm then
|
||||
return nil, err
|
||||
end
|
||||
local match, err = ipm:match(ngx.ctx.bw.remote_addr)
|
||||
local match, err = ipm:match(self.ctx.bw.remote_addr)
|
||||
if err then
|
||||
return nil, err
|
||||
end
|
||||
|
|
@ -223,12 +223,12 @@ function blacklist:is_blacklisted_ip()
|
|||
|
||||
-- Check if rDNS is needed
|
||||
local check_rdns = true
|
||||
if self.variables["BLACKLIST_RDNS_GLOBAL"] == "yes" and not ngx.ctx.bw.ip_is_global then
|
||||
if self.variables["BLACKLIST_RDNS_GLOBAL"] == "yes" and not self.ctx.bw.ip_is_global then
|
||||
check_rdns = false
|
||||
end
|
||||
if check_rdns then
|
||||
-- Get rDNS
|
||||
local rdns_list, err = utils.get_rdns(ngx.ctx.bw.remote_addr)
|
||||
local rdns_list, err = utils.get_rdns(self.ctx.bw.remote_addr)
|
||||
if rdns_list then
|
||||
-- Check if rDNS is in ignore list
|
||||
local ignore = false
|
||||
|
|
@ -256,10 +256,10 @@ function blacklist:is_blacklisted_ip()
|
|||
end
|
||||
|
||||
-- Check if ASN is in ignore list
|
||||
if ngx.ctx.bw.ip_is_global then
|
||||
local asn, err = utils.get_asn(ngx.ctx.bw.remote_addr)
|
||||
if self.ctx.bw.ip_is_global then
|
||||
local asn, err = utils.get_asn(self.ctx.bw.remote_addr)
|
||||
if not asn then
|
||||
self.logger:log(ngx.ERR, "can't get ASN of IP " .. ngx.ctx.bw.remote_addr .. " : " .. err)
|
||||
self.logger:log(ngx.ERR, "can't get ASN of IP " .. self.ctx.bw.remote_addr .. " : " .. err)
|
||||
else
|
||||
local ignore = false
|
||||
for i, ignore_asn in ipairs(self.lists["IGNORE_ASN"]) do
|
||||
|
|
@ -287,7 +287,7 @@ function blacklist:is_blacklisted_uri()
|
|||
-- Check if URI is in ignore list
|
||||
local ignore = false
|
||||
for i, ignore_uri in ipairs(self.lists["IGNORE_URI"]) do
|
||||
if utils.regex_match(ngx.ctx.bw.uri, ignore_uri) then
|
||||
if utils.regex_match(self.ctx.bw.uri, ignore_uri) then
|
||||
ignore = true
|
||||
break
|
||||
end
|
||||
|
|
@ -295,7 +295,7 @@ function blacklist:is_blacklisted_uri()
|
|||
-- Check if URI is in blacklist
|
||||
if not ignore then
|
||||
for i, uri in ipairs(self.lists["URI"]) do
|
||||
if utils.regex_match(ngx.ctx.bw.uri, uri) then
|
||||
if utils.regex_match(self.ctx.bw.uri, uri) then
|
||||
return true, "URI " .. uri
|
||||
end
|
||||
end
|
||||
|
|
@ -308,7 +308,7 @@ function blacklist:is_blacklisted_ua()
|
|||
-- Check if UA is in ignore list
|
||||
local ignore = false
|
||||
for i, ignore_ua in ipairs(self.lists["IGNORE_USER_AGENT"]) do
|
||||
if utils.regex_match(ngx.ctx.bw.http_user_agent, ignore_ua) then
|
||||
if utils.regex_match(self.ctx.bw.http_user_agent, ignore_ua) then
|
||||
ignore = true
|
||||
break
|
||||
end
|
||||
|
|
@ -316,7 +316,7 @@ function blacklist:is_blacklisted_ua()
|
|||
-- Check if UA is in blacklist
|
||||
if not ignore then
|
||||
for i, ua in ipairs(self.lists["USER_AGENT"]) do
|
||||
if utils.regex_match(ngx.ctx.bw.http_user_agent, ua) then
|
||||
if utils.regex_match(self.ctx.bw.http_user_agent, ua) then
|
||||
return true, "UA " .. ua
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,16 +7,16 @@ local http = require "resty.http"
|
|||
|
||||
local bunkernet = class("bunkernet", plugin)
|
||||
|
||||
function bunkernet:initialize()
|
||||
function bunkernet:initialize(ctx)
|
||||
-- Call parent initialize
|
||||
plugin.initialize(self, "bunkernet")
|
||||
plugin.initialize(self, "bunkernet", ctx)
|
||||
-- Get BunkerNet ID and save info
|
||||
if ngx.get_phase() ~= "init" and self:is_needed() then
|
||||
local id, err = self.datastore:get("plugin_bunkernet_id")
|
||||
local id, err = self.datastore:get("plugin_bunkernet_id", true)
|
||||
if id then
|
||||
self.bunkernet_id = id
|
||||
self.version = (ngx.ctx.bw and ngx.ctx.bw.version) or utils.get_version()
|
||||
self.integration = (ngx.ctx.bw and ngx.ctx.bw.integration) or utils.get_integration()
|
||||
self.version = (self.ctx and self.ctx.bw.version) or utils.get_version()
|
||||
self.integration = (self.ctx and self.ctx.bw.integration) or utils.get_integration()
|
||||
else
|
||||
self.logger:log(ngx.ERR, "can't get BunkerNet ID from datastore : " .. err)
|
||||
end
|
||||
|
|
@ -29,7 +29,7 @@ function bunkernet:is_needed()
|
|||
return false
|
||||
end
|
||||
-- Request phases (no default)
|
||||
if self.is_request and (ngx.ctx.bw.server_name ~= "_") then
|
||||
if self.is_request and (self.ctx.bw.server_name ~= "_") then
|
||||
return self.variables["USE_BUNKERNET"] == "yes"
|
||||
end
|
||||
-- Other cases : at least one service uses it
|
||||
|
|
@ -75,7 +75,7 @@ function bunkernet:init()
|
|||
local id = f:read("*all"):gsub("[\r\n]", "")
|
||||
f:close()
|
||||
-- Store ID in datastore
|
||||
local ok, err = self.datastore:set("plugin_bunkernet_id", id)
|
||||
local ok, err = self.datastore:set("plugin_bunkernet_id", id, nil, true)
|
||||
if not ok then
|
||||
return self:ret(false, "can't save instance ID to the datastore : " .. err)
|
||||
end
|
||||
|
|
@ -100,7 +100,7 @@ function bunkernet:init()
|
|||
return self:ret(false, "error while reading database : " .. err)
|
||||
end
|
||||
f:close()
|
||||
local ok, err = self.datastore:set("plugin_bunkernet_db", cjson.encode(db))
|
||||
local ok, err = self.datastore:set("plugin_bunkernet_db", db, nil, true)
|
||||
if not ok then
|
||||
return self:ret(false, "can't store bunkernet database into datastore : " .. err)
|
||||
end
|
||||
|
|
@ -117,25 +117,24 @@ function bunkernet:access()
|
|||
return self:ret(false, "missing instance ID")
|
||||
end
|
||||
-- Check if IP is global
|
||||
if not ngx.ctx.bw.ip_is_global then
|
||||
if not self.ctx.bw.ip_is_global then
|
||||
return self:ret(true, "IP is not global")
|
||||
end
|
||||
-- Check if whitelisted
|
||||
if ngx.ctx.bw.is_whitelisted == "yes" then
|
||||
if self.ctx.bw.is_whitelisted == "yes" then
|
||||
return self:ret(true, "client is whitelisted")
|
||||
end
|
||||
-- Extract DB
|
||||
local db, err = self.datastore:get("plugin_bunkernet_db")
|
||||
local db, err = self.datastore:get("plugin_bunkernet_db", true)
|
||||
if db then
|
||||
db = cjson.decode(db)
|
||||
-- Check if is IP is present
|
||||
if #db.ip > 0 then
|
||||
local present, err = utils.is_ip_in_networks(ngx.ctx.bw.remote_addr, db.ip)
|
||||
local present, err = utils.is_ip_in_networks(self.ctx.bw.remote_addr, db.ip)
|
||||
if present == nil then
|
||||
return self:ret(false, "can't check if ip is in db : " .. err)
|
||||
end
|
||||
if present then
|
||||
return self:ret(true, "ip is in db", utils.get_deny_status())
|
||||
return self:ret(true, "ip is in db", utils.get_deny_status(self.ctx))
|
||||
end
|
||||
end
|
||||
else
|
||||
|
|
@ -156,7 +155,7 @@ function bunkernet:log(bypass_checks)
|
|||
end
|
||||
end
|
||||
-- Check if IP has been blocked
|
||||
local reason = utils.get_reason()
|
||||
local reason = utils.get_reason(self.ctx)
|
||||
if not reason then
|
||||
return self:ret(true, "ip is not blocked")
|
||||
end
|
||||
|
|
@ -164,7 +163,7 @@ function bunkernet:log(bypass_checks)
|
|||
return self:ret(true, "skipping report because the reason is bunkernet")
|
||||
end
|
||||
-- Check if IP is global
|
||||
if not ngx.ctx.bw.ip_is_global then
|
||||
if not self.ctx.bw.ip_is_global then
|
||||
return self:ret(true, "IP is not global")
|
||||
end
|
||||
-- TODO : check if IP has been reported recently
|
||||
|
|
@ -179,8 +178,8 @@ function bunkernet:log(bypass_checks)
|
|||
end
|
||||
end
|
||||
|
||||
local hdr, err = ngx.timer.at(0, report_callback, self, ngx.ctx.bw.remote_addr, reason, ngx.ctx.bw.request_method,
|
||||
ngx.ctx.bw.request_uri, ngx.req.get_headers())
|
||||
local hdr, err = ngx.timer.at(0, report_callback, self, self.ctx.bw.remote_addr, reason, self.ctx.bw.request_method,
|
||||
self.ctx.bw.request_uri, ngx.req.get_headers())
|
||||
if not hdr then
|
||||
return self:ret(false, "can't create report timer : " .. err)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ local utils = require "bunkerweb.utils"
|
|||
|
||||
local cors = class("cors", plugin)
|
||||
|
||||
function cors:initialize()
|
||||
function cors:initialize(ctx)
|
||||
-- Call parent initialize
|
||||
plugin.initialize(self, "cors")
|
||||
plugin.initialize(self, "cors", ctx)
|
||||
self.all_headers = {
|
||||
["CORS_EXPOSE_HEADERS"] = "Access-Control-Expose-Headers"
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ function cors:header()
|
|||
return self:ret(true, "service doesn't use CORS")
|
||||
end
|
||||
-- Skip if Origin header is not present
|
||||
if not ngx.ctx.bw.http_origin then
|
||||
if not self.ctx.bw.http_origin then
|
||||
return self:ret(true, "origin header not present")
|
||||
end
|
||||
-- Always include Vary header to prevent caching
|
||||
|
|
@ -40,22 +40,22 @@ function cors:header()
|
|||
ngx.header.Vary = "Origin"
|
||||
end
|
||||
-- Check if Origin is allowed
|
||||
if ngx.ctx.bw.http_origin and self.variables["CORS_DENY_REQUEST"] == "yes" and self.variables["CORS_ALLOW_ORIGIN"] ~= "*" and not utils.regex_match(ngx.ctx.bw.http_origin, self.variables["CORS_ALLOW_ORIGIN"]) then
|
||||
self.logger:log(ngx.WARN, "origin " .. ngx.ctx.bw.http_origin .. " is not allowed")
|
||||
return self:ret(true, "origin " .. ngx.ctx.bw.http_origin .. " is not allowed")
|
||||
if self.ctx.bw.http_origin and self.variables["CORS_DENY_REQUEST"] == "yes" and self.variables["CORS_ALLOW_ORIGIN"] ~= "*" and not utils.regex_match(self.ctx.bw.http_origin, self.variables["CORS_ALLOW_ORIGIN"]) then
|
||||
self.logger:log(ngx.WARN, "origin " .. self.ctx.bw.http_origin .. " is not allowed")
|
||||
return self:ret(true, "origin " .. self.ctx.bw.http_origin .. " is not allowed")
|
||||
end
|
||||
-- Set headers
|
||||
if self.variables["CORS_ALLOW_ORIGIN"] == "*" then
|
||||
ngx.header["Access-Control-Allow-Origin"] = "*"
|
||||
else
|
||||
ngx.header["Access-Control-Allow-Origin"] = ngx.ctx.bw.http_origin
|
||||
ngx.header["Access-Control-Allow-Origin"] = self.ctx.bw.http_origin
|
||||
end
|
||||
for variable, header in pairs(self.all_headers) do
|
||||
if self.variables[variable] ~= "" then
|
||||
ngx.header[header] = self.variables[variable]
|
||||
end
|
||||
end
|
||||
if ngx.ctx.bw.request_method == "OPTIONS" then
|
||||
if self.ctx.bw.request_method == "OPTIONS" then
|
||||
for variable, header in pairs(self.preflight_headers) do
|
||||
if variable == "CORS_ALLOW_CREDENTIALS" then
|
||||
if self.variables["CORS_ALLOW_CREDENTIALS"] == "yes" then
|
||||
|
|
@ -78,11 +78,11 @@ function cors:access()
|
|||
return self:ret(true, "service doesn't use CORS")
|
||||
end
|
||||
-- Deny as soon as possible if needed
|
||||
if ngx.ctx.bw.http_origin and self.variables["CORS_DENY_REQUEST"] == "yes" and self.variables["CORS_ALLOW_ORIGIN"] ~= "*" and not utils.regex_match(ngx.ctx.bw.http_origin, self.variables["CORS_ALLOW_ORIGIN"]) then
|
||||
return self:ret(true, "origin " .. ngx.ctx.bw.http_origin .. " is not allowed, denying access", utils.get_deny_status())
|
||||
if self.ctx.bw.http_origin and self.variables["CORS_DENY_REQUEST"] == "yes" and self.variables["CORS_ALLOW_ORIGIN"] ~= "*" and not utils.regex_match(self.ctx.bw.http_origin, self.variables["CORS_ALLOW_ORIGIN"]) then
|
||||
return self:ret(true, "origin " .. self.ctx.bw.http_origin .. " is not allowed, denying access", utils.get_deny_status(self.ctx))
|
||||
end
|
||||
-- Send CORS policy with a 204 (no content) status
|
||||
if ngx.ctx.bw.request_method == "OPTIONS" and ngx.ctx.bw.http_origin then
|
||||
if self.ctx.bw.request_method == "OPTIONS" and self.ctx.bw.http_origin then
|
||||
return self:ret(true, "preflight request", ngx.HTTP_NO_CONTENT)
|
||||
end
|
||||
return self:ret(true, "standard request")
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ local cjson = require "cjson"
|
|||
|
||||
local country = class("country", plugin)
|
||||
|
||||
function country:initialize()
|
||||
function country:initialize(ctx)
|
||||
-- Call parent initialize
|
||||
plugin.initialize(self, "country")
|
||||
plugin.initialize(self, "country", ctx)
|
||||
end
|
||||
|
||||
function country:access()
|
||||
|
|
@ -17,73 +17,73 @@ function country:access()
|
|||
return self:ret(true, "country not activated")
|
||||
end
|
||||
-- Check if IP is in cache
|
||||
local ok, data = self:is_in_cache(ngx.ctx.bw.remote_addr)
|
||||
local ok, data = self:is_in_cache(self.ctx.bw.remote_addr)
|
||||
if data then
|
||||
data = cjson.decode(data)
|
||||
if data.result == "ok" then
|
||||
return self:ret(true,
|
||||
"client IP " ..
|
||||
ngx.ctx.bw.remote_addr .. " is in country cache (not blacklisted, country = " .. data.country .. ")")
|
||||
self.ctx.bw.remote_addr .. " is in country cache (not blacklisted, country = " .. data.country .. ")")
|
||||
end
|
||||
return self:ret(true,
|
||||
"client IP " .. ngx.ctx.bw.remote_addr .. " is in country cache (blacklisted, country = " .. data.country .. ")",
|
||||
utils.get_deny_status())
|
||||
"client IP " .. self.ctx.bw.remote_addr .. " is in country cache (blacklisted, country = " .. data.country .. ")",
|
||||
utils.get_deny_status(self.ctx))
|
||||
end
|
||||
|
||||
-- Don't go further if IP is not global
|
||||
if not ngx.ctx.bw.ip_is_global then
|
||||
local ok, err = self:add_to_cache(ngx.ctx.bw.remote_addr, "unknown", "ok")
|
||||
if not self.ctx.bw.ip_is_global then
|
||||
local ok, err = self:add_to_cache(self.ctx.bw.remote_addr, "unknown", "ok")
|
||||
if not ok then
|
||||
return self:ret(false, "error while adding ip to cache : " .. err)
|
||||
end
|
||||
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is not global, skipping check")
|
||||
return self:ret(true, "client IP " .. self.ctx.bw.remote_addr .. " is not global, skipping check")
|
||||
end
|
||||
|
||||
-- Get the country of client
|
||||
local country, err = utils.get_country(ngx.ctx.bw.remote_addr)
|
||||
local country, err = utils.get_country(self.ctx.bw.remote_addr)
|
||||
if not country then
|
||||
return self:ret(false, "can't get country of client IP " .. ngx.ctx.bw.remote_addr .. " : " .. err)
|
||||
return self:ret(false, "can't get country of client IP " .. self.ctx.bw.remote_addr .. " : " .. err)
|
||||
end
|
||||
|
||||
-- Process whitelist first
|
||||
if self.variables["WHITELIST_COUNTRY"] ~= "" then
|
||||
for wh_country in self.variables["WHITELIST_COUNTRY"]:gmatch("%S+") do
|
||||
if wh_country == country then
|
||||
local ok, err = self:add_to_cache(ngx.ctx.bw.remote_addr, country, "ok")
|
||||
local ok, err = self:add_to_cache(self.ctx.bw.remote_addr, country, "ok")
|
||||
if not ok then
|
||||
return self:ret(false, "error while adding item to cache : " .. err)
|
||||
end
|
||||
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is whitelisted (country = " .. country .. ")")
|
||||
return self:ret(true, "client IP " .. self.ctx.bw.remote_addr .. " is whitelisted (country = " .. country .. ")")
|
||||
end
|
||||
end
|
||||
local ok, err = self:add_to_cache(ngx.ctx.bw.remote_addr, country, "ko")
|
||||
local ok, err = self:add_to_cache(self.ctx.bw.remote_addr, country, "ko")
|
||||
if not ok then
|
||||
return self:ret(false, "error while adding item to cache : " .. err)
|
||||
end
|
||||
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is not whitelisted (country = " .. country .. ")",
|
||||
utils.get_deny_status())
|
||||
return self:ret(true, "client IP " .. self.ctx.bw.remote_addr .. " is not whitelisted (country = " .. country .. ")",
|
||||
utils.get_deny_status(self.ctx))
|
||||
end
|
||||
|
||||
-- And then blacklist
|
||||
if self.variables["BLACKLIST_COUNTRY"] ~= "" then
|
||||
for bl_country in self.variables["BLACKLIST_COUNTRY"]:gmatch("%S+") do
|
||||
if bl_country == country then
|
||||
local ok, err = self:add_to_cache(ngx.ctx.bw.remote_addr, country, "ko")
|
||||
local ok, err = self:add_to_cache(self.ctx.bw.remote_addr, country, "ko")
|
||||
if not ok then
|
||||
return self:ret(false, "error while adding item to cache : " .. err)
|
||||
end
|
||||
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is blacklisted (country = " .. country .. ")",
|
||||
utils.get_deny_status())
|
||||
return self:ret(true, "client IP " .. self.ctx.bw.remote_addr .. " is blacklisted (country = " .. country .. ")",
|
||||
utils.get_deny_status(self.ctx))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Country IP is not in blacklist
|
||||
local ok, err = self:add_to_cache(ngx.ctx.bw.remote_addr, country, "ok")
|
||||
local ok, err = self:add_to_cache(self.ctx.bw.remote_addr, country, "ok")
|
||||
if not ok then
|
||||
return self:ret(false, "error while caching IP " .. ngx.ctx.bw.remote_addr .. " : " .. err)
|
||||
return self:ret(false, "error while caching IP " .. self.ctx.bw.remote_addr .. " : " .. err)
|
||||
end
|
||||
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is not blacklisted (country = " .. country .. ")")
|
||||
return self:ret(true, "client IP " .. self.ctx.bw.remote_addr .. " is not blacklisted (country = " .. country .. ")")
|
||||
end
|
||||
|
||||
function country:preread()
|
||||
|
|
@ -91,7 +91,7 @@ function country:preread()
|
|||
end
|
||||
|
||||
function country:is_in_cache(ip)
|
||||
local ok, data = self.cachestore:get("plugin_country_" .. ngx.ctx.bw.server_name .. ip)
|
||||
local ok, data = self.cachestore:get("plugin_country_" .. self.ctx.bw.server_name .. ip)
|
||||
if not ok then
|
||||
return false, data
|
||||
end
|
||||
|
|
@ -99,7 +99,7 @@ function country:is_in_cache(ip)
|
|||
end
|
||||
|
||||
function country:add_to_cache(ip, country, result)
|
||||
local ok, err = self.cachestore:set("plugin_country_" .. ngx.ctx.bw.server_name .. ip,
|
||||
local ok, err = self.cachestore:set("plugin_country_" .. self.ctx.bw.server_name .. ip,
|
||||
cjson.encode({ country = country, result = result }), 86400)
|
||||
if not ok then
|
||||
return false, err
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ local resolver = require "resty.dns.resolver"
|
|||
|
||||
local dnsbl = class("dnsbl", plugin)
|
||||
|
||||
function dnsbl:initialize()
|
||||
function dnsbl:initialize(ctx)
|
||||
-- Call parent initialize
|
||||
plugin.initialize(self, "dnsbl")
|
||||
plugin.initialize(self, "dnsbl", ctx)
|
||||
end
|
||||
|
||||
function dnsbl:init_worker()
|
||||
|
|
@ -56,25 +56,25 @@ function dnsbl:access()
|
|||
return self:ret(true, "dnsbl list is empty")
|
||||
end
|
||||
-- Don't go further if IP is not global
|
||||
if not ngx.ctx.bw.ip_is_global then
|
||||
if not self.ctx.bw.ip_is_global then
|
||||
return self:ret(true, "client IP is not global, skipping DNSBL check")
|
||||
end
|
||||
-- Check if IP is in cache
|
||||
local ok, cached = self:is_in_cache(ngx.ctx.bw.remote_addr)
|
||||
local ok, cached = self:is_in_cache(self.ctx.bw.remote_addr)
|
||||
if not ok then
|
||||
return self:ret(false, "error while checking cache : " .. cached)
|
||||
elseif cached then
|
||||
if cached == "ok" then
|
||||
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is in DNSBL cache (not blacklisted)")
|
||||
return self:ret(true, "client IP " .. self.ctx.bw.remote_addr .. " is in DNSBL cache (not blacklisted)")
|
||||
end
|
||||
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is in DNSBL cache (server = " .. cached .. ")",
|
||||
utils.get_deny_status())
|
||||
return self:ret(true, "client IP " .. self.ctx.bw.remote_addr .. " is in DNSBL cache (server = " .. cached .. ")",
|
||||
utils.get_deny_status(self.ctx))
|
||||
end
|
||||
-- Loop on DNSBL list
|
||||
local threads = {}
|
||||
for server in self.variables["DNSBL_LIST"]:gmatch("%S+") do
|
||||
-- Create thread
|
||||
local thread = ngx.thread.spawn(self.is_in_dnsbl, self, ngx.ctx.bw.remote_addr, server)
|
||||
local thread = ngx.thread.spawn(self.is_in_dnsbl, self, self.ctx.bw.remote_addr, server)
|
||||
threads[server] = thread
|
||||
end
|
||||
-- Wait for threads
|
||||
|
|
@ -124,17 +124,17 @@ function dnsbl:access()
|
|||
end
|
||||
-- Blacklisted by a server : add to cache and deny access
|
||||
if ret_threads then
|
||||
local ok, err = self:add_to_cache(ngx.ctx.bw.remote_addr, ret_server)
|
||||
local ok, err = self:add_to_cache(self.ctx.bw.remote_addr, ret_server)
|
||||
if not ok then
|
||||
return self:ret(false, "error while adding element to cache : " .. err)
|
||||
end
|
||||
return self:ret(true, "IP is blacklisted by " .. ret_server, utils.get_deny_status())
|
||||
return self:ret(true, "IP is blacklisted by " .. ret_server, utils.get_deny_status(self.ctx))
|
||||
end
|
||||
-- Error case
|
||||
return self:ret(false, ret_err)
|
||||
end
|
||||
-- IP is not in DNSBL
|
||||
local ok, err = self:add_to_cache(ngx.ctx.bw.remote_addr, "ok")
|
||||
local ok, err = self:add_to_cache(self.ctx.bw.remote_addr, "ok")
|
||||
if not ok then
|
||||
return self:ret(false, "IP is not in DNSBL (error = " .. err .. ")")
|
||||
end
|
||||
|
|
@ -146,7 +146,7 @@ function dnsbl:preread()
|
|||
end
|
||||
|
||||
function dnsbl:is_in_cache(ip)
|
||||
local ok, data = self.cachestore:get("plugin_dnsbl_" .. ngx.ctx.bw.server_name .. ip)
|
||||
local ok, data = self.cachestore:get("plugin_dnsbl_" .. self.ctx.bw.server_name .. ip)
|
||||
if not ok then
|
||||
return false, data
|
||||
end
|
||||
|
|
@ -154,7 +154,7 @@ function dnsbl:is_in_cache(ip)
|
|||
end
|
||||
|
||||
function dnsbl:add_to_cache(ip, value)
|
||||
local ok, err = self.cachestore:set("plugin_dnsbl_" .. ngx.ctx.bw.server_name .. ip, value, 86400)
|
||||
local ok, err = self.cachestore:set("plugin_dnsbl_" .. self.ctx.bw.server_name .. ip, value, 86400)
|
||||
if not ok then
|
||||
return false, err
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ end
|
|||
|
||||
local errors = class("errors", plugin)
|
||||
|
||||
function errors:initialize()
|
||||
function errors:initialize(ctx)
|
||||
-- Call parent initialize
|
||||
plugin.initialize(self, "errors")
|
||||
plugin.initialize(self, "errors", ctx)
|
||||
-- Default error texts
|
||||
self.default_errors = {
|
||||
["400"] = {
|
||||
|
|
|
|||
|
|
@ -7,17 +7,17 @@ local ipmatcher = require "resty.ipmatcher"
|
|||
|
||||
local greylist = class("greylist", plugin)
|
||||
|
||||
function greylist:initialize()
|
||||
function greylist:initialize(ctx)
|
||||
-- Call parent initialize
|
||||
plugin.initialize(self, "greylist")
|
||||
plugin.initialize(self, "greylist", ctx)
|
||||
-- Decode lists
|
||||
if ngx.get_phase() ~= "init" and self:is_needed() then
|
||||
local lists, err = self.datastore:get("plugin_greylist_lists")
|
||||
local lists, err = self.datastore:get("plugin_greylist_lists", true)
|
||||
if not lists then
|
||||
self.logger:log(ngx.ERR, err)
|
||||
self.lists = {}
|
||||
else
|
||||
self.lists = cjson.decode(lists)
|
||||
self.lists = lists
|
||||
end
|
||||
local kinds = {
|
||||
["IP"] = {},
|
||||
|
|
@ -43,7 +43,7 @@ function greylist:is_needed()
|
|||
return false
|
||||
end
|
||||
-- Request phases (no default)
|
||||
if self.is_request and (ngx.ctx.bw.server_name ~= "_") then
|
||||
if self.is_request and (self.ctx.bw.server_name ~= "_") then
|
||||
return self.variables["USE_GREYLIST"] == "yes"
|
||||
end
|
||||
-- Other cases : at least one service uses it
|
||||
|
|
@ -79,7 +79,7 @@ function greylist:init()
|
|||
end
|
||||
end
|
||||
-- Load them into datastore
|
||||
local ok, err = self.datastore:set("plugin_greylist_lists", cjson.encode(greylists))
|
||||
local ok, err = self.datastore:set("plugin_greylist_lists", greylists, nil, true)
|
||||
if not ok then
|
||||
return self:ret(false, "can't store greylist list into datastore : " .. err)
|
||||
end
|
||||
|
|
@ -93,13 +93,13 @@ function greylist:access()
|
|||
end
|
||||
-- Check the caches
|
||||
local checks = {
|
||||
["IP"] = "ip" .. ngx.ctx.bw.remote_addr
|
||||
["IP"] = "ip" .. self.ctx.bw.remote_addr
|
||||
}
|
||||
if ngx.ctx.bw.http_user_agent then
|
||||
checks["UA"] = "ua" .. ngx.ctx.bw.http_user_agent
|
||||
if self.ctx.bw.http_user_agent then
|
||||
checks["UA"] = "ua" .. self.ctx.bw.http_user_agent
|
||||
end
|
||||
if ngx.ctx.bw.uri then
|
||||
checks["URI"] = "uri" .. ngx.ctx.bw.uri
|
||||
if self.ctx.bw.uri then
|
||||
checks["URI"] = "uri" .. self.ctx.bw.uri
|
||||
end
|
||||
local already_cached = {
|
||||
["IP"] = false,
|
||||
|
|
@ -140,7 +140,7 @@ function greylist:access()
|
|||
end
|
||||
|
||||
-- Return
|
||||
return self:ret(true, "not in greylist", utils.get_deny_status())
|
||||
return self:ret(true, "not in greylist", utils.get_deny_status(self.ctx))
|
||||
end
|
||||
|
||||
function greylist:preread()
|
||||
|
|
@ -149,11 +149,11 @@ end
|
|||
|
||||
function greylist:kind_to_ele(kind)
|
||||
if kind == "IP" then
|
||||
return "ip" .. ngx.ctx.bw.remote_addr
|
||||
return "ip" .. self.ctx.bw.remote_addr
|
||||
elseif kind == "UA" then
|
||||
return "ua" .. ngx.ctx.bw.http_user_agent
|
||||
return "ua" .. self.ctx.bw.http_user_agent
|
||||
elseif kind == "URI" then
|
||||
return "uri" .. ngx.ctx.bw.uri
|
||||
return "uri" .. self.ctx.bw.uri
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ function greylist:is_greylisted_ip()
|
|||
if not ipm then
|
||||
return nil, err
|
||||
end
|
||||
local match, err = ipm:match(ngx.ctx.bw.remote_addr)
|
||||
local match, err = ipm:match(self.ctx.bw.remote_addr)
|
||||
if err then
|
||||
return nil, err
|
||||
end
|
||||
|
|
@ -184,12 +184,12 @@ function greylist:is_greylisted_ip()
|
|||
|
||||
-- Check if rDNS is needed
|
||||
local check_rdns = true
|
||||
if self.variables["GREYLIST_RDNS_GLOBAL"] == "yes" and not ngx.ctx.bw.ip_is_global then
|
||||
if self.variables["GREYLIST_RDNS_GLOBAL"] == "yes" and not self.ctx.bw.ip_is_global then
|
||||
check_rdns = false
|
||||
end
|
||||
if check_rdns then
|
||||
-- Get rDNS
|
||||
local rdns_list, err = utils.get_rdns(ngx.ctx.bw.remote_addr)
|
||||
local rdns_list, err = utils.get_rdns(self.ctx.bw.remote_addr)
|
||||
-- Check if rDNS is in greylist
|
||||
if rdns_list then
|
||||
for i, rdns in ipairs(rdns_list) do
|
||||
|
|
@ -205,10 +205,10 @@ function greylist:is_greylisted_ip()
|
|||
end
|
||||
|
||||
-- Check if ASN is in greylist
|
||||
if ngx.ctx.bw.ip_is_global then
|
||||
local asn, err = utils.get_asn(ngx.ctx.bw.remote_addr)
|
||||
if self.ctx.bw.ip_is_global then
|
||||
local asn, err = utils.get_asn(self.ctx.bw.remote_addr)
|
||||
if not asn then
|
||||
self.logger:log(ngx.ERR, "can't get ASN of IP " .. ngx.ctx.bw.remote_addr .. " : " .. err)
|
||||
self.logger:log(ngx.ERR, "can't get ASN of IP " .. self.ctx.bw.remote_addr .. " : " .. err)
|
||||
else
|
||||
for i, bl_asn in ipairs(self.lists["ASN"]) do
|
||||
if bl_asn == tostring(asn) then
|
||||
|
|
@ -225,7 +225,7 @@ end
|
|||
function greylist:is_greylisted_uri()
|
||||
-- Check if URI is in greylist
|
||||
for i, uri in ipairs(self.lists["URI"]) do
|
||||
if utils.regex_match(ngx.ctx.bw.uri, uri) then
|
||||
if utils.regex_match(self.ctx.bw.uri, uri) then
|
||||
return true, "URI " .. uri
|
||||
end
|
||||
end
|
||||
|
|
@ -236,7 +236,7 @@ end
|
|||
function greylist:is_greylisted_ua()
|
||||
-- Check if UA is in greylist
|
||||
for i, ua in ipairs(self.lists["USER_AGENT"]) do
|
||||
if utils.regex_match(ngx.ctx.bw.http_user_agent, ua) then
|
||||
if utils.regex_match(self.ctx.bw.http_user_agent, ua) then
|
||||
return true, "UA " .. ua
|
||||
end
|
||||
end
|
||||
|
|
@ -245,7 +245,7 @@ function greylist:is_greylisted_ua()
|
|||
end
|
||||
|
||||
function greylist:is_in_cache(ele)
|
||||
local ok, data = self.cachestore:get("plugin_greylist_" .. ngx.ctx.bw.server_name .. ele)
|
||||
local ok, data = self.cachestore:get("plugin_greylist_" .. self.ctx.bw.server_name .. ele)
|
||||
if not ok then
|
||||
return false, data
|
||||
end
|
||||
|
|
@ -253,7 +253,7 @@ function greylist:is_in_cache(ele)
|
|||
end
|
||||
|
||||
function greylist:add_to_cache(ele, value)
|
||||
local ok, err = self.cachestore:set("plugin_greylist_" .. ngx.ctx.bw.server_name .. ele, value, 86400)
|
||||
local ok, err = self.cachestore:set("plugin_greylist_" .. self.ctx.bw.server_name .. ele, value, 86400)
|
||||
if not ok then
|
||||
return false, err
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ function letsencrypt:initialize()
|
|||
end
|
||||
|
||||
function letsencrypt:access()
|
||||
if string.sub(ngx.ctx.bw.uri, 1, string.len("/.well-known/acme-challenge/")) == "/.well-known/acme-challenge/" then
|
||||
if string.sub(self.ctx.bw.uri, 1, string.len("/.well-known/acme-challenge/")) == "/.well-known/acme-challenge/" then
|
||||
self.logger:log(ngx.NOTICE, "got a visit from Let's Encrypt, let's whitelist it")
|
||||
return self:ret(true, "visit from LE", ngx.OK)
|
||||
end
|
||||
|
|
@ -19,8 +19,8 @@ function letsencrypt:access()
|
|||
end
|
||||
|
||||
function letsencrypt:api()
|
||||
if not string.match(ngx.ctx.bw.uri, "^/lets%-encrypt/challenge$") or
|
||||
(ngx.ctx.bw.request_method ~= "POST" and ngx.ctx.bw.request_method ~= "DELETE") then
|
||||
if not string.match(self.ctx.bw.uri, "^/lets%-encrypt/challenge$") or
|
||||
(self.ctx.bw.request_method ~= "POST" and self.ctx.bw.request_method ~= "DELETE") then
|
||||
return false, nil, nil
|
||||
end
|
||||
local acme_folder = "/var/tmp/bunkerweb/lets-encrypt/.well-known/acme-challenge/"
|
||||
|
|
@ -30,7 +30,7 @@ function letsencrypt:api()
|
|||
return true, ngx.HTTP_BAD_REQUEST, { status = "error", msg = "json body decoding failed" }
|
||||
end
|
||||
os.execute("mkdir -p " .. acme_folder)
|
||||
if ngx.ctx.bw.request_method == "POST" then
|
||||
if self.ctx.bw.request_method == "POST" then
|
||||
local file, err = io.open(acme_folder .. data.token, "w+")
|
||||
if not file then
|
||||
return true, ngx.HTTP_INTERNAL_SERVER_ERROR, { status = "error", msg = "can't write validation token : " .. err }
|
||||
|
|
@ -38,7 +38,7 @@ function letsencrypt:api()
|
|||
file:write(data.validation)
|
||||
file:close()
|
||||
return true, ngx.HTTP_OK, { status = "success", msg = "validation token written" }
|
||||
elseif ngx.ctx.bw.request_method == "DELETE" then
|
||||
elseif self.ctx.bw.request_method == "DELETE" then
|
||||
local ok, err = os.remove(acme_folder .. data.token)
|
||||
if not ok then
|
||||
return true, ngx.HTTP_INTERNAL_SERVER_ERROR, { status = "error", msg = "can't remove validation token : " .. err }
|
||||
|
|
|
|||
|
|
@ -14,12 +14,11 @@ function limit:initialize()
|
|||
if ngx.get_phase() ~= "init" and self:is_needed() then
|
||||
-- Get all rules from datastore
|
||||
local limited = false
|
||||
local all_rules, err = self.datastore:get("plugin_limit_rules")
|
||||
local all_rules, err = self.datastore:get("plugin_limit_rules", true)
|
||||
if not all_rules then
|
||||
self.logger:log(ngx.ERR, err)
|
||||
return
|
||||
end
|
||||
all_rules = cjson.decode(all_rules)
|
||||
self.rules = {}
|
||||
-- Extract global rules
|
||||
if all_rules.global then
|
||||
|
|
@ -28,8 +27,8 @@ function limit:initialize()
|
|||
end
|
||||
end
|
||||
-- Extract and overwrite if needed server rules
|
||||
if all_rules[ngx.ctx.bw.server_name] then
|
||||
for k, v in pairs(all_rules[ngx.ctx.bw.server_name]) do
|
||||
if all_rules[self.ctx.bw.server_name] then
|
||||
for k, v in pairs(all_rules[self.ctx.bw.server_name]) do
|
||||
self.rules[k] = v
|
||||
end
|
||||
end
|
||||
|
|
@ -42,7 +41,7 @@ function limit:is_needed()
|
|||
return false
|
||||
end
|
||||
-- Request phases (no default)
|
||||
if self.is_request and (ngx.ctx.bw.server_name ~= "_") then
|
||||
if self.is_request and (self.ctx.bw.server_name ~= "_") then
|
||||
return self.variables["USE_LIMIT_REQ"] == "yes"
|
||||
end
|
||||
-- Other cases : at least one service uses it
|
||||
|
|
@ -63,6 +62,7 @@ function limit:init()
|
|||
if variables == nil then
|
||||
return self:ret(false, err)
|
||||
end
|
||||
self.logger:log(ngx.ERR, cjson.encode(variables))
|
||||
-- Store URLs and rates
|
||||
local data = {}
|
||||
local i = 0
|
||||
|
|
@ -79,7 +79,7 @@ function limit:init()
|
|||
end
|
||||
end
|
||||
end
|
||||
local ok, err = self.datastore:set("plugin_limit_rules", cjson.encode(data))
|
||||
local ok, err = self.datastore:set("plugin_limit_rules", data, nil, true)
|
||||
if not ok then
|
||||
return self:ret(false, err)
|
||||
end
|
||||
|
|
@ -88,7 +88,7 @@ end
|
|||
|
||||
function limit:access()
|
||||
-- Check if we are whitelisted
|
||||
if ngx.ctx.bw.is_whitelisted == "yes" then
|
||||
if self.ctx.bw.is_whitelisted == "yes" then
|
||||
return self:ret(true, "client is whitelisted")
|
||||
end
|
||||
-- Check if access is needed
|
||||
|
|
@ -99,7 +99,7 @@ function limit:access()
|
|||
local rate = nil
|
||||
local uri = nil
|
||||
for k, v in pairs(self.rules) do
|
||||
if k ~= "/" and utils.regex_match(ngx.ctx.bw.uri, k) then
|
||||
if k ~= "/" and utils.regex_match(self.ctx.bw.uri, k) then
|
||||
rate = v
|
||||
uri = k
|
||||
break
|
||||
|
|
@ -110,7 +110,7 @@ function limit:access()
|
|||
rate = self.rules["/"]
|
||||
uri = "/"
|
||||
else
|
||||
return self:ret(true, "no rule for " .. ngx.ctx.bw.uri)
|
||||
return self:ret(true, "no rule for " .. self.ctx.bw.uri)
|
||||
end
|
||||
end
|
||||
-- Check if limit is reached
|
||||
|
|
@ -123,17 +123,17 @@ function limit:access()
|
|||
if limited then
|
||||
return self:ret(true,
|
||||
"client IP " ..
|
||||
ngx.ctx.bw.remote_addr ..
|
||||
self.ctx.bw.remote_addr ..
|
||||
" is limited for URL " ..
|
||||
ngx.ctx.bw.uri .. " (current rate = " .. current_rate .. "r/" .. rate_time .. " and max rate = " .. rate .. ")",
|
||||
self.ctx.bw.uri .. " (current rate = " .. current_rate .. "r/" .. rate_time .. " and max rate = " .. rate .. ")",
|
||||
ngx.HTTP_TOO_MANY_REQUESTS)
|
||||
end
|
||||
-- Limit not reached
|
||||
return self:ret(true,
|
||||
"client IP " ..
|
||||
ngx.ctx.bw.remote_addr ..
|
||||
self.ctx.bw.remote_addr ..
|
||||
" is not limited for URL " ..
|
||||
ngx.ctx.bw.uri .. " (current rate = " .. current_rate .. "r/" .. rate_time .. " and max rate = " .. rate .. ")")
|
||||
self.ctx.bw.uri .. " (current rate = " .. current_rate .. "r/" .. rate_time .. " and max rate = " .. rate .. ")")
|
||||
end
|
||||
|
||||
function limit:limit_req(rate_max, rate_time)
|
||||
|
|
@ -147,7 +147,7 @@ function limit:limit_req(rate_max, rate_time)
|
|||
timestamps = redis_timestamps
|
||||
-- Save the new timestamps
|
||||
local ok, err = self.datastore:set(
|
||||
"plugin_limit_" .. ngx.ctx.bw.server_name .. ngx.ctx.bw.remote_addr .. ngx.ctx.bw.uri,
|
||||
"plugin_limit_" .. self.ctx.bw.server_name .. self.ctx.bw.remote_addr .. self.ctx.bw.uri,
|
||||
cjson.encode(timestamps), delay)
|
||||
if not ok then
|
||||
return nil, "can't update timestamps : " .. err
|
||||
|
|
@ -171,7 +171,7 @@ end
|
|||
function limit:limit_req_local(rate_max, rate_time)
|
||||
-- Get timestamps
|
||||
local timestamps, err = self.datastore:get("plugin_limit_" ..
|
||||
ngx.ctx.bw.server_name .. ngx.ctx.bw.remote_addr .. ngx.ctx.bw.uri)
|
||||
self.ctx.bw.server_name .. self.ctx.bw.remote_addr .. self.ctx.bw.uri)
|
||||
if not timestamps and err ~= "not found" then
|
||||
return nil, err
|
||||
elseif err == "not found" then
|
||||
|
|
@ -183,7 +183,7 @@ function limit:limit_req_local(rate_max, rate_time)
|
|||
-- Save new timestamps if needed
|
||||
if updated then
|
||||
local ok, err = self.datastore:set(
|
||||
"plugin_limit_" .. ngx.ctx.bw.server_name .. ngx.ctx.bw.remote_addr .. ngx.ctx.bw.uri,
|
||||
"plugin_limit_" .. self.ctx.bw.server_name .. self.ctx.bw.remote_addr .. self.ctx.bw.uri,
|
||||
cjson.encode(new_timestamps), delay)
|
||||
if not ok then
|
||||
return nil, err
|
||||
|
|
@ -249,7 +249,7 @@ function limit:limit_req_redis(rate_max, rate_time)
|
|||
end
|
||||
-- Execute script
|
||||
local timestamps, err = self.clusterstore:call("eval", redis_script, 1,
|
||||
"plugin_limit_" .. ngx.ctx.bw.server_name .. ngx.ctx.bw.remote_addr .. ngx.ctx.bw.uri, rate_max, rate_time,
|
||||
"plugin_limit_" .. self.ctx.bw.server_name .. self.ctx.bw.remote_addr .. self.ctx.bw.uri, rate_max, rate_time,
|
||||
os.time(os.date("!*t")))
|
||||
if not timestamps then
|
||||
self.clusterstore:close()
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ end
|
|||
|
||||
function misc:access()
|
||||
-- Check if method is valid
|
||||
local method = ngx.ctx.bw.request_method
|
||||
local method = self.ctx.bw.request_method
|
||||
if not method or not utils.regex_match(method, "^[A-Z]+$") then
|
||||
return self:ret(true, "method is not valid", ngx.HTTP_BAD_REQUEST)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ function reversescan:access()
|
|||
local ret_err = nil
|
||||
for port in self.variables["REVERSE_SCAN_PORTS"]:gmatch("%S+") do
|
||||
-- Check if the scan is already cached
|
||||
local ok, cached = self:is_in_cache(ngx.ctx.bw.remote_addr .. ":" .. port)
|
||||
local ok, cached = self:is_in_cache(self.ctx.bw.remote_addr .. ":" .. port)
|
||||
if not ok then
|
||||
ret_threads = false
|
||||
ret_err = "error getting info from cachestore : " .. cached
|
||||
|
|
@ -30,11 +30,11 @@ function reversescan:access()
|
|||
-- Deny access if port opened
|
||||
elseif cached == "open" then
|
||||
ret_threads = true
|
||||
ret_err = "port " .. port .. " is opened for IP " .. ngx.ctx.bw.remote_addr
|
||||
ret_err = "port " .. port .. " is opened for IP " .. self.ctx.bw.remote_addr
|
||||
break
|
||||
-- Perform scan in a thread
|
||||
elseif not cached then
|
||||
local thread = ngx.thread.spawn(self.scan, ngx.ctx.bw.remote_addr, tonumber(port), tonumber(self.variables["REVERSE_SCAN_TIMEOUT"]))
|
||||
local thread = ngx.thread.spawn(self.scan, self.ctx.bw.remote_addr, tonumber(port), tonumber(self.variables["REVERSE_SCAN_TIMEOUT"]))
|
||||
threads[port] = thread
|
||||
end
|
||||
end
|
||||
|
|
@ -48,7 +48,7 @@ function reversescan:access()
|
|||
end
|
||||
-- Open port case
|
||||
if ret_threads then
|
||||
return self:ret(true, ret_err, utils.get_deny_status())
|
||||
return self:ret(true, ret_err, utils.get_deny_status(self.ctx))
|
||||
end
|
||||
-- Error case
|
||||
return self:ret(false, ret_err)
|
||||
|
|
@ -87,7 +87,7 @@ function reversescan:access()
|
|||
-- Port is opened
|
||||
if open then
|
||||
ret_threads = true
|
||||
ret_err = "port " .. port .. " is opened for IP " .. ngx.ctx.bw.remote_addr
|
||||
ret_err = "port " .. port .. " is opened for IP " .. self.ctx.bw.remote_addr
|
||||
break
|
||||
end
|
||||
end
|
||||
|
|
@ -101,7 +101,7 @@ function reversescan:access()
|
|||
end
|
||||
-- Cache results
|
||||
for port, result in pairs(results) do
|
||||
local ok, err = self:add_to_cache(ngx.ctx.bw.remote_addr .. ":" .. port, result)
|
||||
local ok, err = self:add_to_cache(self.ctx.bw.remote_addr .. ":" .. port, result)
|
||||
if not ok then
|
||||
return self:ret(false, "error while adding element to cache : " .. err)
|
||||
end
|
||||
|
|
@ -109,13 +109,13 @@ function reversescan:access()
|
|||
if ret_threads ~= nil then
|
||||
-- Open port case
|
||||
if ret_threads then
|
||||
return self:ret(true, ret_err, utils.get_deny_status())
|
||||
return self:ret(true, ret_err, utils.get_deny_status(self.ctx))
|
||||
end
|
||||
-- Error case
|
||||
return self:ret(false, ret_err)
|
||||
end
|
||||
-- No port opened
|
||||
return self:ret(true, "no port open for IP " .. ngx.ctx.bw.remote_addr)
|
||||
return self:ret(true, "no port open for IP " .. self.ctx.bw.remote_addr)
|
||||
end
|
||||
|
||||
function reversescan:preread()
|
||||
|
|
|
|||
|
|
@ -29,13 +29,13 @@ function sessions:set()
|
|||
return self:ret(true, "set not needed")
|
||||
end
|
||||
local checks = {
|
||||
["IP"] = ngx.ctx.bw.remote_addr,
|
||||
["USER_AGENT"] = ngx.ctx.bw.http_user_agent or ""
|
||||
["IP"] = self.ctx.bw.remote_addr,
|
||||
["USER_AGENT"] = self.ctx.bw.http_user_agent or ""
|
||||
}
|
||||
ngx.ctx.bw.sessions_checks = {}
|
||||
self.ctx.bw.sessions_checks = {}
|
||||
for check, value in pairs(checks) do
|
||||
if self.variables["SESSIONS_CHECK_" .. check] == "yes" then
|
||||
table.insert(ngx.ctx.bw.sessions_checks, {check, value})
|
||||
table.insert(self.ctx.bw.sessions_checks, {check, value})
|
||||
end
|
||||
end
|
||||
return self:ret(true, "success")
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ function whitelist:initialize()
|
|||
plugin.initialize(self, "whitelist")
|
||||
-- Decode lists
|
||||
if ngx.get_phase() ~= "init" and self:is_needed() then
|
||||
local lists, err = self.datastore:get("plugin_whitelist_lists")
|
||||
local lists, err = self.datastore:get("plugin_whitelist_lists", true)
|
||||
if not lists then
|
||||
self.logger:log(ngx.ERR, err)
|
||||
self.lists = {}
|
||||
else
|
||||
self.lists = cjson.decode(lists)
|
||||
self.lists = lists
|
||||
end
|
||||
local kinds = {
|
||||
["IP"] = {},
|
||||
|
|
@ -45,7 +45,7 @@ function whitelist:is_needed()
|
|||
return false
|
||||
end
|
||||
-- Request phases (no default)
|
||||
if self.is_request and (ngx.ctx.bw.server_name ~= "_") then
|
||||
if self.is_request and (self.ctx.bw.server_name ~= "_") then
|
||||
return self.variables["USE_WHITELIST"] == "yes"
|
||||
end
|
||||
-- Other cases : at least one service uses it
|
||||
|
|
@ -81,7 +81,7 @@ function whitelist:init()
|
|||
end
|
||||
end
|
||||
-- Load them into datastore
|
||||
local ok, err = self.datastore:set("plugin_whitelist_lists", cjson.encode(whitelists))
|
||||
local ok, err = self.datastore:set("plugin_whitelist_lists", whitelists, nil, true)
|
||||
if not ok then
|
||||
return self:ret(false, "can't store whitelist list into datastore : " .. err)
|
||||
end
|
||||
|
|
@ -91,7 +91,7 @@ end
|
|||
function whitelist:set()
|
||||
-- Set default value
|
||||
ngx.var.is_whitelisted = "no"
|
||||
ngx.ctx.bw.is_whitelisted = "no"
|
||||
self.ctx.bw.is_whitelisted = "no"
|
||||
env.set("is_whitelisted", "no")
|
||||
-- Check if set is needed
|
||||
if not self:is_needed() then
|
||||
|
|
@ -103,7 +103,7 @@ function whitelist:set()
|
|||
return self:ret(false, err)
|
||||
elseif whitelisted then
|
||||
ngx.var.is_whitelisted = "yes"
|
||||
ngx.ctx.bw.is_whitelisted = "yes"
|
||||
self.ctx.bw.is_whitelisted = "yes"
|
||||
env.set("is_whitelisted", "yes")
|
||||
return self:ret(true, err)
|
||||
end
|
||||
|
|
@ -121,7 +121,7 @@ function whitelist:access()
|
|||
return self:ret(false, err)
|
||||
elseif whitelisted then
|
||||
ngx.var.is_whitelisted = "yes"
|
||||
ngx.ctx.bw.is_whitelisted = "yes"
|
||||
self.ctx.bw.is_whitelisted = "yes"
|
||||
env.set("is_whitelisted", "yes")
|
||||
return self:ret(true, err, ngx.OK)
|
||||
end
|
||||
|
|
@ -138,7 +138,7 @@ function whitelist:access()
|
|||
end
|
||||
if whitelisted ~= "ok" then
|
||||
ngx.var.is_whitelisted = "yes"
|
||||
ngx.ctx.bw.is_whitelisted = "yes"
|
||||
self.ctx.bw.is_whitelisted = "yes"
|
||||
env.set("is_whitelisted", "yes")
|
||||
return self:ret(true, k .. " is whitelisted (info : " .. whitelisted .. ")", ngx.OK)
|
||||
end
|
||||
|
|
@ -155,24 +155,24 @@ end
|
|||
|
||||
function whitelist:kind_to_ele(kind)
|
||||
if kind == "IP" then
|
||||
return "ip" .. ngx.ctx.bw.remote_addr
|
||||
return "ip" .. self.ctx.bw.remote_addr
|
||||
elseif kind == "UA" then
|
||||
return "ua" .. ngx.ctx.bw.http_user_agent
|
||||
return "ua" .. self.ctx.bw.http_user_agent
|
||||
elseif kind == "URI" then
|
||||
return "uri" .. ngx.ctx.bw.uri
|
||||
return "uri" .. self.ctx.bw.uri
|
||||
end
|
||||
end
|
||||
|
||||
function whitelist:check_cache()
|
||||
-- Check the caches
|
||||
local checks = {
|
||||
["IP"] = "ip" .. ngx.ctx.bw.remote_addr
|
||||
["IP"] = "ip" .. self.ctx.bw.remote_addr
|
||||
}
|
||||
if ngx.ctx.bw.http_user_agent then
|
||||
checks["UA"] = "ua" .. ngx.ctx.bw.http_user_agent
|
||||
if self.ctx.bw.http_user_agent then
|
||||
checks["UA"] = "ua" .. self.ctx.bw.http_user_agent
|
||||
end
|
||||
if ngx.ctx.bw.uri then
|
||||
checks["URI"] = "uri" .. ngx.ctx.bw.uri
|
||||
if self.ctx.bw.uri then
|
||||
checks["URI"] = "uri" .. self.ctx.bw.uri
|
||||
end
|
||||
local already_cached = {}
|
||||
for k, v in pairs(checks) do
|
||||
|
|
@ -198,7 +198,7 @@ function whitelist:check_cache()
|
|||
end
|
||||
|
||||
function whitelist:is_in_cache(ele)
|
||||
local ok, data = self.cachestore:get("plugin_whitelist_" .. ngx.ctx.bw.server_name .. ele)
|
||||
local ok, data = self.cachestore:get("plugin_whitelist_" .. self.ctx.bw.server_name .. ele)
|
||||
if not ok then
|
||||
return false, data
|
||||
end
|
||||
|
|
@ -206,7 +206,7 @@ function whitelist:is_in_cache(ele)
|
|||
end
|
||||
|
||||
function whitelist:add_to_cache(ele, value)
|
||||
local ok, err = self.cachestore:set("plugin_whitelist_" .. ngx.ctx.bw.server_name .. ele, value, 86400)
|
||||
local ok, err = self.cachestore:set("plugin_whitelist_" .. self.ctx.bw.server_name .. ele, value, 86400)
|
||||
if not ok then
|
||||
return false, err
|
||||
end
|
||||
|
|
@ -230,7 +230,7 @@ function whitelist:is_whitelisted_ip()
|
|||
if not ipm then
|
||||
return nil, err
|
||||
end
|
||||
local match, err = ipm:match(ngx.ctx.bw.remote_addr)
|
||||
local match, err = ipm:match(self.ctx.bw.remote_addr)
|
||||
if err then
|
||||
return nil, err
|
||||
end
|
||||
|
|
@ -240,12 +240,12 @@ function whitelist:is_whitelisted_ip()
|
|||
|
||||
-- Check if rDNS is needed
|
||||
local check_rdns = true
|
||||
if self.variables["WHITELIST_RDNS_GLOBAL"] == "yes" and not ngx.ctx.bw.ip_is_global then
|
||||
if self.variables["WHITELIST_RDNS_GLOBAL"] == "yes" and not self.ctx.bw.ip_is_global then
|
||||
check_rdns = false
|
||||
end
|
||||
if check_rdns then
|
||||
-- Get rDNS
|
||||
local rdns_list, err = utils.get_rdns(ngx.ctx.bw.remote_addr)
|
||||
local rdns_list, err = utils.get_rdns(self.ctx.bw.remote_addr)
|
||||
-- Check if rDNS is in whitelist
|
||||
if rdns_list then
|
||||
local forward_check = nil
|
||||
|
|
@ -266,11 +266,11 @@ function whitelist:is_whitelisted_ip()
|
|||
local ip_list, err = utils.get_ips(forward_check)
|
||||
if ip_list then
|
||||
for i, ip in ipairs(ip_list) do
|
||||
if ip == ngx.ctx.bw.remote_addr then
|
||||
if ip == self.ctx.bw.remote_addr then
|
||||
return true, "rDNS " .. rdns_suffix
|
||||
end
|
||||
end
|
||||
self.logger:log(ngx.WARN, "IP " .. ngx.ctx.bw.remote_addr .. " may spoof reverse DNS " .. forward_check)
|
||||
self.logger:log(ngx.WARN, "IP " .. self.ctx.bw.remote_addr .. " may spoof reverse DNS " .. forward_check)
|
||||
else
|
||||
self.logger:log(ngx.ERR, "error while getting rdns (forward check) : " .. err)
|
||||
end
|
||||
|
|
@ -281,10 +281,10 @@ function whitelist:is_whitelisted_ip()
|
|||
end
|
||||
|
||||
-- Check if ASN is in whitelist
|
||||
if ngx.ctx.bw.ip_is_global then
|
||||
local asn, err = utils.get_asn(ngx.ctx.bw.remote_addr)
|
||||
if self.ctx.bw.ip_is_global then
|
||||
local asn, err = utils.get_asn(self.ctx.bw.remote_addr)
|
||||
if not asn then
|
||||
self.logger:log(ngx.ERR, "can't get ASN of IP " .. ngx.ctx.bw.remote_addr .. " : " .. err)
|
||||
self.logger:log(ngx.ERR, "can't get ASN of IP " .. self.ctx.bw.remote_addr .. " : " .. err)
|
||||
else
|
||||
for i, bl_asn in ipairs(self.lists["ASN"]) do
|
||||
if bl_asn == tostring(asn) then
|
||||
|
|
@ -301,7 +301,7 @@ end
|
|||
function whitelist:is_whitelisted_uri()
|
||||
-- Check if URI is in whitelist
|
||||
for i, uri in ipairs(self.lists["URI"]) do
|
||||
if utils.regex_match(ngx.ctx.bw.uri, uri) then
|
||||
if utils.regex_match(self.ctx.bw.uri, uri) then
|
||||
return true, "URI " .. uri
|
||||
end
|
||||
end
|
||||
|
|
@ -312,7 +312,7 @@ end
|
|||
function whitelist:is_whitelisted_ua()
|
||||
-- Check if UA is in whitelist
|
||||
for i, ua in ipairs(self.lists["USER_AGENT"]) do
|
||||
if utils.regex_match(ngx.ctx.bw.http_user_agent, ua) then
|
||||
if utils.regex_match(self.ctx.bw.http_user_agent, ua) then
|
||||
return true, "UA " .. ua
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ COPY --chown=root:scheduler src/bw/misc/country.mmdb /var/tmp/bunkerweb/country.
|
|||
RUN chmod 770 /var/tmp/bunkerweb/asn.mmdb /var/tmp/bunkerweb/country.mmdb
|
||||
|
||||
# Fix CVEs
|
||||
RUN apk add --no-cache "libcrypto3>=3.1.1-r0" "libssl3>=3.1.1-r0"
|
||||
# RUN apk add --no-cache "libcrypto3>=3.1.1-r0" "libssl3>=3.1.1-r0"
|
||||
|
||||
VOLUME /data /etc/nginx
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue