antibot - custom templates
This commit is contained in:
parent
8260746fe1
commit
16e5ede130
@ -15,6 +15,7 @@ COPY entrypoint/ /opt/entrypoint
|
|||||||
COPY confs/ /opt/confs
|
COPY confs/ /opt/confs
|
||||||
COPY scripts/ /opt/scripts
|
COPY scripts/ /opt/scripts
|
||||||
COPY lua/ /usr/local/lib/lua
|
COPY lua/ /usr/local/lib/lua
|
||||||
|
COPY antibot/ /antibot
|
||||||
|
|
||||||
COPY prepare.sh /tmp/prepare.sh
|
COPY prepare.sh /tmp/prepare.sh
|
||||||
RUN chmod +x /tmp/prepare.sh && \
|
RUN chmod +x /tmp/prepare.sh && \
|
||||||
|
|||||||
@ -15,6 +15,7 @@ COPY entrypoint/ /opt/entrypoint
|
|||||||
COPY confs/ /opt/confs
|
COPY confs/ /opt/confs
|
||||||
COPY scripts/ /opt/scripts
|
COPY scripts/ /opt/scripts
|
||||||
COPY lua/ /usr/local/lib/lua
|
COPY lua/ /usr/local/lib/lua
|
||||||
|
COPY antibot/ /antibot
|
||||||
|
|
||||||
COPY prepare.sh /tmp/prepare.sh
|
COPY prepare.sh /tmp/prepare.sh
|
||||||
RUN chmod +x /tmp/prepare.sh && \
|
RUN chmod +x /tmp/prepare.sh && \
|
||||||
|
|||||||
@ -22,6 +22,7 @@ COPY entrypoint/ /opt/entrypoint
|
|||||||
COPY confs/ /opt/confs
|
COPY confs/ /opt/confs
|
||||||
COPY scripts/ /opt/scripts
|
COPY scripts/ /opt/scripts
|
||||||
COPY lua/ /usr/local/lib/lua
|
COPY lua/ /usr/local/lib/lua
|
||||||
|
COPY antibot/ /antibot
|
||||||
|
|
||||||
COPY prepare.sh /tmp/prepare.sh
|
COPY prepare.sh /tmp/prepare.sh
|
||||||
RUN chmod +x /tmp/prepare.sh && \
|
RUN chmod +x /tmp/prepare.sh && \
|
||||||
|
|||||||
@ -22,6 +22,7 @@ COPY entrypoint/ /opt/entrypoint
|
|||||||
COPY confs/ /opt/confs
|
COPY confs/ /opt/confs
|
||||||
COPY scripts/ /opt/scripts
|
COPY scripts/ /opt/scripts
|
||||||
COPY lua/ /usr/local/lib/lua
|
COPY lua/ /usr/local/lib/lua
|
||||||
|
COPY antibot/ /antibot
|
||||||
|
|
||||||
COPY prepare.sh /tmp/prepare.sh
|
COPY prepare.sh /tmp/prepare.sh
|
||||||
RUN chmod +x /tmp/prepare.sh && \
|
RUN chmod +x /tmp/prepare.sh && \
|
||||||
|
|||||||
@ -15,6 +15,7 @@ COPY entrypoint/ /opt/entrypoint
|
|||||||
COPY confs/ /opt/confs
|
COPY confs/ /opt/confs
|
||||||
COPY scripts/ /opt/scripts
|
COPY scripts/ /opt/scripts
|
||||||
COPY lua/ /usr/local/lib/lua
|
COPY lua/ /usr/local/lib/lua
|
||||||
|
COPY antibot/ /antibot
|
||||||
|
|
||||||
COPY prepare.sh /tmp/prepare.sh
|
COPY prepare.sh /tmp/prepare.sh
|
||||||
RUN chmod +x /tmp/prepare.sh && \
|
RUN chmod +x /tmp/prepare.sh && \
|
||||||
|
|||||||
5
antibot/captcha.data
Normal file
5
antibot/captcha.data
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<form method="POST" action="%s">
|
||||||
|
<img src="data:image/jpeg;base64,%s" /><br>
|
||||||
|
Captcha : <input type="text" name="captcha" /><br />
|
||||||
|
<input type="submit" value="send" />
|
||||||
|
</form>
|
||||||
24
antibot/captcha.html
Normal file
24
antibot/captcha.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Website protection</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #1d70b7;
|
||||||
|
}
|
||||||
|
.centered {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="centered" style="color: white;">
|
||||||
|
<h1>As a security measure, we ask you to complete this captcha to access our website :</h1>
|
||||||
|
%CAPTCHA%
|
||||||
|
<div>🛡️ this website is protected with <a href="https://github.com/bunkerity/bunkerized-nginx" target="_blank">bunkerized-nginx</a> 🛡️</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
21
antibot/javascript.data
Normal file
21
antibot/javascript.data
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<script>
|
||||||
|
async function digestMessage(message) {
|
||||||
|
const msgUint8 = new TextEncoder().encode(message);
|
||||||
|
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);
|
||||||
|
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
||||||
|
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
||||||
|
return hashHex;
|
||||||
|
}
|
||||||
|
(async () => {
|
||||||
|
const digestHex = await digestMessage('%s');
|
||||||
|
xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('POST', '%s');
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||||
|
xhr.onload = function() {
|
||||||
|
if (xhr.status === 200) {
|
||||||
|
window.location.replace('%s');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send(encodeURI('challenge=' + digestHex));
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
43
antibot/javascript.html
Normal file
43
antibot/javascript.html
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Website protection</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #1d70b7;
|
||||||
|
}
|
||||||
|
.centered {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.loader {
|
||||||
|
border: 16px solid #1d70b7;
|
||||||
|
border-top: 16px solid #2dab66;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
animation: spin 2s linear infinite;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="centered" style="color: white;">
|
||||||
|
<div class="loader"></div>
|
||||||
|
<noscript>
|
||||||
|
<h1 style="color: red;">In order to access this website, you need to enable JavaScript.</h1>
|
||||||
|
</noscript>
|
||||||
|
<h1>Please wait while we are doing some security checks...</h1>
|
||||||
|
🛡️ this website is protected with <a href="https://github.com/bunkerity/bunkerized-nginx" target="_blank">bunkerized-nginx</a> 🛡️
|
||||||
|
</div>
|
||||||
|
%JAVASCRIPT%
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
11
antibot/recaptcha-body.data
Normal file
11
antibot/recaptcha-body.data
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<form method="POST" action="%s" id="form">
|
||||||
|
<input type="hidden" name="token" id="token">
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
grecaptcha.ready(function() {
|
||||||
|
grecaptcha.execute('%s', {action: 'recaptcha'}).then(function(token) {
|
||||||
|
document.getElementById("token").value = token;
|
||||||
|
document.getElementById("form").submit();
|
||||||
|
});;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
1
antibot/recaptcha-head.data
Normal file
1
antibot/recaptcha-head.data
Normal file
@ -0,0 +1 @@
|
|||||||
|
<script src="https://www.google.com/recaptcha/api.js?render=%s"></script>
|
||||||
44
antibot/recaptcha.html
Normal file
44
antibot/recaptcha.html
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Website protection</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #1d70b7;
|
||||||
|
}
|
||||||
|
.centered {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.loader {
|
||||||
|
border: 16px solid #1d70b7;
|
||||||
|
border-top: 16px solid #2dab66;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
animation: spin 2s linear infinite;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
%RECAPTCHA_HEAD%
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="centered" style="color: white;">
|
||||||
|
<div class="loader"></div>
|
||||||
|
<noscript>
|
||||||
|
<h1 style="color: red;">In order to access this website, you need to enable JavaScript.</h1>
|
||||||
|
</noscript>
|
||||||
|
<h1>Please wait while we are doing some security checks...</h1>
|
||||||
|
🛡️ this website is protected with <a href="https://github.com/bunkerity/bunkerized-nginx" target="_blank">bunkerized-nginx</a> 🛡️
|
||||||
|
</div>
|
||||||
|
%RECAPTCHA_BODY%
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -37,7 +37,7 @@ if use_crowdsec then
|
|||||||
logger.log(ngx.ERR, "CROWDSEC", err)
|
logger.log(ngx.ERR, "CROWDSEC", err)
|
||||||
error()
|
error()
|
||||||
end
|
end
|
||||||
logger.log(ngx.ERR, "CROWDSEC" "*NOT AN ERROR* initialisation done")
|
logger.log(ngx.ERR, "CROWDSEC", "*NOT AN ERROR* initialisation done")
|
||||||
end
|
end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,19 +10,21 @@ function M.get_challenge ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function M.get_code (img, antibot_uri)
|
function M.get_code (img, antibot_uri)
|
||||||
return string.format([[
|
-- get template
|
||||||
<html>
|
local f = io.open("/antibot/captcha.html", "r")
|
||||||
<head>
|
local template = f:read("*all")
|
||||||
</head>
|
f:close()
|
||||||
<body>
|
|
||||||
<form method="POST" action="%s">
|
-- get captcha code
|
||||||
Img = <img src="data:image/jpeg;base64,%s" /><br />
|
f = io.open("/antibot/captcha.data", "r")
|
||||||
Enter captcha : <input type="text" name="captcha" /><br />
|
local captcha_data = f:read("*all")
|
||||||
<input type="submit" value="send" />
|
f:close()
|
||||||
</form>
|
|
||||||
</body>
|
-- edit captcha code
|
||||||
</html>
|
captcha_data = string.format(captcha_data, antibot_uri, base64.encode(img))
|
||||||
]], antibot_uri, base64.encode(img))
|
|
||||||
|
-- return template + edited captcha code
|
||||||
|
return template:gsub("%%CAPTCHA%%", captcha_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.check (captcha_user, captcha_valid)
|
function M.check (captcha_user, captcha_valid)
|
||||||
|
|||||||
@ -7,42 +7,28 @@ function M.get_challenge ()
|
|||||||
local random = ""
|
local random = ""
|
||||||
local rand = 0
|
local rand = 0
|
||||||
for i = 1, 20 do
|
for i = 1, 20 do
|
||||||
rand = math.random(1, #charset)
|
rand = math.random(1, #charset)
|
||||||
random = random .. charset:sub(rand, rand)
|
random = random .. charset:sub(rand, rand)
|
||||||
end
|
end
|
||||||
return random
|
return random
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.get_code (challenge, antibot_uri, original_uri)
|
function M.get_code (challenge, antibot_uri, original_uri)
|
||||||
return string.format([[
|
-- get template
|
||||||
<html>
|
local f = io.open("/antibot/javascript.html", "r")
|
||||||
<head>
|
local template = f:read("*all")
|
||||||
</head>
|
f:close()
|
||||||
<body>
|
|
||||||
<script>
|
-- get JS code
|
||||||
async function digestMessage(message) {
|
f = io.open("/antibot/javascript.data", "r")
|
||||||
const msgUint8 = new TextEncoder().encode(message);
|
local javascript = f:read("*all")
|
||||||
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);
|
f:close()
|
||||||
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
||||||
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
-- edit JS code
|
||||||
return hashHex;
|
javascript = string.format(javascript, challenge, antibot_uri, original_uri)
|
||||||
}
|
|
||||||
(async () => {
|
-- return template + edited JS code
|
||||||
const digestHex = await digestMessage('%s');
|
return template:gsub("%%JAVASCRIPT%%", javascript)
|
||||||
xhr = new XMLHttpRequest();
|
|
||||||
xhr.open('POST', '%s');
|
|
||||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
|
||||||
xhr.onload = function() {
|
|
||||||
if (xhr.status === 200) {
|
|
||||||
window.location.replace('%s');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhr.send(encodeURI('challenge=' + digestHex));
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
]], challenge, antibot_uri, original_uri)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.check (challenge, user)
|
function M.check (challenge, user)
|
||||||
|
|||||||
@ -3,26 +3,25 @@ local http = require "resty.http"
|
|||||||
local cjson = require "cjson"
|
local cjson = require "cjson"
|
||||||
|
|
||||||
function M.get_code (antibot_uri, recaptcha_sitekey)
|
function M.get_code (antibot_uri, recaptcha_sitekey)
|
||||||
return string.format([[
|
-- get template
|
||||||
<html>
|
local f = io.open("/antibot/recaptcha.html", "r")
|
||||||
<head>
|
local template = f:read("*all")
|
||||||
<script src="https://www.google.com/recaptcha/api.js?render=%s"></script>
|
f:close()
|
||||||
</head>
|
|
||||||
<body>
|
-- get recaptcha code
|
||||||
<form method="POST" action="%s" id="form">
|
f = io.open("/antibot/recaptcha-head.data", "r")
|
||||||
<input type="hidden" name="token" id="token">
|
local recaptcha_head = f:read("*all")
|
||||||
</form>
|
f:close()
|
||||||
<script>
|
f = io.open("/antibot/recaptcha-body.data", "r")
|
||||||
grecaptcha.ready(function() {
|
local recaptcha_body = f:read("*all")
|
||||||
grecaptcha.execute('%s', {action: 'recaptcha'}).then(function(token) {
|
f:close()
|
||||||
document.getElementById("token").value = token;
|
|
||||||
document.getElementById("form").submit();
|
-- edit recaptcha code
|
||||||
});;
|
recaptcha_head = string.format(recaptcha_head, recaptcha_sitekey)
|
||||||
});
|
recaptcha_body = string.format(recaptcha_body, antibot_uri, recaptcha_sitekey)
|
||||||
</script>
|
|
||||||
</body>
|
-- return template + edited recaptcha code
|
||||||
</html>
|
return template:gsub("%%RECAPTCHA_HEAD%%", recaptcha_head):gsub("%%RECAPTCHA_BODY%%", recaptcha_body)
|
||||||
]], recaptcha_sitekey, antibot_uri, recaptcha_sitekey)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.check (token, recaptcha_secret)
|
function M.check (token, recaptcha_secret)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user