mirror of
https://gitgud.io/fatchan/haproxy-protection.git
synced 2025-05-09 02:05:37 +00:00
close #4
This commit is contained in:
18
README.MD
18
README.MD
@ -21,6 +21,7 @@ Add some env vars to docker-compose file:
|
||||
- HCAPTCHA_SECRET - your hcaptcha secret key
|
||||
- CAPTCHA_COOKIE_SECRET - random string, a salt for cookies
|
||||
- POW_COOKIE_SECRET - random string a salt for cookies
|
||||
- RAY_ID - string to identify the haproxy node by
|
||||
|
||||
|
||||
Run docker compose:
|
||||
@ -40,6 +41,7 @@ Before installing the tool, ensure that HaProxy is built with Lua support.
|
||||
- Copy [libs](src/libs) to a path where Lua looks for modules.
|
||||
- Copy [ddos-cli](src/cli/ddos-cli) to any convenient path.
|
||||
- Create `/etc/haproxy/domains_under_ddos.txt` with write permissions for HaProxy (feel free to change the map file path, update the HaProxy config correspondingly)
|
||||
- If you want to try with tor, change the haproxy mount in docker-compose to the haproxy/haproxy.tor.cfg and include your hidden_service folder (with keys, etc) in the tor folder
|
||||
|
||||
#### CLI
|
||||
The system comes with CLI. It can be used to manage global and per-domain protection.
|
||||
@ -54,14 +56,16 @@ optional arguments:
|
||||
|
||||
Commands:
|
||||
Global management:
|
||||
ddos-cli global status Show status of global server ddos mode.
|
||||
ddos-cli global enable Enable global ddos mode.
|
||||
ddos-cli global disable Disable global ddos mode.
|
||||
src/cli/ddos-cli global status Show status of global server ddos mode.
|
||||
src/cli/ddos-cli global enable Enable global ddos mode.
|
||||
src/cli/ddos-cli global disable Disable global ddos mode.
|
||||
|
||||
Domain management:
|
||||
ddos-cli domain list List all domains with ddos mode on.
|
||||
ddos-cli domain status <domain> Get ddos mode status for a domain.
|
||||
ddos-cli domain enable <domain> Enable ddos mode for a domain.
|
||||
ddos-cli domain disable <domain> Disable ddos mode for a domain.
|
||||
src/cli/ddos-cli domain list List all domains with ddos mode on.
|
||||
src/cli/ddos-cli domain nocaptcha List all domains with nocaptcha mode on.
|
||||
src/cli/ddos-cli domain status <domain> Get ddos mode status for a domain.
|
||||
src/cli/ddos-cli domain enable <domain> Enable ddos mode for a domain.
|
||||
src/cli/ddos-cli domain disable <domain> Disable ddos mode for a domain.
|
||||
src/cli/ddos-cli domain mode <domain> Toggle nocaptcha mode for a domain.
|
||||
|
||||
```
|
||||
|
@ -1,15 +1,20 @@
|
||||
version: "3.9"
|
||||
services:
|
||||
tor:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: tor/Dockerfile
|
||||
haproxy:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: haproxy/Dockerfile
|
||||
ports:
|
||||
- 80:80
|
||||
volumes:
|
||||
- ./haproxy/haproxy.cfg:/etc/haproxy/haproxy.cfg
|
||||
- ./haproxy/ddos.map:/etc/haproxy/ddos.map
|
||||
- ./haproxy/no_captcha.map:/etc/haproxy/no_captcha.map
|
||||
- ./src/scripts/:/etc/haproxy/scripts/
|
||||
- ./src/libs/:/etc/haproxy/libs/
|
||||
- ./haproxy/js/:/var/www/js/
|
||||
environment:
|
||||
- HCAPTCHA_SECRET=
|
||||
- HCAPTCHA_SITEKEY=
|
||||
|
@ -14,25 +14,29 @@ defaults
|
||||
frontend http-in
|
||||
bind *:80
|
||||
|
||||
# acl for ddos_mode_enabled = global enabled OR domain enabled
|
||||
acl ddos_mode_enabled hdr_cnt(xr3la1rfFc) eq 0
|
||||
acl ddos_mode_enabled hdr(host) -i -f /etc/haproxy/ddos.map
|
||||
#TODO: add ORs here for auto enable on traffic pattern
|
||||
# you can repeat this acl (which ORs them) to add more conditions where ddos_mode_enabled
|
||||
|
||||
# check captcha cookie, separate map allows to disable captcha (still keeping POW)
|
||||
# check captcha cookie
|
||||
acl captcha_passed var(txn.captcha_passed) -m bool
|
||||
acl captcha_passed hdr(host),map_str(/etc/haproxy/no_captcha.map) -m found
|
||||
|
||||
# check proof of work cookie
|
||||
acl pow_passed var(txn.pow_passed) -m bool
|
||||
|
||||
# exclude favicon, and serve script files directly in haproxy
|
||||
acl on_captcha_url path -m beg /bot-check
|
||||
acl is_excluded path_end -i .js .ico
|
||||
acl is_favicon path /favicon.ico
|
||||
acl is_sha1_js path /js/sha1.js
|
||||
acl is_worker_js path /js/worker.js
|
||||
http-request return file /var/www/js/sha1.js status 200 content-type "application/javascript; charset=utf-8" hdr "cache-control" "public, max-age=300" if is_sha1_js
|
||||
http-request return file /var/www/js/worker.js status 200 content-type "application/javascript; charset=utf-8" hdr "cache-control" "public, max-age=300" if is_worker_js
|
||||
|
||||
http-request use-service lua.hcaptcha-view if on_captcha_url !is_excluded
|
||||
http-request lua.hcaptcha-check if !is_excluded !on_captcha_url ddos_mode_enabled
|
||||
http-request lua.pow-check if !is_excluded !on_captcha_url ddos_mode_enabled
|
||||
http-request redirect location /bot-check?%[capture.req.uri] code 302 if !captcha_passed !on_captcha_url ddos_mode_enabled !is_excluded OR !pow_passed !on_captcha_url ddos_mode_enabled !is_excluded
|
||||
# check pow/captcha and show page if necessary
|
||||
http-request use-service lua.hcaptcha-view if on_captcha_url !is_favicon
|
||||
http-request lua.hcaptcha-check if !is_favicon !on_captcha_url ddos_mode_enabled
|
||||
http-request lua.pow-check if !is_favicon !on_captcha_url ddos_mode_enabled
|
||||
http-request redirect location /bot-check?%[capture.req.uri] code 302 if !captcha_passed !on_captcha_url ddos_mode_enabled !is_favicon OR !pow_passed !on_captcha_url ddos_mode_enabled !is_favicon
|
||||
|
||||
default_backend servers
|
||||
|
||||
|
61
haproxy/haproxy.tor.cfg
Normal file
61
haproxy/haproxy.tor.cfg
Normal file
@ -0,0 +1,61 @@
|
||||
global
|
||||
daemon
|
||||
maxconn 256
|
||||
log stdout format raw local0 notice
|
||||
lua-load /etc/haproxy/scripts/register.lua
|
||||
stats socket /var/run/haproxy.sock mode 666 level admin
|
||||
|
||||
defaults
|
||||
log global
|
||||
mode http
|
||||
timeout connect 5000ms
|
||||
timeout client 50000ms
|
||||
timeout server 50000ms
|
||||
|
||||
frontend tor-proxy
|
||||
#this can be a unix socket to tor, too but not between separate docker containers
|
||||
bind *:80 accept-proxy
|
||||
mode tcp
|
||||
default_backend strip-tor-proxy
|
||||
|
||||
backend strip-tor-proxy
|
||||
mode tcp
|
||||
server forward unix@/var/run/haproxy-haproxy.sock check send-proxy
|
||||
|
||||
frontend http-in
|
||||
bind unix@/var/run/haproxy-haproxy.sock accept-proxy
|
||||
|
||||
#forwardfor sets the circuit identifier sent by tor daemon in haproxy PROXY protocol header as the x-forwarded-for header
|
||||
option forwardfor
|
||||
|
||||
acl ddos_mode_enabled hdr_cnt(xr3la1rfFc) eq 0
|
||||
acl ddos_mode_enabled hdr(host) -i -f /etc/haproxy/ddos.map
|
||||
# you can repeat this acl (which ORs them) to add more conditions where ddos_mode_enabled
|
||||
|
||||
# check captcha cookie
|
||||
acl captcha_passed var(txn.captcha_passed) -m bool
|
||||
acl captcha_passed hdr(host),map_str(/etc/haproxy/no_captcha.map) -m found
|
||||
# check proof of work cookie
|
||||
acl pow_passed var(txn.pow_passed) -m bool
|
||||
|
||||
# exclude favicon, and serve script files directly in haproxy
|
||||
acl on_captcha_url path -m beg /bot-check
|
||||
acl is_favicon path /favicon.ico
|
||||
acl is_sha1_js path /js/sha1.js
|
||||
acl is_worker_js path /js/worker.js
|
||||
http-request return file /var/www/js/sha1.js status 200 content-type "application/javascript; charset=utf-8" hdr "cache-control" "public, max-age=300" if is_sha1_js
|
||||
http-request return file /var/www/js/worker.js status 200 content-type "application/javascript; charset=utf-8" hdr "cache-control" "public, max-age=300" if is_worker_js
|
||||
|
||||
# check pow/captcha and show page if necessary
|
||||
http-request use-service lua.hcaptcha-view if on_captcha_url !is_favicon
|
||||
http-request lua.hcaptcha-check if !is_favicon !on_captcha_url ddos_mode_enabled
|
||||
http-request lua.pow-check if !is_favicon !on_captcha_url ddos_mode_enabled
|
||||
http-request redirect location /bot-check?%[capture.req.uri] code 302 if !captcha_passed !on_captcha_url ddos_mode_enabled !is_favicon OR !pow_passed !on_captcha_url ddos_mode_enabled !is_favicon
|
||||
|
||||
default_backend servers
|
||||
|
||||
backend servers
|
||||
server server1 nginx:80
|
||||
|
||||
backend hcaptcha
|
||||
server hcaptcha hcaptcha.com:443
|
11
nginx/index.html
Normal file
11
nginx/index.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>test</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<p>hello, world</p>
|
||||
</body>
|
||||
</html>
|
11
tor/Dockerfile
Normal file
11
tor/Dockerfile
Normal file
@ -0,0 +1,11 @@
|
||||
FROM alpine:latest
|
||||
RUN apk update && apk add tor
|
||||
COPY ./tor/torrc.default /etc/tor/torrc
|
||||
ADD ./tor/hidden_service/ /var/lib/tor/hidden_service
|
||||
RUN chmod -R 700 /var/lib/tor/
|
||||
RUN chmod -R 600 /var/lib/tor/hidden_service/hs_ed25519_secret_key
|
||||
RUN chown -R tor /var/lib/tor/
|
||||
RUN chown -R tor /etc/tor
|
||||
USER tor
|
||||
ENTRYPOINT [ "tor" ]
|
||||
CMD [ "-f", "/etc/tor/torrc" ]
|
5
tor/torrc.default
Normal file
5
tor/torrc.default
Normal file
@ -0,0 +1,5 @@
|
||||
Log notice stdout
|
||||
DataDirectory /var/lib/tor
|
||||
HiddenServiceDir /var/lib/tor/hidden_service/
|
||||
HiddenServicePort 80 haproxy:80
|
||||
HiddenServiceExportCircuitID haproxy
|
Reference in New Issue
Block a user