Sindbad~EG File Manager
--[[
This file is used to retrieve the WAF Configuration and acting upon it. It will return with different HTTP status code
depending on the situation and the WAF Configuration detected. Different Nginx block will be triggered based on the
HTTP Status code returned from here.
--]]
local o2utils = require "lib/o2switch_utils"
local o2redis = require "lib/o2switch_redis"
local cacheWrapper = require "lib/o2switch_cache_wrapper"
local o2counter = require "lib/o2switch_counter"
local config = require "lib/o2switch_config"
local o2debug = require "lib/o2switch_debug"
local o2counter = require "lib/o2switch_counter"
local ban = require "lib/o2switch_ban"
local ngx = ngx
local pairs = pairs
local type = type
local binaryClientIp = ngx.var.binary_remote_addr
local map_underattack_wl = ngx.var.map_underattack_wl
-- Blacklist check. First of all, to be ultra-fast
if ban.isBlacklisted(binaryClientIp) == true then
ngx.exit(444)
end
-- Meaning of the return HTTP code in here.
local BYPASS_ALL_SECURITY = 588
local DEFAULT_SECURITY = 589
local CUSTOM_SECURITY = 590
-- 1. Redis Key, remove the www + proxy subdomain if it's present
local name = o2utils.extractDomainWww(ngx.var.host)
if not name then
o2utils.ngxFinalError(503, 'Direct access denied, no hostname provided')
end
-- 2. Get the value from the cache, or from redis if we don't have it in the Nginx cache (populate the cache too)
local data, err = cacheWrapper.get(name, o2redis.getFromRedis, name)
if (err ~= nil or type(data) ~= 'table' or type(data[4]) ~= 'string') and config.serverType == 'mutu' then
-- Remove common cPanel subdomain
name = o2utils.extractDomain(name)
data, err = cacheWrapper.get(name, o2redis.getFromRedis, name)
end
if (err ~= nil or type(data) ~= 'table' or type(data[4]) ~= 'string') then
-- If it's a mutu, we'll check for a wildcard and default to the defautProxyPass ...
if config.serverType == 'mutu' then
-- Can be a wildcard case, try again but we transform the first subdom to wildcard this time
name = o2utils.transformSubdomainToWildcard(name)
data, err = cacheWrapper.get(name, o2redis.getFromRedis, name)
-- Still no result, we use the default proxypass ...
if (err ~= nil or type(data) ~= 'table' or type(data[4]) ~= 'string') then
ngx.exit(DEFAULT_SECURITY) -- Note : previously was BYPASS_ALL_SECURITY 11/10/22
end
else
-- On a edge server, we return an error if nothing is found in the first place
err = err or 'nothing'
--o2debug.debug("No vhost found for : " .. name .. ". Err = " .. err)
ngx.var.additionalErrorMessage = 'Pas de configuration pour le domaine ' .. name .. ' (ipxtender/lscache/xtremcache actif/configuré ?)'
ngx.exit(503)
end
end
-- Chech the auto-triggering security
local autoMitigation, count = nil, 0
--if map_underattack_wl ~= '1' and map_underattack_wl ~= 1 then -- Didn't know we could use the map_* directly before :(
autoMitigation, count = o2counter.check('i', binaryClientIp) -- Req/ip auto mitigation
--o2debug.debug("Auto-mitigation : " .. (autoMitigation or 'NO'))
if (type(autoMitigation) ~= 'string') then
autoMitigation, count = o2counter.check('d', name) -- Req/domain auto mitigation
else
-- Temp ban of IP, to optimize and drop at the ssl handshake directly
if autoMitigation == config.mitigationType.TmpBan then
local ok, err = ban.addIpToBlacklist(binaryClientIp, map_underattack_wl)
if ok then
ngx.exit(444)
end
end
-- If set to 1, will re-ask the JS/Cookie/Captcha challenge and ignore the o2w-chl cookie
-- Default value is set to 0 in an Nginx file directly (as we must pre-declare ngx.var to avoid errors)
-- We only to this for the per IP limit, as he would be weird for the domain limit.
ngx.var['autoMitigationOverride'] = 1
end
--o2debug.debug("Auto-mitigation : " .. (autoMitigation or 'NO'))
if type(autoMitigation) == 'string' then
--o2debug.debug("Override, automitigation = " .. autoMitigation)
ngx.var['autoMitigation'] = autoMitigation
end
--end
-- 3. Checking the waf configuration. It's in the additionnalParams in data[10]
if data[10] == nil or data[10] == "" or data[10]['wafCustomization'] == nil or data[10]['wafCustomization'] == "" then
--o2debug.debug("No waf config found for " .. name .. " so using the default security")
ngx.exit(DEFAULT_SECURITY) -- Default security
end
-- Pass the security rules config as Nginx variables
local customRules = 0
local waf = data[10]
for ruleName, ruleConfig in pairs(waf['wafCustomization']) do
--o2debug.debug("Setting the security rule name '" .. ruleName .. "' to the value :" .. (ruleConfig['action'] or 'disabled'))
ngx.var[ruleName] = ruleConfig['action'] or 'disabled'
if (ruleConfig['action'] or 'disabled') ~= 'disabled' then
customRules = 1
end
end
-- Check if the customer want the o2switch default security too.
if not waf['wafCustomization'] or not waf['wafCustomization']['r_default']
or not waf['wafCustomization']['r_default']['action']
or waf['wafCustomization']['r_default']['action'] ~= 'enabled' then
if customRules == 1 then
ngx.exit(CUSTOM_SECURITY)
end
if type(autoMitigation) == 'string' then
ngx.exit(CUSTOM_SECURITY)
end
ngx.exit(BYPASS_ALL_SECURITY)
end
ngx.exit(DEFAULT_SECURITY)
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists