mirror of
https://gitgud.io/fatchan/haproxy-protection.git
synced 2025-05-09 02:05:37 +00:00
feat: added captcha serving service to haproxy
This commit is contained in:
19
README.MD
Normal file
19
README.MD
Normal file
@ -0,0 +1,19 @@
|
||||
## HaProxy DDoS protection system PoC
|
||||
|
||||
If there is an unusual HTTP requests flow to a specific domain, the system detects it and triggers DDoS protection mode.
|
||||
Each new client will be first forced to complete hCaptcha, before proceeding to the website.
|
||||
|
||||
|
||||
##### How to test
|
||||
|
||||
- export hcaptcha sitekey and secret:
|
||||
```bash
|
||||
export HCAPTCHA_SITEKEY=xxxXXxxx
|
||||
export HCAPTCHA_SECRET=xxxXXxxx
|
||||
```
|
||||
- run docker compose:
|
||||
```bash
|
||||
docker compose up
|
||||
```
|
||||
|
||||
- visit *http://127.0.0.1/captcha*
|
@ -9,6 +9,9 @@ services:
|
||||
volumes:
|
||||
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
|
||||
- ./scripts/:/usr/local/etc/haproxy/scripts/
|
||||
environment:
|
||||
- HCAPTCHA_SECRET=${HCAPTCHA_SECRET}
|
||||
- HCAPTCHA_SITEKEY=${HCAPTCHA_SITEKEY}
|
||||
|
||||
nginx:
|
||||
image: "nginx:latest"
|
||||
|
@ -95,8 +95,26 @@ STOPSIGNAL SIGUSR1
|
||||
|
||||
ADD haproxy/docker-entrypoint.sh /usr/local/bin/
|
||||
RUN ln -s usr/local/bin/docker-entrypoint.sh / # backwards compat
|
||||
RUN apt-get update && apt-get install luarocks -y
|
||||
RUN luarocks install luasocket
|
||||
|
||||
# This is terrible mess but we need it for simple testing purposes of our POC
|
||||
RUN apt-get update && apt-get install libssl-dev make nano wget gcc libreadline-dev unzip git -y
|
||||
RUN wget http://www.lua.org/ftp/lua-5.3.5.tar.gz &&\
|
||||
tar -zxf lua-5.3.5.tar.gz &&\
|
||||
cd lua-5.3.5 &&\
|
||||
make linux test &&\
|
||||
make install
|
||||
|
||||
RUN wget "https://luarocks.org/releases/luarocks-3.3.1.tar.gz" &&\
|
||||
tar zxpf luarocks-3.3.1.tar.gz &&\
|
||||
cd luarocks-3.3.1 &&\
|
||||
./configure --with-lua-include=/usr/local/include --lua-version=5.3 --lua-suffix=5.3 &&\
|
||||
make &&\
|
||||
make install
|
||||
|
||||
RUN /usr/local/bin/luarocks install luasocket &&\
|
||||
/usr/local/bin/luarocks install luasec &&\
|
||||
/usr/local/bin/luarocks install net-url
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
||||
|
||||
# no USER for backwards compatibility (to try to avoid breaking existing users)
|
||||
|
@ -15,6 +15,7 @@ frontend http-in
|
||||
default_backend servers
|
||||
# http-request lua.test-payload
|
||||
http-request use-service lua.hello-world if { path /hello_world }
|
||||
http-request use-service lua.hcaptcha-view if { path /captcha }
|
||||
|
||||
backend servers
|
||||
server server1 nginx:80 maxconn 32
|
||||
|
1559
scripts/JSON.lua
Normal file
1559
scripts/JSON.lua
Normal file
File diff suppressed because it is too large
Load Diff
51
scripts/hcaptcha.lua
Normal file
51
scripts/hcaptcha.lua
Normal file
@ -0,0 +1,51 @@
|
||||
hcaptcha = {}
|
||||
|
||||
local url = require("net.url")
|
||||
local https = require("ssl.https")
|
||||
local json = require("json")
|
||||
|
||||
function hcaptcha.view(applet)
|
||||
local hcaptcha_secret = os.getenv("HCAPTCHA_SECRET")
|
||||
local hcaptcha_sitekey = os.getenv("HCAPTCHA_SITEKEY")
|
||||
|
||||
local response
|
||||
if applet.method == "GET" then
|
||||
response =
|
||||
[[
|
||||
<form method="POST">
|
||||
<div class="h-captcha" data-sitekey="%s"></div>
|
||||
<script src="https://hcaptcha.com/1/api.js" async defer></script>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
]]
|
||||
response = string.format(response, hcaptcha_sitekey)
|
||||
elseif applet.method == "POST" then
|
||||
local parsed_body = url.parseQuery(applet.receive(applet))
|
||||
|
||||
if parsed_body["h-captcha-response"] then
|
||||
local url =
|
||||
string.format(
|
||||
"https://hcaptcha.com/siteverify?secret=%s&response=%s",
|
||||
hcaptcha_secret,
|
||||
parsed_body["h-captcha-response"]
|
||||
)
|
||||
local body, code, headers, status = https.request(url)
|
||||
local api_response = json:decode(body)
|
||||
|
||||
if api_response.success == true then
|
||||
print("HCAPTCHA SUCCESSFULLY PASSED")
|
||||
print("... success captcha flow goes here ...")
|
||||
else
|
||||
print("HCAPTCHA FAILED", body)
|
||||
end
|
||||
end
|
||||
|
||||
response = "Thank you for submitting"
|
||||
end
|
||||
|
||||
applet:set_status(200)
|
||||
applet:add_header("content-type", "text/html")
|
||||
applet:add_header("content-length", string.len(response))
|
||||
applet:start_response()
|
||||
applet:send(response)
|
||||
end
|
@ -1,5 +1,7 @@
|
||||
package.path = package.path .. "./?.lua;/usr/local/etc/haproxy/scripts/?.lua"
|
||||
|
||||
require("guard")
|
||||
require("hcaptcha")
|
||||
|
||||
core.register_service("hello-world", "http", guard.hello_world);
|
||||
core.register_service("hello-world", "http", guard.hello_world)
|
||||
core.register_service("hcaptcha-view", "http", hcaptcha.view)
|
Reference in New Issue
Block a user