mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 01:18:26 +00:00
misc - add DENY_HTTP_STATUS setting (403 or 444)
This commit is contained in:
parent
90e58f2612
commit
5586b3733b
12 changed files with 67 additions and 24 deletions
14
.github/ISSUE_TEMPLATE/documentation.md
vendored
Normal file
14
.github/ISSUE_TEMPLATE/documentation.md
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
name: Documentation enhancement
|
||||
about: Error in the documentation or something is missing
|
||||
title: "[DOC]"
|
||||
labels: documentation
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Description**
|
||||
Concise description of the error or what is missing.
|
||||
|
||||
**Proposal (optional)**
|
||||
Any proposal or ideas to fix the problem.
|
||||
|
|
@ -2,7 +2,13 @@
|
|||
|
||||
## v1.4.3 -
|
||||
|
||||
- Add \*_CUSTOM_CONF_\* setting to automatically add custom config files from setting value
|
||||
- Fix various documentation errors/typos
|
||||
- Fix ui.env not read when using Linux integration
|
||||
- Fix check if BunkerNet is activated on default server
|
||||
- Add \*_CUSTOM_CONF_\* setting to automatically add custom config files from setting value
|
||||
- Add DENY_HTTP_STATUS setting to choose standard 403 error (default) or to close connection (444)
|
||||
- Add documentation about Docker in rootless mode and podman
|
||||
- Migrate CI/CD to another provider
|
||||
|
||||
## v1.4.2 - 2022/06/28
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ access_by_lua_block {
|
|||
local logger = require "logger"
|
||||
local datastore = require "datastore"
|
||||
local plugins = require "plugins"
|
||||
local utils = require "utils"
|
||||
|
||||
-- Don't process internal requests
|
||||
if ngx.req.is_internal() then
|
||||
|
|
@ -16,7 +17,7 @@ logger.log(ngx.INFO, "ACCESS", "Access phase started")
|
|||
local banned, err = datastore:get("bans_ip_" .. ngx.var.remote_addr)
|
||||
if banned then
|
||||
logger.log(ngx.WARN, "ACCESS", "IP " .. ngx.var.remote_addr .. " is banned with reason : " .. banned)
|
||||
ngx.exit(ngx.HTTP_FORBIDDEN)
|
||||
ngx.exit(utils.get_deny_status())
|
||||
end
|
||||
|
||||
-- List all plugins
|
||||
|
|
@ -41,7 +42,7 @@ for i, plugin in ipairs(list) do
|
|||
end
|
||||
if ret then
|
||||
if type(value) == "number" then
|
||||
if value == ngx.HTTP_FORBIDDEN then
|
||||
if value == utils.get_deny_status() then
|
||||
logger.log(ngx.WARN, "ACCESS", "Denied access from " .. plugin.id .. " : " .. err)
|
||||
ngx.var.reason = plugin.id
|
||||
else
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ function _M:access()
|
|||
end
|
||||
|
||||
-- Method is suspicious, let's deny the request
|
||||
return true, "unsupported HTTP method for Antibot", true, ngx.HTTP_FORBIDDEN
|
||||
return true, "unsupported HTTP method for Antibot", true, utils.get_deny_status()
|
||||
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -61,17 +61,17 @@ function _M:access()
|
|||
-- Check the cache
|
||||
local cached_ip, err = self:is_in_cache("ip" .. ngx.var.remote_addr)
|
||||
if cached_ip and cached_ip ~= "ok" then
|
||||
return true, "IP is in blacklist cache (info = " .. cached_ip .. ")", true, ngx.HTTP_FORBIDDEN
|
||||
return true, "IP is in blacklist cache (info = " .. cached_ip .. ")", true, utils.get_deny_status()
|
||||
end
|
||||
local cached_uri, err = self:is_in_cache("uri" .. ngx.var.uri)
|
||||
if cached_uri and cached_uri ~= "ok" then
|
||||
return true, "URI is in blacklist cache (info = " .. cached_uri .. ")", true, ngx.HTTP_FORBIDDEN
|
||||
return true, "URI is in blacklist cache (info = " .. cached_uri .. ")", true, utils.get_deny_status()
|
||||
end
|
||||
local cached_ua = true
|
||||
if ngx.var.http_user_agent then
|
||||
cached_ua, err = self:is_in_cache("ua" .. ngx.var.http_user_agent)
|
||||
if cached_ua and cached_ua ~= "ok" then
|
||||
return true, "User-Agent is in blacklist cache (info = " .. cached_ua .. ")", true, ngx.HTTP_FORBIDDEN
|
||||
return true, "User-Agent is in blacklist cache (info = " .. cached_ua .. ")", true, utils.get_deny_status()
|
||||
end
|
||||
end
|
||||
if cached_ip and cached_uri and cached_ua then
|
||||
|
|
@ -106,7 +106,7 @@ function _M:access()
|
|||
else
|
||||
if ipm:match(ngx.var.remote_addr) then
|
||||
self:add_to_cache("ip" .. ngx.var.remote_addr, "ip/net")
|
||||
return ret, "client IP " .. ngx.var.remote_addr .. " is in blacklist", true, ngx.HTTP_FORBIDDEN
|
||||
return ret, "client IP " .. ngx.var.remote_addr .. " is in blacklist", true, utils.get_deny_status()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -137,7 +137,7 @@ function _M:access()
|
|||
for i, suffix in ipairs(blacklists["RDNS"]) do
|
||||
if rdns:sub(-#suffix) == suffix 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, ngx.HTTP_FORBIDDEN
|
||||
return ret, "client IP " .. ngx.var.remote_addr .. " is in blacklist (info = rDNS " .. suffix .. ")", true, utils.get_deny_status()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -160,7 +160,7 @@ function _M:access()
|
|||
for i, asn_bl in ipairs(blacklists["ASN"]) do
|
||||
if tostring(asn) == asn_bl 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, ngx.HTTP_FORBIDDEN
|
||||
return ret, "client IP " .. ngx.var.remote_addr .. " is in blacklist (kind = ASN " .. tostring(asn) .. ")", true, utils.get_deny_status()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -185,7 +185,7 @@ function _M:access()
|
|||
for i, ua_bl in ipairs(blacklists["USER_AGENT"]) do
|
||||
if ngx.var.http_user_agent:match(ua_bl) then
|
||||
self:add_to_cache("ua" .. ngx.var.http_user_agent, "UA " .. ua_bl)
|
||||
return ret, "client User-Agent " .. ngx.var.http_user_agent .. " is in blacklist (matched " .. ua_bl .. ")", true, ngx.HTTP_FORBIDDEN
|
||||
return ret, "client User-Agent " .. ngx.var.http_user_agent .. " is in blacklist (matched " .. ua_bl .. ")", true, utils.get_deny_status()
|
||||
end
|
||||
end
|
||||
-- UA is not blacklisted
|
||||
|
|
@ -207,7 +207,7 @@ function _M:access()
|
|||
for i, uri_bl in ipairs(blacklists["URI"]) do
|
||||
if ngx.var.uri:match(uri_bl) then
|
||||
self:add_to_cache("uri" .. ngx.var.uri, "URI " .. uri_bl)
|
||||
return ret, "client URI " .. ngx.var.uri .. " is in blacklist (matched " .. uri_bl .. ")", true, ngx.HTTP_FORBIDDEN
|
||||
return ret, "client URI " .. ngx.var.uri .. " is in blacklist (matched " .. uri_bl .. ")", true, utils.get_deny_status()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ function _M:report(ip, reason, method, url, headers)
|
|||
end
|
||||
|
||||
function _M:log(bypass_use_bunkernet)
|
||||
if bypass_use_bunkernet then
|
||||
if not bypass_use_bunkernet then
|
||||
-- Check if BunkerNet is activated
|
||||
local use_bunkernet = utils.get_variable("USE_BUNKERNET")
|
||||
if use_bunkernet ~= "yes" then
|
||||
|
|
@ -232,7 +232,7 @@ function _M:access()
|
|||
local db = cjson.decode(data)
|
||||
for index, value in ipairs(db.ip) do
|
||||
if value == ngx.var.remote_addr then
|
||||
return true, "ip is in database", true, ngx.exit(ngx.HTTP_FORBIDDEN)
|
||||
return true, "ip is in database", true, utils.get_deny_status()
|
||||
end
|
||||
end
|
||||
return true, "ip is not in database", false, nil
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ function _M:access()
|
|||
if data.result == "ok" then
|
||||
return true, "client IP " .. ngx.var.remote_addr .. " is in country cache (not blacklisted, country = " .. data.country .. ")", nil, nil
|
||||
end
|
||||
return true, "client IP " .. ngx.var.remote_addr .. " is in country cache (blacklisted, country = " .. data.country .. ")", true, ngx.HTTP_FORBIDDEN
|
||||
return true, "client IP " .. ngx.var.remote_addr .. " is in country cache (blacklisted, country = " .. data.country .. ")", true, utils.get_deny_status()
|
||||
end
|
||||
|
||||
-- Don't go further if IP is not global
|
||||
|
|
@ -60,7 +60,7 @@ function _M:access()
|
|||
end
|
||||
end
|
||||
self:add_to_cache(ngx.var.remote_addr, country, "ko")
|
||||
return true, "client IP " .. ngx.var.remote_addr .. " is not whitelisted (country = " .. country .. ")", true, ngx.HTTP_FORBIDDEN
|
||||
return true, "client IP " .. ngx.var.remote_addr .. " is not whitelisted (country = " .. country .. ")", true, utils.get_deny_status()
|
||||
end
|
||||
|
||||
-- And then blacklist
|
||||
|
|
@ -68,7 +68,7 @@ function _M:access()
|
|||
for bl_country in blacklist:gmatch("%S+") do
|
||||
if bl_country == country then
|
||||
self:add_to_cache(ngx.var.remote_addr, country, "ko")
|
||||
return true, "client IP " .. ngx.var.remote_addr .. " is blacklisted (country = " .. country .. ")", true, ngx.HTTP_FORBIDDEN
|
||||
return true, "client IP " .. ngx.var.remote_addr .. " is blacklisted (country = " .. country .. ")", true, utils.get_deny_status()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ function _M:access()
|
|||
if dnsbl == "ok" then
|
||||
return true, "client IP " .. ngx.var.remote_addr .. " is in DNSBL cache (not blacklisted)", nil, nil
|
||||
end
|
||||
return true, "client IP " .. ngx.var.remote_addr .. " is in DNSBL cache (server = " .. dnsbl .. ")", true, ngx.HTTP_FORBIDDEN
|
||||
return true, "client IP " .. ngx.var.remote_addr .. " is in DNSBL cache (server = " .. dnsbl .. ")", true, utils.get_deny_status()
|
||||
end
|
||||
|
||||
-- Don't go further if IP is not global
|
||||
|
|
@ -84,7 +84,7 @@ function _M:access()
|
|||
local result, err = self:is_in_dnsbl(dnsbl, ngx.var.remote_addr)
|
||||
if result then
|
||||
self:add_to_cache(ngx.var.remote_addr, dnsbl)
|
||||
return ret, "client IP " .. ngx.var.remote_addr .. " is in DNSBL (server = " .. dnsbl .. ")", true, ngx.HTTP_FORBIDDEN
|
||||
return ret, "client IP " .. ngx.var.remote_addr .. " is in DNSBL (server = " .. dnsbl .. ")", true, utils.get_deny_status()
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{% if DISABLE_DEFAULT_SERVER == "yes" +%}
|
||||
location / {
|
||||
set $reason "default";
|
||||
return 444;
|
||||
return {{ DENY_HTTP_STATUS }};
|
||||
}
|
||||
{% endif %}
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
"label": "Auto redirect HTTP to HTTPS",
|
||||
"regex": ".*",
|
||||
"type": "text"
|
||||
},
|
||||
},
|
||||
"ALLOWED_METHODS": {
|
||||
"context": "multisite",
|
||||
"default": "GET|POST|HEAD",
|
||||
|
|
@ -148,6 +148,19 @@
|
|||
"label": "External plugin URLs",
|
||||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
},
|
||||
"DENY_HTTP_STATUS": {
|
||||
"context": "global",
|
||||
"default": "403",
|
||||
"help": "HTTP status code to send when the request is denied (403 or 444). When using 444, BunkerWeb will close the connection.",
|
||||
"id": "deny-http-status",
|
||||
"label": "Deny HTTP status",
|
||||
"regex": "^(403|444)$",
|
||||
"type": "select",
|
||||
"select": [
|
||||
"403",
|
||||
"444"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,6 +105,6 @@ include /etc/nginx/{{ SERVER_NAME.split(" ")[0] }}/modsec/*.conf
|
|||
|
||||
# set REASON env var
|
||||
{% if USE_MODSECURITY_CRS == "yes" %}
|
||||
SecRuleUpdateActionById 949110 "t:none,deny,status:403,setenv:REASON=modsecurity"
|
||||
SecRuleUpdateActionById 959100 "t:none,deny,status:403,setenv:REASON=modsecurity"
|
||||
SecRuleUpdateActionById 949110 "t:none,deny,status:{{ DENY_HTTP_STATUS }},setenv:REASON=modsecurity"
|
||||
SecRuleUpdateActionById 959100 "t:none,deny,status:{{ DENY_HTTP_STATUS }},setenv:REASON=modsecurity"
|
||||
{% endif %}
|
||||
|
|
@ -248,7 +248,7 @@ utils.get_reason = function()
|
|||
if banned then
|
||||
return banned
|
||||
end
|
||||
if ngx.status == ngx.HTTP_FORBIDDEN then
|
||||
if ngx.status == utils.get_deny_status() then
|
||||
return "unknown"
|
||||
end
|
||||
return nil
|
||||
|
|
@ -347,4 +347,13 @@ utils.rand = function(nb)
|
|||
return result
|
||||
end
|
||||
|
||||
utils.get_deny_status = function ()
|
||||
local status, err = datastore:get("variable_DENY_HTTP_STATUS")
|
||||
if not status then
|
||||
logger.log(ngx.ERR, "UTILS", "Can't get DENY_HTTP_STATUS variable " .. err)
|
||||
return 403
|
||||
end
|
||||
return tonumber(status)
|
||||
end
|
||||
|
||||
return utils
|
||||
Loading…
Reference in a new issue