basic antibot using javascript
This commit is contained in:
parent
6e1c43c4cd
commit
446ee3761b
@ -12,7 +12,7 @@ COPY fail2ban/ /opt/fail2ban
|
|||||||
COPY logs/ /opt/logs
|
COPY logs/ /opt/logs
|
||||||
COPY lua/ /opt/lua
|
COPY lua/ /opt/lua
|
||||||
|
|
||||||
RUN apk --no-cache add php7-fpm certbot libstdc++ libmaxminddb geoip pcre yajl fail2ban clamav apache2-utils rsyslog openssl && \
|
RUN apk --no-cache add php7-fpm certbot libstdc++ libmaxminddb geoip pcre yajl fail2ban clamav apache2-utils rsyslog openssl lua && \
|
||||||
chmod +x /opt/entrypoint.sh /opt/scripts/* && \
|
chmod +x /opt/entrypoint.sh /opt/scripts/* && \
|
||||||
mkdir /opt/entrypoint.d && \
|
mkdir /opt/entrypoint.d && \
|
||||||
adduser -h /dev/null -g '' -s /sbin/nologin -D -H nginx
|
adduser -h /dev/null -g '' -s /sbin/nologin -D -H nginx
|
||||||
|
|||||||
@ -12,7 +12,7 @@ COPY fail2ban/ /opt/fail2ban
|
|||||||
COPY logs/ /opt/logs
|
COPY logs/ /opt/logs
|
||||||
COPY lua/ /opt/lua
|
COPY lua/ /opt/lua
|
||||||
|
|
||||||
RUN apk --no-cache add php7-fpm certbot libstdc++ libmaxminddb geoip pcre yajl fail2ban clamav apache2-utils rsyslog openssl && \
|
RUN apk --no-cache add php7-fpm certbot libstdc++ libmaxminddb geoip pcre yajl fail2ban clamav apache2-utils rsyslog openssl lua && \
|
||||||
chmod +x /opt/entrypoint.sh /opt/scripts/* && \
|
chmod +x /opt/entrypoint.sh /opt/scripts/* && \
|
||||||
mkdir /opt/entrypoint.d && \
|
mkdir /opt/entrypoint.d && \
|
||||||
adduser -h /dev/null -g '' -s /sbin/nologin -D -H nginx
|
adduser -h /dev/null -g '' -s /sbin/nologin -D -H nginx
|
||||||
|
|||||||
@ -19,7 +19,7 @@ COPY fail2ban/ /opt/fail2ban
|
|||||||
COPY logs/ /opt/logs
|
COPY logs/ /opt/logs
|
||||||
COPY lua/ /opt/lua
|
COPY lua/ /opt/lua
|
||||||
|
|
||||||
RUN apk --no-cache add php7-fpm certbot libstdc++ libmaxminddb geoip pcre yajl fail2ban clamav apache2-utils rsyslog openssl && \
|
RUN apk --no-cache add php7-fpm certbot libstdc++ libmaxminddb geoip pcre yajl fail2ban clamav apache2-utils rsyslog openssl lua && \
|
||||||
chmod +x /opt/entrypoint.sh /opt/scripts/* && \
|
chmod +x /opt/entrypoint.sh /opt/scripts/* && \
|
||||||
mkdir /opt/entrypoint.d && \
|
mkdir /opt/entrypoint.d && \
|
||||||
adduser -h /dev/null -g '' -s /sbin/nologin -D -H nginx
|
adduser -h /dev/null -g '' -s /sbin/nologin -D -H nginx
|
||||||
|
|||||||
@ -19,7 +19,7 @@ COPY fail2ban/ /opt/fail2ban
|
|||||||
COPY logs/ /opt/logs
|
COPY logs/ /opt/logs
|
||||||
COPY lua/ /opt/lua
|
COPY lua/ /opt/lua
|
||||||
|
|
||||||
RUN apk --no-cache add php7-fpm certbot libstdc++ libmaxminddb geoip pcre yajl fail2ban clamav apache2-utils rsyslog openssl && \
|
RUN apk --no-cache add php7-fpm certbot libstdc++ libmaxminddb geoip pcre yajl fail2ban clamav apache2-utils rsyslog openssl lua && \
|
||||||
chmod +x /opt/entrypoint.sh /opt/scripts/* && \
|
chmod +x /opt/entrypoint.sh /opt/scripts/* && \
|
||||||
mkdir /opt/entrypoint.d && \
|
mkdir /opt/entrypoint.d && \
|
||||||
adduser -h /dev/null -g '' -s /sbin/nologin -D -H nginx
|
adduser -h /dev/null -g '' -s /sbin/nologin -D -H nginx
|
||||||
|
|||||||
@ -12,7 +12,7 @@ COPY fail2ban/ /opt/fail2ban
|
|||||||
COPY logs/ /opt/logs
|
COPY logs/ /opt/logs
|
||||||
COPY lua/ /opt/lua
|
COPY lua/ /opt/lua
|
||||||
|
|
||||||
RUN apk --no-cache add php7-fpm certbot libstdc++ libmaxminddb geoip pcre yajl fail2ban clamav apache2-utils rsyslog openssl && \
|
RUN apk --no-cache add php7-fpm certbot libstdc++ libmaxminddb geoip pcre yajl fail2ban clamav apache2-utils rsyslog openssl lua && \
|
||||||
chmod +x /opt/entrypoint.sh /opt/scripts/* && \
|
chmod +x /opt/entrypoint.sh /opt/scripts/* && \
|
||||||
mkdir /opt/entrypoint.d && \
|
mkdir /opt/entrypoint.d && \
|
||||||
adduser -h /dev/null -g '' -s /sbin/nologin -D -H nginx
|
adduser -h /dev/null -g '' -s /sbin/nologin -D -H nginx
|
||||||
|
|||||||
39
confs/antibot-javascript.conf
Normal file
39
confs/antibot-javascript.conf
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
location = %ANTIBOT_URI% {
|
||||||
|
|
||||||
|
default_type 'text/html';
|
||||||
|
|
||||||
|
if ($request_method = GET) {
|
||||||
|
content_by_lua_block {
|
||||||
|
local cookie = require "cookie"
|
||||||
|
local javascript = require "javascript"
|
||||||
|
if not cookie.is_set("challenge") then
|
||||||
|
return ngx.exit(ngx.HTTP_FORBIDDEN)
|
||||||
|
end
|
||||||
|
local challenge = cookie.get("challenge")
|
||||||
|
local code = javascript.get_code(challenge, "%ANTIBOT_URI%", cookie.get("uri"))
|
||||||
|
ngx.say(code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request_method = POST) {
|
||||||
|
content_by_lua_block {
|
||||||
|
local cookie = require "cookie"
|
||||||
|
local javascript = require "javascript"
|
||||||
|
if not cookie.is_set("challenge") then
|
||||||
|
return ngx.exit(ngx.HTTP_FORBIDDEN)
|
||||||
|
end
|
||||||
|
ngx.req.read_body()
|
||||||
|
local args, err = ngx.req.get_post_args(1)
|
||||||
|
if err == "truncated" or not args or not args["challenge"] then
|
||||||
|
return ngx.exit(ngx.HTTP_FORBIDDEN)
|
||||||
|
end
|
||||||
|
local challenge = args["challenge"]
|
||||||
|
local check = javascript.check(cookie.get("challenge"), challenge)
|
||||||
|
if not check then
|
||||||
|
return ngx.exit(ngx.HTTP_FORBIDDEN)
|
||||||
|
end
|
||||||
|
cookie.set("javascript", "ok")
|
||||||
|
cookie.save()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,17 +1,19 @@
|
|||||||
access_by_lua_block {
|
access_by_lua_block {
|
||||||
|
|
||||||
local use_whitelist_ip = %USE_WHITELIST_IP%
|
local use_whitelist_ip = %USE_WHITELIST_IP%
|
||||||
local use_whitelist_reverse = %USE_WHITELIST_REVERSE%
|
local use_whitelist_reverse = %USE_WHITELIST_REVERSE%
|
||||||
local use_blacklist_ip = %USE_BLACKLIST_IP%
|
local use_blacklist_ip = %USE_BLACKLIST_IP%
|
||||||
local use_blacklist_reverse = %USE_BLACKLIST_REVERSE%
|
local use_blacklist_reverse = %USE_BLACKLIST_REVERSE%
|
||||||
local use_dnsbl = %USE_DNSBL%
|
local use_dnsbl = %USE_DNSBL%
|
||||||
local use_antibot_cookie = %USE_ANTIBOT_COOKIE%
|
local use_antibot_cookie = %USE_ANTIBOT_COOKIE%
|
||||||
|
local use_antibot_javascript = %USE_ANTIBOT_JAVASCRIPT%
|
||||||
|
|
||||||
-- include LUA code
|
-- include LUA code
|
||||||
local whitelist = require "whitelist"
|
local whitelist = require "whitelist"
|
||||||
local blacklist = require "blacklist"
|
local blacklist = require "blacklist"
|
||||||
local dnsbl = require "dnsbl"
|
local dnsbl = require "dnsbl"
|
||||||
local cookie = require "cookie"
|
local cookie = require "cookie"
|
||||||
|
local javascript = require "javascript"
|
||||||
|
|
||||||
-- antibot
|
-- antibot
|
||||||
local antibot_uri = "%ANTIBOT_URI%"
|
local antibot_uri = "%ANTIBOT_URI%"
|
||||||
@ -74,15 +76,28 @@ end
|
|||||||
|
|
||||||
-- cookie check
|
-- cookie check
|
||||||
if use_antibot_cookie then
|
if use_antibot_cookie then
|
||||||
if not cookie.is_set() then
|
if not cookie.is_set("uri") then
|
||||||
if ngx.var.uri ~= antibot_uri then
|
if ngx.var.request_uri ~= antibot_uri then
|
||||||
cookie.set()
|
cookie.set("uri", ngx.var.request_uri)
|
||||||
|
cookie.save()
|
||||||
return ngx.redirect(antibot_uri)
|
return ngx.redirect(antibot_uri)
|
||||||
end
|
end
|
||||||
return ngx.exit(ngx.HTTP_FORBIDDEN)
|
return ngx.exit(ngx.HTTP_FORBIDDEN)
|
||||||
else
|
else
|
||||||
if ngx.var.uri == antibot_uri then
|
if ngx.var.request_uri == antibot_uri then
|
||||||
return ngx.redirect(cookie.get_uri())
|
return ngx.redirect(cookie.get("uri"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- javascript check
|
||||||
|
if use_antibot_javascript then
|
||||||
|
if not cookie.is_set("javascript") then
|
||||||
|
if ngx.var.request_uri ~= antibot_uri then
|
||||||
|
cookie.set("uri", ngx.var.request_uri)
|
||||||
|
cookie.set("challenge", javascript.get_challenge())
|
||||||
|
cookie.save()
|
||||||
|
return ngx.redirect(antibot_uri)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -90,3 +105,5 @@ end
|
|||||||
ngx.exit(ngx.OK)
|
ngx.exit(ngx.OK)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%INCLUDE_ANTIBOT_JAVASCRIPT%
|
||||||
|
|||||||
@ -154,7 +154,7 @@ SELF_SIGNED_SSL_ORG="${SELF_SIGNED_SSL_ORG-AcmeInc}"
|
|||||||
SELF_SIGNED_SSL_OU="${SELF_SIGNED_SSL_OU-IT}"
|
SELF_SIGNED_SSL_OU="${SELF_SIGNED_SSL_OU-IT}"
|
||||||
SELF_SIGNED_SSL_CN="${SELF_SIGNED_SSL_CN-bunkerity-nginx}"
|
SELF_SIGNED_SSL_CN="${SELF_SIGNED_SSL_CN-bunkerity-nginx}"
|
||||||
ANTIBOT_URI="${ANTIBOT_URI-/challenge}"
|
ANTIBOT_URI="${ANTIBOT_URI-/challenge}"
|
||||||
USE_ANTIBOT_COOKIE="${USE_ANTIBOT_COOKIE-yes}"
|
USE_ANTIBOT="${USE_ANTIBOT-cookie}"
|
||||||
|
|
||||||
# install additional modules if needed
|
# install additional modules if needed
|
||||||
if [ "$ADDITIONAL_MODULES" != "" ] ; then
|
if [ "$ADDITIONAL_MODULES" != "" ] ; then
|
||||||
@ -499,10 +499,20 @@ replace_in_file "/usr/local/lib/lua/dnsbl.lua" "%DNSBL_LIST%" "$list"
|
|||||||
replace_in_file "/etc/nginx/main-lua.conf" "%ANTIBOT_URI%" "$ANTIBOT_URI"
|
replace_in_file "/etc/nginx/main-lua.conf" "%ANTIBOT_URI%" "$ANTIBOT_URI"
|
||||||
|
|
||||||
# antibot via cookie
|
# antibot via cookie
|
||||||
if [ "$USE_ANTIBOT_COOKIE" = "yes" ] ; then
|
if [ "$USE_ANTIBOT" = "cookie" ] ; then
|
||||||
replace_in_file "/etc/nginx/main-lua.conf" "%USE_ANTIBOT_COOKIE%" "true"
|
replace_in_file "/etc/nginx/main-lua.conf" "%USE_ANTIBOT_COOKIE%" "true"
|
||||||
|
replace_in_file "/etc/nginx/main-lua.conf" "%USE_ANTIBOT_JAVASCRIPT%" "false"
|
||||||
|
replace_in_file "/etc/nginx/main-lua.conf" "%INCLUDE_ANTIBOT_JAVASCRIPT%" ""
|
||||||
|
# antibot via javascript
|
||||||
|
elif [ "$USE_ANTIBOT" = "javascript" ] ; then
|
||||||
|
replace_in_file "/etc/nginx/main-lua.conf" "%USE_ANTIBOT_COOKIE%" "false"
|
||||||
|
replace_in_file "/etc/nginx/main-lua.conf" "%USE_ANTIBOT_JAVASCRIPT%" "true"
|
||||||
|
replace_in_file "/etc/nginx/main-lua.conf" "%INCLUDE_ANTIBOT_JAVASCRIPT%" "include /etc/nginx/antibot-javascript.conf;"
|
||||||
|
replace_in_file "/etc/nginx/antibot-javascript.conf" "%ANTIBOT_URI%" "$ANTIBOT_URI"
|
||||||
else
|
else
|
||||||
replace_in_file "/etc/nginx/main-lua.conf" "%USE_ANTIBOT_COOKIE%" "false"
|
replace_in_file "/etc/nginx/main-lua.conf" "%USE_ANTIBOT_COOKIE%" "false"
|
||||||
|
replace_in_file "/etc/nginx/main-lua.conf" "%USE_ANTIBOT_JAVASCRIPT%" "false"
|
||||||
|
replace_in_file "/etc/nginx/main-lua.conf" "%INCLUDE_ANTIBOT_JAVASCRIPT%" ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$USE_LIMIT_REQ" = "yes" ] ; then
|
if [ "$USE_LIMIT_REQ" = "yes" ] ; then
|
||||||
|
|||||||
@ -1,22 +1,29 @@
|
|||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
local session = require "resty.session"
|
local session = require "resty.session"
|
||||||
|
|
||||||
function M.is_set ()
|
local s = session.open()
|
||||||
local s = session.open()
|
if not s then
|
||||||
if s and s.data.uri then
|
s = session.start()
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.set ()
|
function M.is_set (key)
|
||||||
local s = session.start()
|
if s.data[key] then
|
||||||
s.data.uri = ngx.var.request_uri
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.set (key, value)
|
||||||
|
s.data[key] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.get (key)
|
||||||
|
return s.data[key]
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.save ()
|
||||||
s:save()
|
s:save()
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.get_uri ()
|
|
||||||
return session.open().data.uri
|
|
||||||
end
|
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
57
lua/javascript.lua
Normal file
57
lua/javascript.lua
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
local M = {}
|
||||||
|
local session = require "resty.session"
|
||||||
|
|
||||||
|
function M.get_challenge ()
|
||||||
|
local charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIKLMNOPQRSTUVWXYZ0123456789"
|
||||||
|
math.randomseed(os.clock()*os.time())
|
||||||
|
local random = ""
|
||||||
|
local rand = 0
|
||||||
|
for i = 1, 20 do
|
||||||
|
rand = math.random(1, #charset)
|
||||||
|
random = random .. charset:sub(rand, rand)
|
||||||
|
end
|
||||||
|
return random
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.get_code (challenge, antibot_uri, original_uri)
|
||||||
|
return string.format([[
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<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>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
]], challenge, antibot_uri, original_uri)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.check (challenge, user)
|
||||||
|
local resty_sha256 = require "resty.sha256"
|
||||||
|
local str = require "resty.string"
|
||||||
|
local sha256 = resty_sha256:new()
|
||||||
|
sha256:update(challenge)
|
||||||
|
local digest = sha256:final()
|
||||||
|
return str.to_hex(digest) == user
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
Loading…
x
Reference in New Issue
Block a user