use ngx.ctx to store common values

This commit is contained in:
florian 2023-04-18 21:01:45 +02:00
parent 881d3a00d5
commit 4ba5d66598
No known key found for this signature in database
GPG Key ID: 3D80806F12602A7C
19 changed files with 234 additions and 213 deletions

View File

@ -99,12 +99,14 @@ helpers.fill_ctx = function()
if not ngx.shared.cachestore then
data.kind = "stream"
end
data.ip = ngx.var.remote_addr
data.remote_addr = ngx.var.remote_addr
data.uri = ngx.var.uri
data.original_uri = ngx.var.original_uri
data.user_agent = ngx.var.http_user_agent
data.request_uri = ngx.var.request_uri
data.request_method = ngx.var.request_method
data.http_user_agent = ngx.var.http_user_agent
data.server_name = ngx.var.server_name
-- IP data : global
local ip_is_global, err = utils.ip_is_global(data.ip)
local ip_is_global, err = utils.ip_is_global(data.remote_addr)
if ip_is_global == nil then
table.insert(errors, "can't check if IP is global : " .. err)
else

View File

@ -44,6 +44,18 @@ server {
local datastore = cdatastore:new()
logger:log(ngx.INFO, "log_default phase started")
-- Fill ctx
logger:log(ngx.INFO, "filling ngx.ctx ...")
local ok, ret, errors = 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
logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
-- Get plugins
local plugins, err = datastore:get("plugins")
if not plugins then

View File

@ -1,76 +1,76 @@
init_by_lua_block {
local class = require "middleclass"
local logger = require "bunkerweb.logger"
local helpers = require "bunkerweb.helpers"
local datastore = require "bunkerweb.datastore"
local cjson = require "cjson"
local class = require "middleclass"
local clogger = require "bunkerweb.logger"
local helpers = require "bunkerweb.helpers"
local cdatastore = require "bunkerweb.datastore"
local cjson = require "cjson"
-- Start init phase
local init_logger = logger:new("INIT")
local ds = datastore:new()
init_logger:log(ngx.NOTICE, "init phase started")
local logger = clogger:new("INIT")
local datastore = cdatastore:new()
logger:log(ngx.NOTICE, "init phase started")
-- Remove previous data from the datastore
init_logger:log(ngx.NOTICE, "deleting old keys from datastore ...")
logger:log(ngx.NOTICE, "deleting old keys from datastore ...")
local data_keys = {"^plugin_", "^variable_", "^plugins$", "^api_", "^misc_"}
for i, key in pairs(data_keys) do
local ok, err = ds:delete_all(key)
local ok, err = datastore:delete_all(key)
if not ok then
init_logger:log(ngx.ERR, "can't delete " .. key .. " from datastore : " .. err)
logger:log(ngx.ERR, "can't delete " .. key .. " from datastore : " .. err)
return false
end
init_logger:log(ngx.INFO, "deleted " .. key .. " from datastore")
logger:log(ngx.INFO, "deleted " .. key .. " from datastore")
end
init_logger:log(ngx.NOTICE, "deleted old keys from datastore")
logger:log(ngx.NOTICE, "deleted old keys from datastore")
-- Load variables into the datastore
init_logger:log(ngx.NOTICE, "saving variables into datastore ...")
logger:log(ngx.NOTICE, "saving variables into datastore ...")
local file = io.open("/etc/nginx/variables.env")
if not file then
init_logger:log(ngx.ERR, "can't open /etc/nginx/variables.env file")
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 = ds:set("variable_" .. variable, value)
local ok, err = datastore:set("variable_" .. variable, value)
if not ok then
init_logger:log(ngx.ERR, "can't save variable " .. variable .. " into datastore : " .. err)
logger:log(ngx.ERR, "can't save variable " .. variable .. " into datastore : " .. err)
return false
end
init_logger:log(ngx.INFO, "saved variable " .. variable .. "=" .. value .. " into datastore")
logger:log(ngx.INFO, "saved variable " .. variable .. "=" .. value .. " into datastore")
end
init_logger:log(ngx.NOTICE, "saved variables into datastore")
logger:log(ngx.NOTICE, "saved variables into datastore")
-- Set API values into the datastore
init_logger:log(ngx.NOTICE, "saving API values into datastore ...")
local value, err = ds:get("variable_USE_API")
logger:log(ngx.NOTICE, "saving API values into datastore ...")
local value, err = datastore:get("variable_USE_API")
if not value then
init_logger:log(ngx.ERR, "can't get variable USE_API from the datastore : " .. err)
logger:log(ngx.ERR, "can't get variable USE_API from the datastore : " .. err)
return false
end
if value == "yes" then
local value, err = ds:get("variable_API_WHITELIST_IP")
local value, err = datastore:get("variable_API_WHITELIST_IP")
if not value then
init_logger:log(ngx.ERR, "can't get variable API_WHITELIST_IP from the datastore : " .. err)
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 = ds:set("api_whitelist_ip", cjson.encode(whitelists))
local ok, err = datastore:set("api_whitelist_ip", cjson.encode(whitelists))
if not ok then
init_logger:log(ngx.ERR, "can't save API whitelist_ip to datastore : " .. err)
logger:log(ngx.ERR, "can't save API whitelist_ip to datastore : " .. err)
return false
end
init_logger:log(ngx.INFO, "saved API whitelist_ip into datastore")
logger:log(ngx.INFO, "saved API whitelist_ip into datastore")
end
init_logger:log(ngx.NOTICE, "saved API values into datastore")
logger:log(ngx.NOTICE, "saved API values into datastore")
-- Load plugins into the datastore
init_logger:log(ngx.NOTICE, "saving plugins into datastore ...")
logger:log(ngx.NOTICE, "saving plugins into datastore ...")
local plugins = {}
local plugin_paths = {"/usr/share/bunkerweb/core", "/etc/bunkerweb/plugins"}
for i, plugin_path in ipairs(plugin_paths) do
@ -78,61 +78,61 @@ for i, plugin_path in ipairs(plugin_paths) do
for path in paths:lines() do
local ok, plugin = helpers.load_plugin(path .. "/plugin.json")
if not ok then
init_logger:log(ngx.ERR, plugin)
logger:log(ngx.ERR, plugin)
else
local ok, err = ds:set("plugin_" .. plugin.id, cjson.encode(plugin))
local ok, err = datastore:set("plugin_" .. plugin.id, cjson.encode(plugin))
if not ok then
init_logger:log(ngx.ERR, "can't save " .. plugin.id .. " into datastore : " .. err)
logger:log(ngx.ERR, "can't save " .. plugin.id .. " into datastore : " .. err)
else
table.insert(plugins, plugin)
table.sort(plugins, function (a, b)
return a.order < b.order
end)
init_logger:log(ngx.NOTICE, "loaded plugin " .. plugin.id .. " v" .. plugin.version)
logger:log(ngx.NOTICE, "loaded plugin " .. plugin.id .. " v" .. plugin.version)
end
end
end
end
local ok, err = ds:set("plugins", cjson.encode(plugins))
local ok, err = datastore:set("plugins", cjson.encode(plugins))
if not ok then
init_logger:log(ngx.ERR, "can't save plugins into datastore : " .. err)
logger:log(ngx.ERR, "can't save plugins into datastore : " .. err)
return false
end
init_logger:log(ngx.NOTICE, "saved plugins into datastore")
logger:log(ngx.NOTICE, "saved plugins into datastore")
-- Call init() methods
init_logger:log(ngx.NOTICE, "calling init() methods of plugins ...")
-- Call init() methodatastore
logger:log(ngx.NOTICE, "calling init() methods of plugins ...")
for i, plugin in ipairs(plugins) do
-- Require call
local plugin_lua, err = helpers.require_plugin(plugin.id)
if plugin_lua == false then
init_logger:log(ngx.ERR, err)
logger:log(ngx.ERR, err)
elseif plugin_lua == nil then
init_logger:log(ngx.NOTICE, err)
logger:log(ngx.NOTICE, err)
else
-- Check if plugin has init method
if plugin_lua.init ~= nil then
-- New call
local ok, plugin_obj = helpers.new_plugin(plugin_lua)
if not ok then
init_logger:log(ngx.ERR, plugin_obj)
logger:log(ngx.ERR, plugin_obj)
else
local ok, ret = helpers.call_plugin(plugin_obj, "init")
if not ok then
init_logger:log(ngx.ERR, ret)
logger:log(ngx.ERR, ret)
elseif not ret.ret then
init_logger:log(ngx.ERR, plugin.id .. ":init() call failed : " .. ret.msg)
logger:log(ngx.ERR, plugin.id .. ":init() call failed : " .. ret.msg)
else
init_logger:log(ngx.NOTICE, plugin.id .. ":init() call successful : " .. ret.msg)
logger:log(ngx.NOTICE, plugin.id .. ":init() call successful : " .. ret.msg)
end
end
else
init_logger:log(ngx.NOTICE, "skipped execution of " .. plugin.id .. " because method init() is not defined")
logger:log(ngx.NOTICE, "skipped execution of " .. plugin.id .. " because method init() is not defined")
end
end
end
init_logger:log(ngx.NOTICE, "called init() methods of plugins")
logger:log(ngx.NOTICE, "called init() methods of plugins")
init_logger:log(ngx.NOTICE, "init phase ended")
logger:log(ngx.NOTICE, "init phase ended")
}

View File

@ -5,7 +5,6 @@ local clogger = require "bunkerweb.logger"
local helpers = require "bunkerweb.helpers"
local utils = require "bunkerweb.utils"
local cdatastore = require "bunkerweb.datastore"
local ccachestore = require "bunkerweb.cachestore"
local cjson = require "cjson"
-- Don't process internal requests
@ -17,19 +16,8 @@ end
-- Start access phase
local datastore = cdatastore:new()
local use_redis, err = utils.get_variable("USE_REDIS", false)
if not use_redis then
logger:log(ngx.ERR, err)
end
local cachestore = ccachestore:new(use_redis == "yes")
logger:log(ngx.INFO, "access phase started")
-- Update cachestore only once and before any other code
local ok, err = cachestore.cache:update()
if not ok then
logger:log(ngx.ERR, "can't update cachestore : " .. err)
end
-- Fill ctx
logger:log(ngx.INFO, "filling ngx.ctx ...")
local ok, ret, errors = helpers.fill_ctx()
@ -43,12 +31,12 @@ end
logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
-- Process bans as soon as possible
local ok, reason = datastore:get("bans_ip_" .. ngx.var.remote_addr)
local ok, reason = datastore:get("bans_ip_" .. ngx.ctx.bw.remote_addr)
if not ok and reason ~= "not found" then
logger:log(ngx.INFO, "error while checking if client is banned : " .. reason)
return false
elseif ok and reason ~= "not found" then
logger:log(ngx.WARN, "IP " .. ngx.var.remote_addr .. " is banned with reason : " .. reason)
logger:log(ngx.WARN, "IP " .. ngx.ctx.bw.remote_addr .. " is banned with reason : " .. reason)
return ngx.exit(utils.get_deny_status())
end
@ -83,7 +71,7 @@ for i, plugin in ipairs(plugins) do
elseif not ret.ret then
logger:log(ngx.ERR, plugin.id .. ":access() call failed : " .. ret.msg)
else
logger:log(ngx.NOTICE, plugin.id .. ":access() call successful : " .. ret.msg)
logger:log(ngx.INFO, plugin.id .. ":access() call successful : " .. ret.msg)
end
if ret.status then
if ret.status == utils.get_deny_status() then

View File

@ -17,6 +17,18 @@ end
local datastore = cdatastore:new()
logger:log(ngx.INFO, "header phase started")
-- Fill ctx
logger:log(ngx.INFO, "filling ngx.ctx ...")
local ok, ret, errors = 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
logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
-- Get plugins
local plugins, err = datastore:get("plugins")
if not plugins then

View File

@ -11,6 +11,18 @@ local logger = clogger:new("LOG")
local datastore = cdatastore:new()
logger:log(ngx.INFO, "log phase started")
-- Fill ctx
logger:log(ngx.INFO, "filling ngx.ctx ...")
local ok, ret, errors = 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
logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
-- Get plugins
local plugins, err = datastore:get("plugins")
if not plugins then
@ -42,7 +54,7 @@ for i, plugin in ipairs(plugins) do
elseif not ret.ret then
logger:log(ngx.ERR, plugin.id .. ":log() call failed : " .. ret.msg)
else
logger:log(ngx.NOTICE, plugin.id .. ":log() call successful : " .. ret.msg)
logger:log(ngx.INFO, plugin.id .. ":log() call successful : " .. ret.msg)
end
end
else

View File

@ -5,6 +5,7 @@ local class = require "middleclass"
local clogger = require "bunkerweb.logger"
local helpers = require "bunkerweb.helpers"
local cdatastore = require "bunkerweb.datastore"
local ccachestore = require "bunkerweb.cachestore"
local cjson = require "cjson"
-- Don't process internal requests
@ -18,6 +19,25 @@ end
local datastore = cdatastore:new()
logger:log(ngx.INFO, "set phase started")
-- Update cachestore only once and before any other code
local cachestore = ccachestore:new()
local ok, err = cachestore.cache:update()
if not ok then
logger:log(ngx.ERR, "can't update cachestore : " .. err)
end
-- Fill ctx
logger:log(ngx.INFO, "filling ngx.ctx ...")
local ok, ret, errors = 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
logger:log(ngx.INFO, "ngx.ctx filled (ret = " .. ret .. ")")
-- Get plugins
local plugins, err = datastore:get("plugins")
if not plugins then
@ -49,7 +69,7 @@ for i, plugin in ipairs(plugins) do
elseif not ret.ret then
logger:log(ngx.ERR, plugin.id .. ":set() call failed : " .. ret.msg)
else
logger:log(ngx.NOTICE, plugin.id .. ":set() call successful : " .. ret.msg)
logger:log(ngx.INFO, plugin.id .. ":set() call successful : " .. ret.msg)
end
end
else

View File

@ -35,25 +35,25 @@ function antibot:access()
return self:ret(false, "can't check if challenge is resolved : " .. err)
end
if resolved then
if ngx.var.uri == challenge_uri then
if ngx.ctx.bw.uri == challenge_uri then
return self:ret(true, "client already resolved the challenge", nil, original_uri)
end
return self:ret(true, "client already resolved the challenge")
end
-- Redirect to challenge page
if ngx.var.uri ~= challenge_uri then
if ngx.ctx.bw.uri ~= challenge_uri then
return self:ret(true, "redirecting client to the challenge uri", nil, challenge_uri)
end
-- Display challenge needed
if ngx.var.request_method == "GET" then
if ngx.ctx.bw.request_method == "GET" then
ngx.ctx.antibot_display_content = true
return self:ret(true, "displaying challenge to client", ngx.HTTP_OK)
end
-- Check challenge
if ngx.var.request_method == "POST" then
if ngx.ctx.bw.request_method == "POST" then
local ok, err, redirect = self:check_challenge(antibot)
if ok == nil then
return self:ret(false, "check challenge error : " .. err, ngx.HTTP_INTERNAL_SERVER_ERROR)
@ -123,9 +123,9 @@ function antibot:prepare_challenge()
data = {
type = self.variables["USE_ANTIBOT"],
resolved = self.variables["USE_ANTIBOT"] == "cookie",
original_uri = ngx.var.request_uri
original_uri = ngx.ctx.bw.request_uri
}
if ngx.var.original_uri == challenge_uri then
if ngx.ctx.bw.uri == self.variables["ANTIBOT_URI"] then
data.original_uri = "/"
end
set_needed = true
@ -269,7 +269,7 @@ function antibot:check_challenge()
end
local res, err = httpc:request_uri("https://www.google.com/recaptcha/api/siteverify", {
method = "POST",
body = "secret=" .. self.variables["ANTIBOT_RECAPTCHA_SECRET"] .. "&response=" .. args["token"] .. "&remoteip=" .. ngx.var.remote_addr,
body = "secret=" .. self.variables["ANTIBOT_RECAPTCHA_SECRET"] .. "&response=" .. args["token"] .. "&remoteip=" .. ngx.ctx.bw.remote_addr,
headers = {
["Content-Type"] = "application/x-www-form-urlencoded"
}
@ -303,7 +303,7 @@ function antibot:check_challenge()
end
local res, err = httpc:request_uri("https://hcaptcha.com/siteverify", {
method = "POST",
body = "secret=" .. self.variables["ANTIBOT_HCAPTCHA_SECRET"] .. "&response=" .. args["token"] .. "&remoteip=" .. ngx.var.remote_addr,
body = "secret=" .. self.variables["ANTIBOT_HCAPTCHA_SECRET"] .. "&response=" .. args["token"] .. "&remoteip=" .. ngx.ctx.bw.remote_addr,
headers = {
["Content-Type"] = "application/x-www-form-urlencoded"
}

View File

@ -19,7 +19,7 @@ end
function badbehavior:log()
-- Check if we are whitelisted
if ngx.var.is_whitelisted == "yes" then
if ngx.ctx.bw.is_whitelisted == "yes" then
return self:ret(true, "client is whitelisted")
end
-- Check if bad behavior is activated
@ -31,12 +31,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.var.remote_addr)
local banned, err = self.datastore:get("bans_ip_" .. ngx.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, self, ngx.var.remote_addr)
local ok, err = ngx.timer.at(0, badbehavior.increase, self, ngx.ctx.bw.remote_addr)
if not ok then
return self:ret(false, "can't create increase timer : " .. err)
end

View File

@ -81,13 +81,13 @@ function blacklist:access()
end
-- Check the caches
local checks = {
["IP"] = "ip" .. ngx.var.remote_addr
["IP"] = "ip" .. ngx.ctx.bw.remote_addr
}
if ngx.var.http_user_agent then
checks["UA"] = "ua" .. ngx.var.http_user_agent
if ngx.ctx.bw.http_user_agent then
checks["UA"] = "ua" .. ngx.ctx.bw.http_user_agent
end
if ngx.var.uri then
checks["URI"] = "uri" .. ngx.var.uri
if ngx.ctx.bw.uri then
checks["URI"] = "uri" .. ngx.ctx.bw.uri
end
local already_cached = {
["IP"] = false,
@ -138,11 +138,11 @@ end
function blacklist:kind_to_ele(kind)
if kind == "IP" then
return "ip" .. ngx.var.remote_addr
return "ip" .. ngx.ctx.bw.remote_addr
elseif kind == "UA" then
return "ua" .. ngx.var.http_user_agent
return "ua" .. ngx.ctx.bw.http_user_agent
elseif kind == "URI" then
return "uri" .. ngx.var.uri
return "uri" .. ngx.ctx.bw.uri
end
end
@ -179,7 +179,7 @@ function blacklist:is_blacklisted_ip()
if not ipm then
return nil, err
end
local match, err = ipm:match(ngx.var.remote_addr)
local match, err = ipm:match(ngx.ctx.bw.remote_addr)
if err then
return nil, err
end
@ -189,7 +189,7 @@ function blacklist:is_blacklisted_ip()
if not ipm then
return nil, err
end
local match, err = ipm:match(ngx.var.remote_addr)
local match, err = ipm:match(ngx.ctx.bw.remote_addr)
if err then
return nil, err
end
@ -200,18 +200,12 @@ function blacklist:is_blacklisted_ip()
-- Check if rDNS is needed
local check_rdns = true
local is_global, err = utils.ip_is_global(ngx.var.remote_addr)
if self.variables["BLACKLIST_RDNS_GLOBAL"] == "yes" then
if is_global == nil then
return nil, err
end
if not is_global then
check_rdns = false
end
if self.variables["BLACKLIST_RDNS_GLOBAL"] == "yes" and not ngx.ctx.bw.ip_is_global then
check_rdns = false
end
if check_rdns then
-- Get rDNS
local rdns_list, err = utils.get_rdns(ngx.var.remote_addr)
local rdns_list, err = utils.get_rdns(ngx.ctx.bw.remote_addr)
if not rdns_list then
return false, err
end
@ -241,8 +235,8 @@ function blacklist:is_blacklisted_ip()
end
-- Check if ASN is in ignore list
if is_global then
local asn, err = utils.get_asn(ngx.var.remote_addr)
if ngx.ctx.bw.ip_is_global then
local asn, err = utils.get_asn(ngx.ctx.bw.remote_addr)
if not asn then
self.logger:log(ngx.ERR, "7")
return nil, err
@ -272,7 +266,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 ngx.var.uri:match(ignore_uri) then
if ngx.ctx.bw.uri:match(ignore_uri) then
ignore = true
break
end
@ -280,7 +274,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 ngx.var.uri:match(uri) then
if ngx.ctx.bw.uri:match(uri) then
return true, "URI " .. uri
end
end
@ -293,7 +287,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 ngx.var.http_user_agent:match(ignore_ua) then
if ngx.ctx.bw.http_user_agent:match(ignore_ua) then
ignore = true
break
end
@ -301,7 +295,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 ngx.var.http_user_agent:match(ua) then
if ngx.ctx.bw.http_user_agent:match(ua) then
return true, "UA " .. ua
end
end

View File

@ -94,11 +94,7 @@ function bunkernet:log(bypass_use_bunkernet)
return self:ret(true, "skipping report because the reason is bunkernet")
end
-- Check if IP is global
local is_global, err = utils.ip_is_global(ngx.var.remote_addr)
if is_global == nil then
return self:ret(false, "error while checking if IP is global " .. err)
end
if not is_global then
if not ngx.ctx.bw.ip_is_global then
return self:ret(true, "IP is not global")
end
-- TODO : check if IP has been reported recently
@ -113,8 +109,8 @@ function bunkernet:log(bypass_use_bunkernet)
end
end
local hdr, err = ngx.timer.at(0, report_callback, self, ngx.var.remote_addr, reason, ngx.var.request_method,
ngx.var.request_uri, ngx.req.get_headers())
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())
if not hdr then
return self:ret(false, "can't create report timer : " .. err)
end

View File

@ -14,7 +14,7 @@ function cors:header()
if self.variables["USE_CORS"] ~= "yes" then
return self:ret(true, "service doesn't use CORS")
end
if ngx.var.request_method ~= "OPTIONS" then
if ngx.ctx.bw.request_method ~= "OPTIONS" then
return self:ret(true, "method is not OPTIONS")
end
-- Add headers

View File

@ -23,69 +23,66 @@ function country:access()
return self:ret(true, "country not activated")
end
-- Check if IP is in cache
local data, err = self:is_in_cache(ngx.var.remote_addr)
local data, err = self:is_in_cache(ngx.ctx.bw.remote_addr)
if data then
if data.result == "ok" then
return self:ret(true, "client IP " .. ngx.var.remote_addr .. " is in country cache (not blacklisted, country = " .. data.country .. ")")
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is in country cache (not blacklisted, country = " .. data.country .. ")")
end
return self:ret(true, "client IP " .. ngx.var.remote_addr .. " is in country cache (blacklisted, country = " .. data.country .. ")", utils.get_deny_status())
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is in country cache (blacklisted, country = " .. data.country .. ")", utils.get_deny_status())
end
-- Don't go further if IP is not global
local is_global, err = utils.ip_is_global(ngx.var.remote_addr)
if is_global == nil then
return self:ret(false, "error while checking if ip is global : " .. err)
elseif not is_global then
local ok, err = self:add_to_cache(ngx.var.remote_addr, "unknown", "ok")
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 ok then
return self:ret(false, "error while adding ip to cache : " .. err)
end
return self:ret(true, "client IP " .. ngx.var.remote_addr .. " is not global, skipping check")
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is not global, skipping check")
end
-- Get the country of client
local country, err = utils.get_country(ngx.var.remote_addr)
local country, err = utils.get_country(ngx.ctx.bw.remote_addr)
if not country then
return self:ret(false, "can't get country of client IP " .. ngx.var.remote_addr .. " : " .. err)
return self:ret(false, "can't get country of client IP " .. ngx.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.var.remote_addr, country, "ok")
local ok, err = self:add_to_cache(ngx.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.var.remote_addr .. " is whitelisted (country = " .. country .. ")")
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is whitelisted (country = " .. country .. ")")
end
end
local ok, err = self:add_to_cache(ngx.var.remote_addr, country, "ko")
local ok, err = self:add_to_cache(ngx.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.var.remote_addr .. " is not whitelisted (country = " .. country .. ")", utils.get_deny_status())
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is not whitelisted (country = " .. country .. ")", utils.get_deny_status())
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.var.remote_addr, country, "ko")
local ok, err = self:add_to_cache(ngx.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.var.remote_addr .. " is blacklisted (country = " .. country .. ")", true, utils.get_deny_status())
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is blacklisted (country = " .. country .. ")", true, utils.get_deny_status())
end
end
end
-- Country IP is not in blacklist
local ok, err = self:add_to_cache(ngx.var.remote_addr, country, "ok")
local ok, err = self:add_to_cache(ngx.ctx.bw.remote_addr, country, "ok")
if not ok then
return self:ret(false, "error while caching IP " .. ngx.var.remote_addr .. " : " .. err)
return self:ret(false, "error while caching IP " .. ngx.ctx.bw.remote_addr .. " : " .. err)
end
return self:ret(true, "client IP " .. ngx.var.remote_addr .. " is not blacklisted (country = " .. country .. ")")
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is not blacklisted (country = " .. country .. ")")
end
function country:preread()

View File

@ -28,22 +28,18 @@ function dnsbl:access()
return self:ret(true, "dnsbl list is empty")
end
-- Check if IP is in cache
local ok, cached = self:is_in_cache(ngx.var.remote_addr)
local ok, cached = self:is_in_cache(ngx.ctx.bw.remote_addr)
if not ok then
return self:ret(false, "error while checking cache : " .. err)
elseif cached then
if cached == "ok" then
return self:ret(true, "client IP " .. ngx.var.remote_addr .. " is in DNSBL cache (not blacklisted)")
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is in DNSBL cache (not blacklisted)")
end
return self:ret(true, "client IP " .. ngx.var.remote_addr .. " is in DNSBL cache (server = " .. cached .. ")", utils.get_deny_status())
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is in DNSBL cache (server = " .. cached .. ")", utils.get_deny_status())
end
-- Don't go further if IP is not global
local is_global, err = utils.ip_is_global(ngx.var.remote_addr)
if is_global == nil then
return self:ret(false, "can't check if client IP is global : " .. err)
end
if not is_global then
local ok, err = self:add_to_cache(ngx.var.remote_addr, "ok")
if not ngx.ctx.bw.ip_is_global then
local ok, err = self:add_to_cache(ngx.ctx.bw.remote_addr, "ok")
if not ok then
return self:ret(false, "error while adding element to cache : " .. err)
end
@ -56,7 +52,7 @@ function dnsbl:access()
self.logger:log(ngx.ERR, "error while sending DNS request to " .. server .. " : " .. err)
end
if result then
local ok, err self:add_to_cache(ngx.var.remote_addr, server)
local ok, err self:add_to_cache(ngx.ctx.bw.remote_addr, server)
if not ok then
return self:ret(false, "error while adding element to cache : " .. err)
end
@ -64,7 +60,7 @@ function dnsbl:access()
end
end
-- IP is not in DNSBL
local ok, err = self:add_to_cache(ngx.var.remote_addr, "ok")
local ok, err = self:add_to_cache(ngx.ctx.bw.remote_addr, "ok")
if not ok then
return self:ret(false, "IP is not in DNSBL (error = " .. err .. ")")
end

View File

@ -41,7 +41,7 @@ function greylist:init()
if not self.init_needed then
return self:ret(true, "init not needed")
end
-- Read blacklists
-- Read greylists
local greylists = {
["IP"] = {},
["RDNS"] = {},
@ -75,13 +75,13 @@ function greylist:access()
end
-- Check the caches
local checks = {
["IP"] = "ip" .. ngx.var.remote_addr
["IP"] = "ip" .. ngx.ctx.bw.remote_addr
}
if ngx.var.http_user_agent then
checks["UA"] = "ua" .. ngx.var.http_user_agent
if ngx.ctx.bw.http_user_agent then
checks["UA"] = "ua" .. ngx.ctx.bw.http_user_agent
end
if ngx.var.uri then
checks["URI"] = "uri" .. ngx.var.uri
if ngx.ctx.bw.uri then
checks["URI"] = "uri" .. ngx.ctx.bw.uri
end
local already_cached = {
["IP"] = false,
@ -131,11 +131,11 @@ end
function greylist:kind_to_ele(kind)
if kind == "IP" then
return "ip" .. ngx.var.remote_addr
return "ip" .. ngx.ctx.bw.remote_addr
elseif kind == "UA" then
return "ua" .. ngx.var.http_user_agent
return "ua" .. ngx.ctx.bw.http_user_agent
elseif kind == "URI" then
return "uri" .. ngx.var.uri
return "uri" .. ngx.ctx.bw.uri
end
end
@ -151,12 +151,12 @@ function greylist:is_greylisted(kind)
end
function greylist:is_greylisted_ip()
-- Check if IP is in blacklist
-- Check if IP is in greylist
local ipm, err = ipmatcher.new(self.lists["IP"])
if not ipm then
return nil, err
end
local match, err = ipm:match(ngx.var.remote_addr)
local match, err = ipm:match(ngx.ctx.bw.remote_addr)
if err then
return nil, err
end
@ -166,18 +166,12 @@ function greylist:is_greylisted_ip()
-- Check if rDNS is needed
local check_rdns = true
local is_global, err = utils.ip_is_global(ngx.var.remote_addr)
if self.variables["BLACKLIST_RDNS_GLOBAL"] == "yes" then
if is_global == nil then
return nil, err
end
if not is_global then
check_rdns = false
end
if self.variables["GREYLIST_RDNS_GLOBAL"] == "yes" and not ngx.ctx.bw.ip_is_global then
check_rdns = false
end
if check_rdns then
-- Get rDNS
local rdns_list, err = utils.get_rdns(ngx.var.remote_addr)
local rdns_list, err = utils.get_rdns(ngx.ctx.bw.remote_addr)
if not rdns_list then
return nil, err
end
@ -192,8 +186,8 @@ function greylist:is_greylisted_ip()
end
-- Check if ASN is in greylist
if is_global then
local asn, err = utils.get_asn(ngx.var.remote_addr)
if ngx.ctx.bw.ip_is_global then
local asn, err = utils.get_asn(ngx.ctx.bw.remote_addr)
if not asn then
return nil, err
end
@ -209,9 +203,9 @@ function greylist:is_greylisted_ip()
end
function greylist:is_greylisted_uri()
-- Check if URI is in blacklist
-- Check if URI is in greylist
for i, uri in ipairs(self.lists["URI"]) do
if ngx.var.uri:match(uri) then
if ngx.ctx.bw.uri:match(uri) then
return true, "URI " .. uri
end
end
@ -222,7 +216,7 @@ end
function greylist:is_greylisted_ua()
-- Check if UA is in greylist
for i, ua in ipairs(self.lists["USER_AGENT"]) do
if ngx.var.http_user_agent:match(ua) then
if ngx.ctx.bw.http_user_agent:match(ua) then
return true, "UA " .. ua
end
end

View File

@ -11,7 +11,7 @@ function letsencrypt:initialize()
end
function letsencrypt:access()
if string.sub(ngx.var.uri, 1, string.len("/.well-known/acme-challenge/")) == "/.well-known/acme-challenge/" then
if string.sub(ngx.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.var.uri, "^/lets%-encrypt/challenge$") or
(ngx.var.request_method ~= "POST" and ngx.var.request_method ~= "DELETE") then
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
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.var.request_method == "POST" then
if ngx.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.var.request_method == "DELETE" then
elseif ngx.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 }

View File

@ -35,8 +35,8 @@ function limit:initialize()
end
end
-- Extract and overwrite if needed server rules
if all_rules[ngx.var.server_name] then
for k, v in pairs(all_rules[ngx.var.server_name]) do
if all_rules[ngx.ctx.bw.server_name] then
for k, v in pairs(all_rules[ngx.ctx.bw.server_name]) do
self.rules[k] = v
end
end
@ -83,7 +83,7 @@ end
function limit:access()
-- Check if we are whitelisted
if ngx.var.is_whitelisted == "yes" then
if ngx.ctx.bw.is_whitelisted == "yes" then
return self:ret(true, "client is whitelisted")
end
-- Check if access is needed
@ -94,7 +94,7 @@ function limit:access()
local rate = nil
local uri = nil
for k, v in pairs(self.rules) do
if k ~= "/" and ngx.var.uri:match(k) then
if k ~= "/" and ngx.ctx.bw.uri:match(k) then
rate = v
uri = k
break
@ -105,7 +105,7 @@ function limit:access()
rate = self.rules["/"]
uri = "/"
else
return self:ret(true, "no rule for " .. ngx.var.uri)
return self:ret(true, "no rule for " .. ngx.ctx.bw.uri)
end
end
-- Check if limit is reached
@ -116,10 +116,10 @@ function limit:access()
end
-- Limit reached
if limited then
return self:ret(true, "client IP " .. ngx.var.remote_addr .. " is limited for URL " .. ngx.var.uri .. " (current rate = " .. current_rate .. "r/" .. rate_time .. " and max rate = " .. rate .. ")", ngx.HTTP_TOO_MANY_REQUESTS)
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is limited for URL " .. ngx.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.var.remote_addr .. " is not limited for URL " .. ngx.var.uri .. " (current rate = " .. current_rate .. "r/" .. rate_time .. " and max rate = " .. rate .. ")")
return self:ret(true, "client IP " .. ngx.ctx.bw.remote_addr .. " is not limited for URL " .. ngx.ctx.bw.uri .. " (current rate = " .. current_rate .. "r/" .. rate_time .. " and max rate = " .. rate .. ")")
end
function limit:limit_req(rate_max, rate_time)
@ -132,7 +132,7 @@ function limit:limit_req(rate_max, rate_time)
else
timestamps = redis_timestamps
-- Save the new timestamps
local ok, err = self.datastore:set("plugin_limit_cache_" .. ngx.var.server_name .. ngx.var.remote_addr .. ngx.var.uri, cjson.encode(timestamps), delay)
local ok, err = self.datastore:set("plugin_limit_cache_" .. ngx.ctx.bw.server_name .. ngx.ctx.bw.remote_addr .. ngx.ctx.bw.uri, cjson.encode(timestamps), delay)
if not ok then
return nil, "can't update timestamps : " .. err
end
@ -154,7 +154,7 @@ end
function limit:limit_req_local(rate_max, rate_time)
-- Get timestamps
local timestamps, err = self.datastore:get("plugin_limit_cache_" .. ngx.var.server_name .. ngx.var.remote_addr .. ngx.var.uri)
local timestamps, err = self.datastore:get("plugin_limit_cache_" .. ngx.ctx.bw.server_name .. ngx.ctx.bw.remote_addr .. ngx.ctx.bw.uri)
if not timestamps and err ~= "not found" then
return nil, err
elseif err == "not found" then
@ -165,7 +165,7 @@ function limit:limit_req_local(rate_max, rate_time)
local updated, new_timestamps, delay = self:limit_req_timestamps(rate_max, rate_time, timestamps)
-- Save new timestamps if needed
if updated then
local ok, err = self.datastore:set("plugin_limit_cache_" .. ngx.var.server_name .. ngx.var.remote_addr .. ngx.var.uri, cjson.encode(timestamps), delay)
local ok, err = self.datastore:set("plugin_limit_cache_" .. ngx.ctx.bw.server_name .. ngx.ctx.bw.remote_addr .. ngx.ctx.bw.uri, cjson.encode(timestamps), delay)
if not ok then
return nil, err
end
@ -184,7 +184,7 @@ function limit:limit_req_redis(rate_max, rate_time)
return nil, err
end
-- Get timestamps
local timestamps, err = clusterstore:call("get", "limit_" .. ngx.var.server_name .. ngx.var.remote_addr .. ngx.var.uri)
local timestamps, err = clusterstore:call("get", "limit_" .. ngx.ctx.bw.server_name .. ngx.ctx.bw.remote_addr .. ngx.ctx.bw.uri)
if err then
clusterstore:close()
return nil, err
@ -198,7 +198,7 @@ function limit:limit_req_redis(rate_max, rate_time)
local updated, new_timestamps, delay = self:limit_req_timestamps(rate_max, rate_time, timestamps)
-- Save new timestamps if needed
if updated then
local ok, err = clusterstore:call("set", "limit_" .. ngx.var.server_name .. ngx.var.remote_addr .. ngx.var.uri, cjson.encode(new_timestamps), "EX", delay)
local ok, err = clusterstore:call("set", "limit_" .. ngx.ctx.bw.server_name .. ngx.ctx.bw.remote_addr .. ngx.ctx.bw.uri, cjson.encode(new_timestamps), "EX", delay)
if not ok then
clusterstore:close()
return nil, err

View File

@ -25,28 +25,28 @@ function reversescan:access()
-- Loop on ports
for port in self.variables["REVERSE_SCAN_PORTS"]:gmatch("%S+") do
-- Check if the scan is already cached
local cached, err = self:is_in_cache(ngx.var.remote_addr .. ":" .. port)
local cached, err = self:is_in_cache(ngx.ctx.bw.remote_addr .. ":" .. port)
if cached == nil then
return self:ret(false, "error getting cache from datastore : " .. err)
end
if cached == "open" then
return self:ret(true, "port " .. port .. " is opened for IP " .. ngx.var.remote_addr, utils.get_deny_status())
return self:ret(true, "port " .. port .. " is opened for IP " .. ngx.ctx.bw.remote_addr, utils.get_deny_status())
elseif not cached then
-- Do the scan
local res, err = self:scan(ngx.var.remote_addr, tonumber(port), tonumber(self.variables["REVERSE_SCAN_TIMEOUT"]))
local res, err = self:scan(ngx.ctx.bw.remote_addr, tonumber(port), tonumber(self.variables["REVERSE_SCAN_TIMEOUT"]))
-- Cache the result
local ok, err = self:add_to_cache(ngx.var.remote_addr .. ":" .. port, res)
local ok, err = self:add_to_cache(ngx.ctx.bw.remote_addr .. ":" .. port, res)
if not ok then
return self:ret(false, "error updating cache from datastore : " .. err)
end
-- Deny request if port is open
if res == "open" then
return self:ret(true, "port " .. port .. " is opened for IP " .. ngx.var.remote_addr, utils.get_deny_status())
return self:ret(true, "port " .. port .. " is opened for IP " .. ngx.ctx.bw.remote_addr, utils.get_deny_status())
end
end
end
-- No port opened
return self:ret(true, "no port open for IP " .. ngx.var.remote_addr)
return self:ret(true, "no port open for IP " .. ngx.ctx.bw.remote_addr)
end
function reversescan:scan(ip, port, timeout)

View File

@ -73,6 +73,7 @@ end
function whitelist:set()
-- Set default value
ngx.var.is_whitelisted = "no"
ngx.ctx.bw.is_whitelisted = "no"
env.set("is_whitelisted", "no")
-- Check if set is needed
if self.variables["USE_WHITELIST"] ~= "yes" then
@ -84,6 +85,7 @@ function whitelist:set()
return self:ret(false, err)
elseif whitelisted then
ngx.var.is_whitelisted = "yes"
ngx.ctx.bw.is_whitelisted = "yes"
env.set("is_whitelisted", "yes")
return self:ret(true, err)
end
@ -101,6 +103,7 @@ function whitelist:access()
return self:ret(false, err)
elseif whitelisted then
ngx.var.is_whitelisted = "yes"
ngx.ctx.bw.is_whitelisted = "yes"
env.set("is_whitelisted", "yes")
return self:ret(true, err, ngx.OK)
end
@ -117,6 +120,7 @@ function whitelist:access()
end
if whitelisted ~= "ok" then
ngx.var.is_whitelisted = "yes"
ngx.ctx.bw.is_whitelisted = "yes"
env.set("is_whitelisted", "yes")
return self:ret(true, k + " is whitelisted (info : " .. whitelisted .. ")", ngx.OK)
end
@ -133,24 +137,24 @@ end
function whitelist:kind_to_ele(kind)
if kind == "IP" then
return "ip" .. ngx.var.remote_addr
return "ip" .. ngx.ctx.bw.remote_addr
elseif kind == "UA" then
return "ua" .. ngx.var.http_user_agent
return "ua" .. ngx.ctx.bw.http_user_agent
elseif kind == "URI" then
return "uri" .. ngx.var.uri
return "uri" .. ngx.ctx.bw.uri
end
end
function whitelist:check_cache()
-- Check the caches
local checks = {
["IP"] = "ip" .. ngx.var.remote_addr
["IP"] = "ip" .. ngx.ctx.bw.remote_addr
}
if ngx.var.http_user_agent then
checks["UA"] = "ua" .. ngx.var.http_user_agent
if ngx.ctx.bw.http_user_agent then
checks["UA"] = "ua" .. ngx.ctx.bw.http_user_agent
end
if ngx.var.uri then
checks["URI"] = "uri" .. ngx.var.uri
if ngx.ctx.bw.uri then
checks["URI"] = "uri" .. ngx.ctx.bw.uri
end
local already_cached = {
["IP"] = false,
@ -209,7 +213,7 @@ function whitelist:is_whitelisted_ip()
if not ipm then
return nil, err
end
local match, err = ipm:match(ngx.var.remote_addr)
local match, err = ipm:match(ngx.ctx.bw.remote_addr)
if err then
return nil, err
end
@ -219,18 +223,12 @@ function whitelist:is_whitelisted_ip()
-- Check if rDNS is needed
local check_rdns = true
local is_global, err = utils.ip_is_global(ngx.var.remote_addr)
if self.variables["WHITELIST_RDNS_GLOBAL"] == "yes" then
if is_global == nil then
return nil, err
end
if not is_global then
check_rdns = false
end
if self.variables["WHITELIST_RDNS_GLOBAL"] == "yes" and not ngx.ctx.bw.ip_is_global then
check_rdns = false
end
if check_rdns then
-- Get rDNS
local rdns_list, err = utils.get_rdns(ngx.var.remote_addr)
local rdns_list, err = utils.get_rdns(ngx.ctx.bw.remote_addr)
if not rdns_list then
return nil, err
end
@ -245,8 +243,8 @@ function whitelist:is_whitelisted_ip()
end
-- Check if ASN is in whitelist
if is_global then
local asn, err = utils.get_asn(ngx.var.remote_addr)
if ngx.ctx.bw.ip_is_global then
local asn, err = utils.get_asn(ngx.ctx.bw.remote_addr)
if not asn then
return nil, err
end
@ -264,7 +262,7 @@ end
function whitelist:is_whitelisted_uri()
-- Check if URI is in whitelist
for i, uri in ipairs(self.lists["URI"]) do
if ngx.var.uri:match(uri) then
if ngx.ctx.bw.uri:match(uri) then
return true, "URI " .. uri
end
end
@ -275,7 +273,7 @@ end
function whitelist:is_whitelisted_ua()
-- Check if UA is in whitelist
for i, ua in ipairs(self.lists["USER_AGENT"]) do
if ngx.var.http_user_agent:match(ua) then
if ngx.ctx.bw.http_user_agent:match(ua) then
return true, "UA " .. ua
end
end