stream - add is_stream variable to check if we are in stream or http mode

This commit is contained in:
florian 2023-02-21 20:03:57 +01:00
parent 4f4c8ebf08
commit 947ecf81f1
No known key found for this signature in database
GPG Key ID: 3D80806F12602A7C
7 changed files with 209 additions and 4 deletions

View File

@ -353,8 +353,8 @@ utils.rand = function(nb)
return result
end
utils.get_deny_status = function(stream)
if stream then
utils.get_deny_status = function()
if ngx.var.is_stream == "yes" then
return 403
end
local status, err = datastore:get("variable_DENY_HTTP_STATUS")

View File

@ -11,7 +11,7 @@ logger.log(ngx.INFO, "PREREAD", "Preread phase started")
local banned, err = datastore:get("bans_ip_" .. ngx.var.remote_addr)
if banned then
logger.log(ngx.WARN, "PREREAD", "IP " .. ngx.var.remote_addr .. " is banned with reason : " .. banned)
ngx.exit(utils.get_deny_status(true))
ngx.exit(utils.get_deny_status())
end
-- Redis case
local use_redis = utils.get_variable("USE_REDIS")
@ -64,7 +64,7 @@ for i, plugin in ipairs(list) do
end
if ret then
if type(value) == "number" then
if value == utils.get_deny_status(true) then
if value == utils.get_deny_status() then
logger.log(ngx.WARN, "PREREAD", "Denied access from " .. plugin.id .. " : " .. err)
ngx.var.reason = plugin.id
else

View File

@ -14,6 +14,9 @@ server {
# reason variable
set $reason '';
# stream flag
set $is_stream 'yes';
# include LUA files
include {{ NGINX_PREFIX }}preread-stream-lua.conf;
include {{ NGINX_PREFIX }}log-stream-lua.conf;

View File

@ -329,6 +329,179 @@ function _M:access()
return ret, "IP is not in list (error = " .. ret_err .. ")", false, nil
end
function _M:preread()
-- Check if preread is needed
local preread_needed, err = utils.get_variable("USE_BLACKLIST")
if preread_needed == nil then
return false, err
end
if access_needed ~= "yes" then
return true, "Blacklist not activated"
end
-- Check the cache
local cached_ip, err = self:is_in_cache("ip" .. ngx.var.remote_addr)
local cached_ignored_ip, err = self:is_in_cache("ignore_ip" .. ngx.var.remote_addr)
if cached_ignored_ip then
logger.log(ngx.NOTICE, "BLACKLIST", "IP is in cached ignore blacklist (info: " .. cached_ignored_ip .. ")")
elseif cached_ip and cached_ip ~= "ok" then
return true, "IP is in blacklist cache (info = " .. cached_ip .. ")", true, utils.get_deny_status()
elseif cached_ip
return true, "IP is in blacklist cache (not blacklisted)", false, nil
end
-- Get list
local data, err = datastore:get("plugin_blacklist_list")
if not data then
return false, "can't get Blacklist list : " .. err, false, nil
end
local ok, blacklists = pcall(cjson.decode, data)
if not ok then
return false, "error while decoding blacklists : " .. blacklists, false, nil
end
-- Return value
local ret, ret_err = true, "success"
-- Check if IP is in IP/net blacklist
local ip_net, err = utils.get_variable("BLACKLIST_IP")
local ignored_ip_net, err = utils.get_variable("BLACKLIST_IGNORE_IP")
if ip_net and ip_net ~= "" then
for element in ip_net:gmatch("%S+") do
table.insert(blacklists["IP"], element)
end
end
if ignored_ip_net and ignored_ip_net ~= "" then
for element in ignored_ip_net:gmatch("%S+") do
table.insert(blacklists["IGNORE_IP"], element)
end
end
if not cached_ip then
local ipm, err = ipmatcher.new(blacklists["IP"])
local ipm_ignore, err_ignore = ipmatcher.new(blacklists["IGNORE_IP"])
if not ipm then
ret = false
ret_err = "can't instantiate ipmatcher " .. err
elseif not ipm_ignore then
ret = false
ret_err = "can't instantiate ipmatcher " .. err_ignore
else
if ipm:match(ngx.var.remote_addr) then
if ipm_ignore:match(ngx.var.remote_addr) then
self:add_to_cache("ignore_ip" .. ngx.var.remote_addr, "ip/net")
logger.log(ngx.NOTICE, "BLACKLIST", "client IP " .. ngx.var.remote_addr .. " is in blacklist but is ignored")
else
self:add_to_cache("ip" .. ngx.var.remote_addr, "ip/net")
return ret, "client IP " .. ngx.var.remote_addr .. " is in blacklist", true, utils.get_deny_status()
end
end
end
end
-- Instantiate ignore variable
local ignore = false
-- Check if rDNS is in blacklist
local rdns_global, err = utils.get_variable("BLACKLIST_RDNS_GLOBAL")
local check = true
if not rdns_global then
logger.log(ngx.ERR, "BLACKLIST", "Error while getting BLACKLIST_RDNS_GLOBAL variable : " .. err)
elseif rdns_global == "yes" then
check, err = utils.ip_is_global(ngx.var.remote_addr)
if check == nil then
logger.log(ngx.ERR, "BLACKLIST", "Error while getting checking if IP is global : " .. err)
end
end
if not cached_ip and check then
local rdns, err = utils.get_rdns(ngx.var.remote_addr)
if not rdns then
ret = false
ret_err = "error while trying to get reverse dns : " .. err
else
local rdns_list, err = utils.get_variable("BLACKLIST_RDNS")
local ignored_rdns_list, err = utils.get_variable("BLACKLIST_IGNORE_RDNS")
if rdns_list and rdns_list ~= "" then
for element in rdns_list:gmatch("%S+") do
table.insert(blacklists["RDNS"], element)
end
end
if ignored_rdns_list and ignored_rdns_list ~= "" then
for element in ignored_rdns_list:gmatch("%S+") do
table.insert(blacklists["IGNORE_RDNS"], element)
end
end
for i, suffix in ipairs(blacklists["RDNS"]) do
if rdns:sub(- #suffix) == suffix then
for j, ignore_suffix in ipairs(blacklists["IGNORE_RDNS"]) do
if rdns:sub(- #ignore_suffix) == ignore_suffix then
ignore = true
self:add_to_cache("ignore_rdns" .. ngx.var.remote_addr, "rDNS" .. suffix)
logger.log(ngx.NOTICE, "BLACKLIST",
"client IP " .. ngx.var.remote_addr .. " is in blacklist (info = rDNS " .. suffix .. ") but is ignored")
break
end
end
if not ignore then
self:add_to_cache("ip" .. ngx.var.remote_addr, "rDNS" .. suffix)
return ret, "client IP " .. ngx.var.remote_addr .. " is in blacklist (info = rDNS " .. suffix .. ")", true,
utils.get_deny_status()
end
end
end
end
end
-- Check if ASN is in blacklist
if not cached_ip then
if utils.ip_is_global(ngx.var.remote_addr) then
local asn, err = utils.get_asn(ngx.var.remote_addr)
if not asn then
ret = false
ret_err = "error while trying to get asn number : " .. err
else
local asn_list, err = utils.get_variable("BLACKLIST_ASN")
local ignored_asn_list, err = utils.get_variable("BLACKLIST_IGNORE_ASN")
if asn_list and asn_list ~= "" then
for element in asn_list:gmatch("%S+") do
table.insert(blacklists["ASN"], element)
end
end
if ignored_asn_list and ignored_asn_list ~= "" then
for element in ignored_asn_list:gmatch("%S+") do
table.insert(blacklists["IGNORE_ASN"], element)
end
end
for i, asn_bl in ipairs(blacklists["ASN"]) do
if tostring(asn) == asn_bl then
for j, ignore_asn_bl in ipairs(blacklists["IGNORE_ASN"]) do
if tostring(asn) == ignore_asn_bl then
ignore = true
self:add_to_cache("ignore_asn" .. ngx.var.remote_addr, "ASN" .. tostring(asn))
logger.log(ngx.NOTICE, "BLACKLIST",
"client IP " .. ngx.var.remote_addr .. " is in blacklist (info = ASN " .. tostring(asn) .. ") but is ignored")
break
end
end
if not ignore then
self:add_to_cache("ip" .. ngx.var.remote_addr, "ASN " .. tostring(asn))
return ret, "client IP " .. ngx.var.remote_addr .. " is in blacklist (kind = ASN " .. tostring(asn) .. ")", true,
utils.get_deny_status()
end
end
end
end
end
end
-- IP is not blacklisted
local ok, err = self:add_to_cache("ip" .. ngx.var.remote_addr, "ok")
if not ok then
ret = false
ret_err = err
end
return ret, "IP is not in list (error = " .. ret_err .. ")", false, nil
end
function _M:is_in_cache(ele)
local kind, err = datastore:get("plugin_blacklist_cache_" .. ngx.var.server_name .. ele)
if not kind then

View File

@ -0,0 +1,20 @@
{% set os_path = import("os.path") %}
{% if USE_CUSTOM_HTTPS == "yes" and os_path.isfile("/data/cache/customcert/{}".format(CUSTOM_HTTPS_CERT.replace("/", "_"))) and os_path.isfile("/data/cache/customcert/{}".format(CUSTOM_HTTPS_KEY.replace("/", "_"))) +%}
# listen
listen 0.0.0.0:{{ LISTEN_STREAM_PORT_SSL }} ssl {% if USE_UDP == "yes" %} udp {% endif %}{% if USE_PROXY_PROTOCOL == "yes" %} proxy_protocol {% endif %};
# TLS config
ssl_certificate /data/cache/customcert/{{ CUSTOM_HTTPS_CERT.replace("/", "_") }};
ssl_certificate_key /data/cache/customcert/{{ CUSTOM_HTTPS_KEY.replace("/", "_") }};
ssl_protocols {{ HTTPS_PROTOCOLS }};
ssl_prefer_server_ciphers on;
ssl_session_tickets off;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
{% if "TLSv1.2" in HTTPS_PROTOCOLS +%}
ssl_dhparam /etc/nginx/dhparam;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
{% endif %}
{% endif %}

View File

@ -97,6 +97,10 @@ function _M:access()
end
function _M:preread()
return self:access()
end
function _M:is_in_dnsbl(dnsbl, ip)
local request = resolver.arpa_str(ip) .. "." .. dnsbl
local ips, err = utils.get_ips(request)

View File

@ -0,0 +1,5 @@
{% if USE_WHITELIST == "yes" +%}
{% if WHITELIST_IP != "" +%}
SecRule REMOTE_ADDR "@ipMatch {{ WHITELIST_IP.replace(" ", ",") }}" "id:1000,phase:1,t:none,nolog,pass,ctl:ruleEngine=Off"
{% endif +%}
{% endif +%}