refactor - disable asn checks for non global IPs, use resty.template with antibot and various fixes
This commit is contained in:
parent
8d63e39740
commit
2fddbd8627
3
TODO
3
TODO
|
@ -1,5 +1,6 @@
|
|||
- utils refactoring
|
||||
- use resty.template for antibot
|
||||
- load inline values for white/black/grey list core
|
||||
- check if correct setting is set to yes in new() before loading stuff in self
|
||||
- store object in ngx.ctx
|
||||
- bwcli with redis
|
||||
- move bans to cachestore
|
||||
|
|
|
@ -31,7 +31,7 @@ if not ok then
|
|||
end
|
||||
|
||||
-- Process bans as soon as possible
|
||||
local ok, reason = cachestore:get("bans_ip_" .. ngx.var.remote_addr)
|
||||
local ok, reason = datastore:get("bans_ip_" .. ngx.var.remote_addr)
|
||||
if not ok and reason then
|
||||
logger:log(ngx.INFO, "error while checking if client is banned : " .. reason)
|
||||
return false
|
||||
|
|
|
@ -8,40 +8,13 @@ local base64 = require "base64"
|
|||
local sha256 = require "resty.sha256"
|
||||
local str = require "resty.string"
|
||||
local http = require "resty.http"
|
||||
local template = require "resty.template"
|
||||
|
||||
local antibot = class("antibot", plugin)
|
||||
|
||||
function antibot:initialize()
|
||||
-- Call parent initialize
|
||||
plugin.initialize(self, "antibot")
|
||||
-- Check if init is needed
|
||||
if ngx.get_phase() == "init" then
|
||||
local init_needed, err = utils.has_not_variable("USE_ANTIBOT", "no")
|
||||
if init_needed == nil then
|
||||
self.logger:log(ngx.ERR, err)
|
||||
end
|
||||
self.init_needed = init_needed
|
||||
end
|
||||
end
|
||||
|
||||
function antibot:init()
|
||||
if self.init_needed then
|
||||
-- Load templates
|
||||
local templates = {}
|
||||
for i, template in ipairs({ "javascript", "captcha", "recaptcha", "hcaptcha" }) do
|
||||
local f, err = io.open("/usr/share/bunkerweb/core/antibot/files/" .. template .. ".html")
|
||||
if not f then
|
||||
return self:ret(false, "error while loading " .. template .. ".html : " .. err)
|
||||
end
|
||||
templates[template] = f:read("*all")
|
||||
f:close()
|
||||
end
|
||||
local ok, err = self.datastore:set("plugin_antibot_templates", cjson.encode(templates))
|
||||
if not ok then
|
||||
return self:ret(false, "can't save templates to datastore : " .. err)
|
||||
end
|
||||
end
|
||||
return self:ret(true, "success")
|
||||
end
|
||||
|
||||
function antibot:access()
|
||||
|
@ -195,38 +168,33 @@ function antibot:display_challenge(challenge_uri)
|
|||
return false, "session type is different from antibot type"
|
||||
end
|
||||
|
||||
-- Load HTML templates
|
||||
local str_templates, err = self.datastore:get("plugin_antibot_templates")
|
||||
if not str_templates then
|
||||
return false, "can't get templates from datastore : " .. err
|
||||
end
|
||||
local templates = cjson.decode(str_templates)
|
||||
|
||||
local html = ""
|
||||
-- Common variables for templates
|
||||
local template_vars = {
|
||||
antibot_uri = self.variables["ANTIBOT_URI"]
|
||||
}
|
||||
|
||||
-- Javascript case
|
||||
if self.variables["USE_ANTIBOT"] == "javascript" then
|
||||
html = templates.javascript:format(self.variables["ANTIBOT_URI"], data.random)
|
||||
template_vars.random = data.random
|
||||
end
|
||||
|
||||
-- Captcha case
|
||||
if self.variables["USE_ANTIBOT"] == "captcha" then
|
||||
html = templates.captcha:format(self.variables["ANTIBOT_URI"], data.image)
|
||||
template_vars.captcha = data.image
|
||||
end
|
||||
|
||||
-- reCAPTCHA case
|
||||
if self.variables["USE_ANTIBOT"] == "recaptcha" then
|
||||
html = templates.recaptcha:format(self.variables["ANTIBOT_RECAPTCHA_SITEKEY"], self.variables["ANTIBOT_URI"], self.variables["ANTIBOT_RECAPTCHA_SITEKEY"])
|
||||
template_vars.recaptcha_sitekey = self.variables["ANTIBOT_RECAPTCHA_SITEKEY"]
|
||||
end
|
||||
|
||||
-- hCaptcha case
|
||||
if self.variables["USE_ANTIBOT"] == "hcaptcha" then
|
||||
html = templates.hcaptcha:format(self.variables["ANTIBOT_URI"], self.variables["ANTIBOT_HCAPTCHA_SITEKEY"])
|
||||
template_vars.hcaptcha_sitekey = self.variables["ANTIBOT_HCAPTCHA_SITEKEY"]
|
||||
end
|
||||
|
||||
-- Send content
|
||||
ngx.header["Content-Type"] = "text/html"
|
||||
ngx.say(html)
|
||||
-- Render content
|
||||
template.render(self.variables["USE_ANTIBOT"] .. ".html", template_vars)
|
||||
|
||||
return true, "displayed challenge"
|
||||
end
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
{% if USE_ANTIBOT == "yes" +%}
|
||||
location /{{ ANTIBOT_URI }} {
|
||||
root /usr/share/bunkerweb/core/antibot/files;
|
||||
content_by_lua_block {
|
||||
local antibot = require "antibot.antibot"
|
||||
local logger = require "bunkerweb.logger"
|
||||
antibot:new()
|
||||
logger:new("ANTIBOT")
|
||||
local cantibot = require "antibot.antibot"
|
||||
local clogger = require "bunkerweb.logger"
|
||||
local antibot = cantibot:new()
|
||||
local logger = clogger:new("ANTIBOT")
|
||||
local ok, err = antibot:content()
|
||||
if not ok then
|
||||
logger:log(ngx.ERR, "antibot:content() failed : " .. err)
|
||||
|
|
|
@ -6,26 +6,26 @@
|
|||
<title>Bot Detection</title>
|
||||
<link
|
||||
rel="icon"
|
||||
href="data:image/svg+xml, %%3Csvg version='1.0' xmlns='http://www.w3.org/2000/svg' width='96.000000pt' height='96.000000pt' viewBox='0 0 96.000000 96.000000' preserveAspectRatio='xMidYMid meet'%%3E%%3Cg transform='translate(0.000000,96.000000) scale(0.100000,-0.100000)'%%0Afill='%%23085577' stroke='none'%%3E%%3Cpath d='M535 863 c-22 -2 -139 -17 -260 -34 -228 -31 -267 -43 -272 -85 -2%%0A-10 23 -181 55 -379 l57 -360 400 0 400 0 20 40 c16 31 20 59 19 125 -1 100%%0A-24 165 -73 199 -41 29 -46 57 -22 111 30 67 29 188 -3 256 -13 28 -37 60 -53%%0A72 -55 39 -169 62 -268 55z m-15 -348 c30 -16 60 -61 60 -90 0 -10 -8 -33 -17%%0A-52 -16 -34 -16 -41 0 -116 9 -44 15 -82 12 -85 -6 -7 -92 -21 -131 -21 l-31%%0A-1 -6 85 c-4 75 -8 89 -31 112 -20 20 -26 36 -26 70 0 38 5 50 34 79 39 39 86%%0A45 136 19z'/%%3E%%3C/g%%3E%%3C/svg%%3E"
|
||||
href="data:image/svg+xml, %3Csvg version='1.0' xmlns='http://www.w3.org/2000/svg' width='96.000000pt' height='96.000000pt' viewBox='0 0 96.000000 96.000000' preserveAspectRatio='xMidYMid meet'%3E%3Cg transform='translate(0.000000,96.000000) scale(0.100000,-0.100000)'%0Afill='%23085577' stroke='none'%3E%3Cpath d='M535 863 c-22 -2 -139 -17 -260 -34 -228 -31 -267 -43 -272 -85 -2%0A-10 23 -181 55 -379 l57 -360 400 0 400 0 20 40 c16 31 20 59 19 125 -1 100%0A-24 165 -73 199 -41 29 -46 57 -22 111 30 67 29 188 -3 256 -13 28 -37 60 -53%0A72 -55 39 -169 62 -268 55z m-15 -348 c30 -16 60 -61 60 -90 0 -10 -8 -33 -17%0A-52 -16 -34 -16 -41 0 -116 9 -44 15 -82 12 -85 -6 -7 -92 -21 -131 -21 l-31%0A-1 -6 85 c-4 75 -8 89 -31 112 -20 20 -26 36 -26 70 0 38 5 50 34 79 39 39 86%0A45 136 19z'/%3E%3C/g%3E%3C/svg%3E"
|
||||
type="image/svg+xml"
|
||||
/>
|
||||
<style type="text/css">
|
||||
body,
|
||||
html {
|
||||
width: 100%%;
|
||||
height: 100%%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #125678;
|
||||
}
|
||||
body {
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
min-height: 100%%;
|
||||
min-height: 100%;
|
||||
display: table;
|
||||
font-family: "Open Sans", Arial, sans-serif;
|
||||
margin: 0;
|
||||
-ms-text-size-adjust: 100%%;
|
||||
-webkit-text-size-adjust: 100%%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
h1 {
|
||||
display: flex;
|
||||
|
@ -54,7 +54,7 @@
|
|||
}
|
||||
footer {
|
||||
position: fixed;
|
||||
width: 100%%;
|
||||
width: 100%;
|
||||
letter-spacing: 1px;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
|
@ -141,7 +141,7 @@
|
|||
position: absolute;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%%;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
margin: -4px 0 0 -4px;
|
||||
}
|
||||
|
@ -202,10 +202,10 @@
|
|||
left: 12px;
|
||||
}
|
||||
@keyframes lds-roller {
|
||||
0%% {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100%% {
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
@ -220,13 +220,13 @@
|
|||
JavaScript needs to be enabled in order to visit this website.
|
||||
</p>
|
||||
</noscript>
|
||||
<form method="POST" action="%s" id="form">
|
||||
<form method="POST" action="{{antibot_uri}}" id="form">
|
||||
<input type="hidden" name="token" id="token" />
|
||||
</form>
|
||||
<div>
|
||||
<div
|
||||
class="h-captcha"
|
||||
data-sitekey="%s"
|
||||
data-sitekey="{{hcaptcha_sitekey}}"
|
||||
data-callback="send_challenge"
|
||||
></div>
|
||||
<br />
|
||||
|
|
|
@ -4,24 +4,24 @@
|
|||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Bot Detection</title>
|
||||
<link rel="icon" href="data:image/svg+xml, %%3Csvg version='1.0' xmlns='http://www.w3.org/2000/svg' width='96.000000pt' height='96.000000pt' viewBox='0 0 96.000000 96.000000' preserveAspectRatio='xMidYMid meet'%%3E%%3Cg transform='translate(0.000000,96.000000) scale(0.100000,-0.100000)'%%0Afill='%%23085577' stroke='none'%%3E%%3Cpath d='M535 863 c-22 -2 -139 -17 -260 -34 -228 -31 -267 -43 -272 -85 -2%%0A-10 23 -181 55 -379 l57 -360 400 0 400 0 20 40 c16 31 20 59 19 125 -1 100%%0A-24 165 -73 199 -41 29 -46 57 -22 111 30 67 29 188 -3 256 -13 28 -37 60 -53%%0A72 -55 39 -169 62 -268 55z m-15 -348 c30 -16 60 -61 60 -90 0 -10 -8 -33 -17%%0A-52 -16 -34 -16 -41 0 -116 9 -44 15 -82 12 -85 -6 -7 -92 -21 -131 -21 l-31%%0A-1 -6 85 c-4 75 -8 89 -31 112 -20 20 -26 36 -26 70 0 38 5 50 34 79 39 39 86%%0A45 136 19z'/%%3E%%3C/g%%3E%%3C/svg%%3E" type="image/svg+xml"/>
|
||||
<link rel="icon" href="data:image/svg+xml, %3Csvg version='1.0' xmlns='http://www.w3.org/2000/svg' width='96.000000pt' height='96.000000pt' viewBox='0 0 96.000000 96.000000' preserveAspectRatio='xMidYMid meet'%3E%3Cg transform='translate(0.000000,96.000000) scale(0.100000,-0.100000)'%0Afill='%23085577' stroke='none'%3E%3Cpath d='M535 863 c-22 -2 -139 -17 -260 -34 -228 -31 -267 -43 -272 -85 -2%0A-10 23 -181 55 -379 l57 -360 400 0 400 0 20 40 c16 31 20 59 19 125 -1 100%0A-24 165 -73 199 -41 29 -46 57 -22 111 30 67 29 188 -3 256 -13 28 -37 60 -53%0A72 -55 39 -169 62 -268 55z m-15 -348 c30 -16 60 -61 60 -90 0 -10 -8 -33 -17%0A-52 -16 -34 -16 -41 0 -116 9 -44 15 -82 12 -85 -6 -7 -92 -21 -131 -21 l-31%0A-1 -6 85 c-4 75 -8 89 -31 112 -20 20 -26 36 -26 70 0 38 5 50 34 79 39 39 86%0A45 136 19z'/%3E%3C/g%3E%3C/svg%3E" type="image/svg+xml"/>
|
||||
<style type="text/css">
|
||||
body,
|
||||
html {
|
||||
width: 100%%;
|
||||
height: 100%%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #125678;
|
||||
}
|
||||
body {
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
min-height: 100%%;
|
||||
min-height: 100%;
|
||||
display: table;
|
||||
font-family: "Open Sans", Arial, sans-serif;
|
||||
margin: 0;
|
||||
-ms-text-size-adjust: 100%%;
|
||||
-webkit-text-size-adjust: 100%%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
h1 {
|
||||
display: flex;
|
||||
|
@ -49,7 +49,7 @@
|
|||
}
|
||||
footer {
|
||||
position: fixed;
|
||||
width: 100%%;
|
||||
width: 100%;
|
||||
letter-spacing: 1px;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
|
@ -123,7 +123,7 @@
|
|||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
.lds-roller{display: inline-block;position: relative;width: 80px;height: 80px}.lds-roller div{animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;transform-origin: 40px 40px}.lds-roller div:after{content: " ";display: block;position: absolute;width: 7px;height: 7px;border-radius: 50%%;background: #fff;margin: -4px 0 0 -4px}.lds-roller div:nth-child(1){animation-delay: -0.036s}.lds-roller div:nth-child(1):after{top: 63px;left: 63px}.lds-roller div:nth-child(2){animation-delay: -0.072s}.lds-roller div:nth-child(2):after{top: 68px;left: 56px}.lds-roller div:nth-child(3){animation-delay: -0.108s}.lds-roller div:nth-child(3):after{top: 71px;left: 48px}.lds-roller div:nth-child(4){animation-delay: -0.144s}.lds-roller div:nth-child(4):after{top: 72px;left: 40px}.lds-roller div:nth-child(5){animation-delay: -0.18s}.lds-roller div:nth-child(5):after{top: 71px;left: 32px}.lds-roller div:nth-child(6){animation-delay: -0.216s}.lds-roller div:nth-child(6):after{top: 68px;left: 24px}.lds-roller div:nth-child(7){animation-delay: -0.252s}.lds-roller div:nth-child(7):after{top: 63px;left: 17px}.lds-roller div:nth-child(8){animation-delay: -0.288s}.lds-roller div:nth-child(8):after{top: 56px;left: 12px}@keyframes lds-roller{0%%{transform: rotate(0deg)}100%%{transform: rotate(360deg)}}#showjs{display:none}#nojs{display:table-cell}
|
||||
.lds-roller{display: inline-block;position: relative;width: 80px;height: 80px}.lds-roller div{animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;transform-origin: 40px 40px}.lds-roller div:after{content: " ";display: block;position: absolute;width: 7px;height: 7px;border-radius: 50%;background: #fff;margin: -4px 0 0 -4px}.lds-roller div:nth-child(1){animation-delay: -0.036s}.lds-roller div:nth-child(1):after{top: 63px;left: 63px}.lds-roller div:nth-child(2){animation-delay: -0.072s}.lds-roller div:nth-child(2):after{top: 68px;left: 56px}.lds-roller div:nth-child(3){animation-delay: -0.108s}.lds-roller div:nth-child(3):after{top: 71px;left: 48px}.lds-roller div:nth-child(4){animation-delay: -0.144s}.lds-roller div:nth-child(4):after{top: 72px;left: 40px}.lds-roller div:nth-child(5){animation-delay: -0.18s}.lds-roller div:nth-child(5):after{top: 71px;left: 32px}.lds-roller div:nth-child(6){animation-delay: -0.216s}.lds-roller div:nth-child(6):after{top: 68px;left: 24px}.lds-roller div:nth-child(7){animation-delay: -0.252s}.lds-roller div:nth-child(7):after{top: 63px;left: 17px}.lds-roller div:nth-child(8){animation-delay: -0.288s}.lds-roller div:nth-child(8):after{top: 56px;left: 12px}@keyframes lds-roller{0%{transform: rotate(0deg)}100%{transform: rotate(360deg)}}#showjs{display:none}#nojs{display:table-cell}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -136,7 +136,7 @@
|
|||
<div class="lds-roller"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div>
|
||||
</p>
|
||||
</div>
|
||||
<form method="POST" action="%s" id="form">
|
||||
<form method="POST" action="{{antibot_uri}}" id="form">
|
||||
<input type="hidden" name="challenge" id="challenge">
|
||||
</form>
|
||||
<footer>
|
||||
|
@ -233,7 +233,7 @@
|
|||
var i, l = input.length * 32,
|
||||
output = '';
|
||||
for (i = 0; i < l; i += 8) {
|
||||
output += String.fromCharCode((input[i >> 5] >>> (24 - i %% 32)) & 0xFF);
|
||||
output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
@ -250,7 +250,7 @@
|
|||
output[i] = 0;
|
||||
}
|
||||
for (i = 0; i < l; i += 8) {
|
||||
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i %% 32);
|
||||
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
@ -299,7 +299,7 @@
|
|||
var W = [64];
|
||||
var a, b, c, d, e, f, g, h;
|
||||
var i, j, T1, T2;
|
||||
m[l >> 5] |= 0x80 << (24 - (l %% 32));
|
||||
m[l >> 5] |= 0x80 << (24 - (l % 32));
|
||||
m[(((l + 64) >> 9) << 4) + 15] = l;
|
||||
for (i = 0; i < m.length; i += 16) {
|
||||
a = HASH[0];
|
||||
|
@ -362,7 +362,7 @@
|
|||
return hashBuffer;
|
||||
}
|
||||
(async () => {
|
||||
const nonce = '%s';
|
||||
const nonce = '{{random}}';
|
||||
var i = 0;
|
||||
while (true) {
|
||||
var digestHex = await digestMessage(nonce + i.toString());
|
||||
|
|
|
@ -6,26 +6,26 @@
|
|||
<title>Bot Detection</title>
|
||||
<link
|
||||
rel="icon"
|
||||
href="data:image/svg+xml, %%3Csvg version='1.0' xmlns='http://www.w3.org/2000/svg' width='96.000000pt' height='96.000000pt' viewBox='0 0 96.000000 96.000000' preserveAspectRatio='xMidYMid meet'%%3E%%3Cg transform='translate(0.000000,96.000000) scale(0.100000,-0.100000)'%%0Afill='%%23085577' stroke='none'%%3E%%3Cpath d='M535 863 c-22 -2 -139 -17 -260 -34 -228 -31 -267 -43 -272 -85 -2%%0A-10 23 -181 55 -379 l57 -360 400 0 400 0 20 40 c16 31 20 59 19 125 -1 100%%0A-24 165 -73 199 -41 29 -46 57 -22 111 30 67 29 188 -3 256 -13 28 -37 60 -53%%0A72 -55 39 -169 62 -268 55z m-15 -348 c30 -16 60 -61 60 -90 0 -10 -8 -33 -17%%0A-52 -16 -34 -16 -41 0 -116 9 -44 15 -82 12 -85 -6 -7 -92 -21 -131 -21 l-31%%0A-1 -6 85 c-4 75 -8 89 -31 112 -20 20 -26 36 -26 70 0 38 5 50 34 79 39 39 86%%0A45 136 19z'/%%3E%%3C/g%%3E%%3C/svg%%3E"
|
||||
href="data:image/svg+xml, %3Csvg version='1.0' xmlns='http://www.w3.org/2000/svg' width='96.000000pt' height='96.000000pt' viewBox='0 0 96.000000 96.000000' preserveAspectRatio='xMidYMid meet'%3E%3Cg transform='translate(0.000000,96.000000) scale(0.100000,-0.100000)'%0Afill='%23085577' stroke='none'%3E%3Cpath d='M535 863 c-22 -2 -139 -17 -260 -34 -228 -31 -267 -43 -272 -85 -2%0A-10 23 -181 55 -379 l57 -360 400 0 400 0 20 40 c16 31 20 59 19 125 -1 100%0A-24 165 -73 199 -41 29 -46 57 -22 111 30 67 29 188 -3 256 -13 28 -37 60 -53%0A72 -55 39 -169 62 -268 55z m-15 -348 c30 -16 60 -61 60 -90 0 -10 -8 -33 -17%0A-52 -16 -34 -16 -41 0 -116 9 -44 15 -82 12 -85 -6 -7 -92 -21 -131 -21 l-31%0A-1 -6 85 c-4 75 -8 89 -31 112 -20 20 -26 36 -26 70 0 38 5 50 34 79 39 39 86%0A45 136 19z'/%3E%3C/g%3E%3C/svg%3E"
|
||||
type="image/svg+xml"
|
||||
/>
|
||||
<style type="text/css">
|
||||
body,
|
||||
html {
|
||||
width: 100%%;
|
||||
height: 100%%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #125678;
|
||||
}
|
||||
body {
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
min-height: 100%%;
|
||||
min-height: 100%;
|
||||
display: table;
|
||||
font-family: "Open Sans", Arial, sans-serif;
|
||||
margin: 0;
|
||||
-ms-text-size-adjust: 100%%;
|
||||
-webkit-text-size-adjust: 100%%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
h1 {
|
||||
display: flex;
|
||||
|
@ -53,7 +53,7 @@
|
|||
}
|
||||
footer {
|
||||
position: fixed;
|
||||
width: 100%%;
|
||||
width: 100%;
|
||||
letter-spacing: 1px;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
|
@ -120,7 +120,7 @@
|
|||
visibility: hidden;
|
||||
}
|
||||
</style>
|
||||
<script src="https://www.google.com/recaptcha/api.js?render=%s"></script>
|
||||
<script src="https://www.google.com/recaptcha/api.js?render={{recaptcha_sitekey}}"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="cover">
|
||||
|
@ -138,7 +138,7 @@
|
|||
<a href="https://policies.google.com/terms">Terms of Service</a> apply.
|
||||
</p>
|
||||
</div>
|
||||
<form method="POST" action="%s" id="form">
|
||||
<form method="POST" action="{{antibot_uri}}" id="form">
|
||||
<input type="hidden" name="token" id="token" />
|
||||
</form>
|
||||
<footer>
|
||||
|
@ -156,7 +156,7 @@
|
|||
function check_robot() {
|
||||
grecaptcha.ready(function () {
|
||||
grecaptcha
|
||||
.execute("%s", { action: "recaptcha" })
|
||||
.execute("{{recaptcha_sitekey}}", { action: "recaptcha" })
|
||||
.then(function (token) {
|
||||
document.getElementById("token").value = token;
|
||||
document.getElementById("form").submit();
|
||||
|
|
|
@ -6,26 +6,26 @@
|
|||
<title>%s</title>
|
||||
<link
|
||||
rel="icon"
|
||||
href="data:image/svg+xml, %%3Csvg version='1.0' xmlns='http://www.w3.org/2000/svg' width='96.000000pt' height='96.000000pt' viewBox='0 0 96.000000 96.000000' preserveAspectRatio='xMidYMid meet'%%3E%%3Cg transform='translate(0.000000,96.000000) scale(0.100000,-0.100000)'%%0Afill='%%23085577' stroke='none'%%3E%%3Cpath d='M535 863 c-22 -2 -139 -17 -260 -34 -228 -31 -267 -43 -272 -85 -2%%0A-10 23 -181 55 -379 l57 -360 400 0 400 0 20 40 c16 31 20 59 19 125 -1 100%%0A-24 165 -73 199 -41 29 -46 57 -22 111 30 67 29 188 -3 256 -13 28 -37 60 -53%%0A72 -55 39 -169 62 -268 55z m-15 -348 c30 -16 60 -61 60 -90 0 -10 -8 -33 -17%%0A-52 -16 -34 -16 -41 0 -116 9 -44 15 -82 12 -85 -6 -7 -92 -21 -131 -21 l-31%%0A-1 -6 85 c-4 75 -8 89 -31 112 -20 20 -26 36 -26 70 0 38 5 50 34 79 39 39 86%%0A45 136 19z'/%%3E%%3C/g%%3E%%3C/svg%%3E"
|
||||
href="data:image/svg+xml, %3Csvg version='1.0' xmlns='http://www.w3.org/2000/svg' width='96.000000pt' height='96.000000pt' viewBox='0 0 96.000000 96.000000' preserveAspectRatio='xMidYMid meet'%3E%3Cg transform='translate(0.000000,96.000000) scale(0.100000,-0.100000)'%0Afill='%23085577' stroke='none'%3E%3Cpath d='M535 863 c-22 -2 -139 -17 -260 -34 -228 -31 -267 -43 -272 -85 -2%0A-10 23 -181 55 -379 l57 -360 400 0 400 0 20 40 c16 31 20 59 19 125 -1 100%0A-24 165 -73 199 -41 29 -46 57 -22 111 30 67 29 188 -3 256 -13 28 -37 60 -53%0A72 -55 39 -169 62 -268 55z m-15 -348 c30 -16 60 -61 60 -90 0 -10 -8 -33 -17%0A-52 -16 -34 -16 -41 0 -116 9 -44 15 -82 12 -85 -6 -7 -92 -21 -131 -21 l-31%0A-1 -6 85 c-4 75 -8 89 -31 112 -20 20 -26 36 -26 70 0 38 5 50 34 79 39 39 86%0A45 136 19z'/%3E%3C/g%3E%3C/svg%3E"
|
||||
type="image/svg+xml"
|
||||
/>
|
||||
<style type="text/css">
|
||||
body,
|
||||
html {
|
||||
width: 100%%;
|
||||
height: 100%%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #125678;
|
||||
}
|
||||
body {
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
min-height: 100%%;
|
||||
min-height: 100%;
|
||||
display: table;
|
||||
font-family: "Open Sans", Arial, sans-serif;
|
||||
margin: 0;
|
||||
-ms-text-size-adjust: 100%%;
|
||||
-webkit-text-size-adjust: 100%%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
h1 {
|
||||
display: flex;
|
||||
|
@ -63,7 +63,7 @@
|
|||
}
|
||||
footer {
|
||||
position: fixed;
|
||||
width: 100%%;
|
||||
width: 100%;
|
||||
letter-spacing: 1px;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
|
|
|
@ -31,12 +31,12 @@ function badbehavior:log()
|
|||
return self:ret(true, "not increasing counter")
|
||||
end
|
||||
-- Check if we are already banned
|
||||
local banned, err = datastore:get("bans_ip_" .. ngx.var.remote_addr)
|
||||
local banned, err = self.datastore:get("bans_ip_" .. ngx.var.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.use_redis, ngx.var.remote_addr, tonumber(self.variables["BAD_BEHAVIOR_COUNT_TIME"]), tonumber(self.variables["BAD_BEHAVIOR_BAN_TIME"]), tonumber(self.variables["BAD_BEHAVIOR_THRESHOLD"]))
|
||||
local ok, err = ngx.timer.at(0, badbehavior.increase, self, ngx.var.remote_addr)
|
||||
if not ok then
|
||||
return self:ret(false, "can't create increase timer : " .. err)
|
||||
end
|
||||
|
@ -47,23 +47,27 @@ function badbehavior:log_default()
|
|||
return self:log()
|
||||
end
|
||||
|
||||
function badbehavior.increase(premature, use_redis, ip, count_time, ban_time, threshold)
|
||||
function badbehavior.increase(premature, obj, ip)
|
||||
-- Our vars
|
||||
local count_time = tonumber(obj.variables["BAD_BEHAVIOR_COUNT_TIME"])
|
||||
local ban_time = tonumber(obj.variables["BAD_BEHAVIOR_BAN_TIME"])
|
||||
local threshold = tonumber(obj.variables["BAD_BEHAVIOR_THRESHOLD"])
|
||||
-- Declare counter
|
||||
local counter = false
|
||||
-- Redis case
|
||||
if use_redis then
|
||||
local redis_counter, err = badbehavior.redis_increase(ip, count_time, ban_time, threshold)
|
||||
if obj.use_redis then
|
||||
local redis_counter, err = obj:redis_increase(ip)
|
||||
if not redis_counter then
|
||||
badbehavior.logger:log(ngx.ERR, "(increase) redis_increase failed, falling back to local : " .. err)
|
||||
obj.logger:log(ngx.ERR, "(increase) redis_increase failed, falling back to local : " .. err)
|
||||
else
|
||||
counter = redis_counter
|
||||
end
|
||||
end
|
||||
-- Local case
|
||||
if not counter then
|
||||
local local_counter, err = datastore:get("plugin_badbehavior_count_" .. ip)
|
||||
local local_counter, err = obj.datastore:get("plugin_badbehavior_count_" .. ip)
|
||||
if not local_counter and err ~= "not found" then
|
||||
badbehavior.logger:log(ngx.ERR, "(increase) can't get counts from the datastore : " .. err)
|
||||
obj.logger:log(ngx.ERR, "(increase) can't get counts from the datastore : " .. err)
|
||||
end
|
||||
if local_counter == nil then
|
||||
local_counter = 0
|
||||
|
@ -71,28 +75,71 @@ function badbehavior.increase(premature, use_redis, ip, count_time, ban_time, th
|
|||
counter = local_counter + 1
|
||||
end
|
||||
-- Call decrease later
|
||||
local ok, err = ngx.timer.at(count_time, badbehavior.decrease, use_redis, ip)
|
||||
local ok, err = ngx.timer.at(count_time, badbehavior.decrease, obj, ip)
|
||||
if not ok then
|
||||
badbehavior.logger:log(ngx.ERR, "(increase) can't create decrease timer : " .. err)
|
||||
obj.logger:log(ngx.ERR, "(increase) can't create decrease timer : " .. err)
|
||||
end
|
||||
-- Store local counter
|
||||
local ok, err = datastore:set("plugin_badbehavior_count_" .. ip, counter)
|
||||
local ok, err = obj.datastore:set("plugin_badbehavior_count_" .. ip, counter)
|
||||
if not ok then
|
||||
badbehavior.logger:log(ngx.ERR, "(increase) can't save counts to the datastore : " .. err)
|
||||
obj.logger:log(ngx.ERR, "(increase) can't save counts to the datastore : " .. err)
|
||||
return
|
||||
end
|
||||
-- Store local ban
|
||||
if counter > threshold then
|
||||
local ok, err = datastore:set("bans_ip_" .. ip, "bad behavior", ban_time)
|
||||
local ok, err = obj.datastore:set("bans_ip_" .. ip, "bad behavior", ban_time)
|
||||
if not ok then
|
||||
badbehavior.logger:log(ngx.ERR, "(increase) can't save ban to the datastore : " .. err)
|
||||
obj.logger:log(ngx.ERR, "(increase) can't save ban to the datastore : " .. err)
|
||||
return
|
||||
end
|
||||
badbehavior.logger:log(ngx.WARN, "IP " .. ip .. " is banned for " .. ban_time .. "s (" .. tostring(counter) .. "/" .. tostring(threshold) .. ")")
|
||||
obj.logger:log(ngx.WARN, "IP " .. ip .. " is banned for " .. ban_time .. "s (" .. tostring(counter) .. "/" .. tostring(threshold) .. ")")
|
||||
end
|
||||
end
|
||||
|
||||
function badbehavior.redis_increase(ip, count_time, ban_time, threshold)
|
||||
function badbehavior.decrease(premature, obj, ip)
|
||||
-- Our vars
|
||||
local count_time = tonumber(obj.variables["BAD_BEHAVIOR_COUNT_TIME"])
|
||||
local ban_time = tonumber(obj.variables["BAD_BEHAVIOR_BAN_TIME"])
|
||||
local threshold = tonumber(obj.variables["BAD_BEHAVIOR_THRESHOLD"])
|
||||
-- Declare counter
|
||||
local counter = false
|
||||
-- Redis case
|
||||
if obj.use_redis then
|
||||
local redis_counter, err = obj:redis_decrease(ip)
|
||||
if not redis_counter then
|
||||
obj.logger:log(ngx.ERR, "(increase) redis_increase failed, falling back to local : " .. err)
|
||||
else
|
||||
counter = redis_counter
|
||||
end
|
||||
end
|
||||
-- Local case
|
||||
if not counter then
|
||||
local local_counter, err = obj.datastore:get("plugin_badbehavior_count_" .. ip)
|
||||
if not local_counter and err ~= "not found" then
|
||||
obj.logger:log(ngx.ERR, "(increase) can't get counts from the datastore : " .. err)
|
||||
end
|
||||
if local_counter == nil or local_counter <= 1 then
|
||||
counter = 0
|
||||
else
|
||||
counter = local_counter - 1
|
||||
end
|
||||
end
|
||||
-- Store local counter
|
||||
if counter <= 0 then
|
||||
local ok, err = obj.datastore:delete("plugin_badbehavior_count_" .. ip)
|
||||
else
|
||||
local ok, err = obj.datastore:delete("plugin_badbehavior_count_" .. ip, counter)
|
||||
if not ok then
|
||||
obj.logger:log(ngx.ERR, "(increase) can't save counts to the datastore : " .. err)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function badbehavior:redis_increase(ip)
|
||||
-- Our vars
|
||||
local count_time = tonumber(self.variables["BAD_BEHAVIOR_COUNT_TIME"])
|
||||
local ban_time = tonumber(self.variables["BAD_BEHAVIOR_BAN_TIME"])
|
||||
-- Connect to server
|
||||
local cstore, err = clusterstore:new()
|
||||
if not cstore then
|
||||
|
@ -137,7 +184,7 @@ function badbehavior.redis_increase(ip, count_time, ban_time, threshold)
|
|||
return counter
|
||||
end
|
||||
|
||||
function badbehavior.redis_decrease(ip)
|
||||
function badbehavior:redis_decrease(ip)
|
||||
-- Connect to server
|
||||
local cstore, err = clusterstore:new()
|
||||
if not cstore then
|
||||
|
@ -160,12 +207,12 @@ function badbehavior.redis_decrease(ip)
|
|||
if counter == 0 then
|
||||
local ok, err = clusterstore:call("del", "bad_behavior_" .. ip)
|
||||
if err then
|
||||
clusterstore:close(redis_client)
|
||||
clusterstore:close()
|
||||
return false, err
|
||||
end
|
||||
end
|
||||
-- End connection
|
||||
clusterstore:close(redis_client)
|
||||
clusterstore:close()
|
||||
return counter
|
||||
end
|
||||
|
||||
|
|
|
@ -200,8 +200,8 @@ 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
|
||||
local is_global, err = utils.ip_is_global(ngx.var.remote_addr)
|
||||
if is_global == nil then
|
||||
return nil, err
|
||||
end
|
||||
|
@ -241,22 +241,25 @@ function blacklist:is_blacklisted_ip()
|
|||
end
|
||||
|
||||
-- Check if ASN is in ignore list
|
||||
local asn, err = utils.get_asn(ngx.var.remote_addr)
|
||||
if not asn then
|
||||
return nil, err
|
||||
end
|
||||
local ignore = false
|
||||
for i, ignore_asn in ipairs(self.lists["IGNORE_ASN"]) do
|
||||
if ignore_asn == tostring(asn) then
|
||||
ignore = true
|
||||
break
|
||||
if is_global then
|
||||
local asn, err = utils.get_asn(ngx.var.remote_addr)
|
||||
if not asn then
|
||||
self.logger:log(ngx.ERR, "7")
|
||||
return nil, err
|
||||
end
|
||||
end
|
||||
-- Check if ASN is in blacklist
|
||||
if not ignore then
|
||||
for i, bl_asn in ipairs(self.lists["ASN"]) do
|
||||
if bl_asn == tostring(asn) then
|
||||
return true, "ASN " .. bl_asn
|
||||
local ignore = false
|
||||
for i, ignore_asn in ipairs(self.lists["IGNORE_ASN"]) do
|
||||
if ignore_asn == tostring(asn) then
|
||||
ignore = true
|
||||
break
|
||||
end
|
||||
end
|
||||
-- Check if ASN is in blacklist
|
||||
if not ignore then
|
||||
for i, bl_asn in ipairs(self.lists["ASN"]) do
|
||||
if bl_asn == tostring(asn) then
|
||||
return true, "ASN " .. bl_asn
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,7 +25,7 @@ location = {{ page }} {
|
|||
internal;
|
||||
modsecurity off;
|
||||
default_type 'text/html';
|
||||
root /usr/share/bunkerweb/core/files;
|
||||
root /usr/share/bunkerweb/core/errors/files;
|
||||
content_by_lua_block {
|
||||
local logger = require "bunkerweb.logger"
|
||||
local cerrors = require "errors.errors"
|
||||
|
|
|
@ -166,8 +166,8 @@ 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
|
||||
local is_global, err = utils.ip_is_global(ngx.var.remote_addr)
|
||||
if is_global == nil then
|
||||
return nil, err
|
||||
end
|
||||
|
@ -192,9 +192,15 @@ function greylist:is_greylisted_ip()
|
|||
end
|
||||
|
||||
-- Check if ASN is in greylist
|
||||
for i, bl_asn in ipairs(self.lists["ASN"]) do
|
||||
if bl_asn == tostring(asn) then
|
||||
return true, "ASN " .. bl_asn
|
||||
if is_global then
|
||||
local asn, err = utils.get_asn(ngx.var.remote_addr)
|
||||
if not asn then
|
||||
return nil, err
|
||||
end
|
||||
for i, bl_asn in ipairs(self.lists["ASN"]) do
|
||||
if bl_asn == tostring(asn) then
|
||||
return true, "ASN " .. bl_asn
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -219,8 +219,8 @@ 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
|
||||
local is_global, err = utils.ip_is_global(ngx.var.remote_addr)
|
||||
if is_global == nil then
|
||||
return nil, err
|
||||
end
|
||||
|
@ -245,9 +245,15 @@ function whitelist:is_whitelisted_ip()
|
|||
end
|
||||
|
||||
-- Check if ASN is in whitelist
|
||||
for i, bl_asn in ipairs(self.lists["ASN"]) do
|
||||
if bl_asn == tostring(asn) then
|
||||
return true, "ASN " .. bl_asn
|
||||
if is_global then
|
||||
local asn, err = utils.get_asn(ngx.var.remote_addr)
|
||||
if not asn then
|
||||
return nil, err
|
||||
end
|
||||
for i, bl_asn in ipairs(self.lists["ASN"]) do
|
||||
if bl_asn == tostring(asn) then
|
||||
return true, "ASN " .. bl_asn
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue