From 9557c06aa156c011488cbbb585b399b5797ccce3 Mon Sep 17 00:00:00 2001 From: Thomas Lynch Date: Sun, 26 Dec 2021 23:56:15 +1100 Subject: [PATCH] update, dynamic backends based on hostname ,can be updated live control panel/management socket --- README.MD | 2 ++ docker-compose.yml | 7 +++++++ haproxy/backends.map | 0 haproxy/blocked.map | 0 haproxy/ddos.map | 1 - haproxy/haproxy.cfg | 13 +++++++++++-- haproxy/hosts.map | 1 - src/scripts/hcaptcha.lua | 21 ++++++++++++++++++++- src/scripts/register.lua | 1 + 9 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 haproxy/backends.map create mode 100644 haproxy/blocked.map diff --git a/README.MD b/README.MD index 9571f0c..ef3ee6c 100644 --- a/README.MD +++ b/README.MD @@ -31,6 +31,8 @@ Add some env vars to docker-compose file: - POW_COOKIE_SECRET - different random string, a salt for pow cookies - RAY_ID - string to identify the haproxy node by - BUCKET_DURATION - how long between bucket changes, invalidating cookies +- BACKEND_NAME - name of backend to build from hosts.map +- SERVER_PREFIX - prefix of server names i.e. n where n is the number, in server-template Run docker compose: ```bash diff --git a/docker-compose.yml b/docker-compose.yml index b96782a..8d8e5ae 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,7 @@ services: # context: ./ # dockerfile: tor/Dockerfile haproxy: + network_mode: "host" build: context: ./ dockerfile: haproxy/Dockerfile @@ -15,6 +16,8 @@ services: - ./haproxy/haproxy.cfg:/etc/haproxy/haproxy.cfg - ./haproxy/ddos.map:/etc/haproxy/ddos.map - ./haproxy/hosts.map:/etc/haproxy/hosts.map + - ./haproxy/backends.map:/etc/haproxy/backends.map + - ./haproxy/blocked.map:/etc/haproxy/blocked.map - ./src/scripts/:/etc/haproxy/scripts/ - ./src/libs/:/etc/haproxy/libs/ - ./haproxy/js/:/var/www/js/ @@ -25,7 +28,11 @@ services: - POW_COOKIE_SECRET= - RAY_ID= - BUCKET_DURATION=43200 + - BACKEND_NAME="servers" + - SERVER_PREFIX="websrv" nginx: + ports: + - 81:80 image: "nginx:latest" volumes: - ./nginx:/usr/share/nginx/html diff --git a/haproxy/backends.map b/haproxy/backends.map new file mode 100644 index 0000000..e69de29 diff --git a/haproxy/blocked.map b/haproxy/blocked.map new file mode 100644 index 0000000..e69de29 diff --git a/haproxy/ddos.map b/haproxy/ddos.map index e58f379..e69de29 100644 --- a/haproxy/ddos.map +++ b/haproxy/ddos.map @@ -1 +0,0 @@ -localhost 1 diff --git a/haproxy/haproxy.cfg b/haproxy/haproxy.cfg index 13d7c94..e36a805 100644 --- a/haproxy/haproxy.cfg +++ b/haproxy/haproxy.cfg @@ -4,7 +4,7 @@ global log stdout format raw local0 debug lua-load /etc/haproxy/scripts/register.lua stats socket /var/run/haproxy.sock mode 666 level admin - stats socket *:2000 level operator + stats socket *:2000 level admin defaults mode http @@ -13,11 +13,17 @@ defaults timeout server 50000ms frontend http-in + option httplog bind *:80 + bind *:443 acl is_existing_vhost hdr(host),lower,map_str(/etc/haproxy/hosts.map) -m found http-request silent-drop unless is_existing_vhost + # acl for blocked IPs/subnets + acl blocked_ip_or_subnet src,map_ip(/etc/haproxy/blocked.map) -m found + http-request deny deny_status 403 if blocked_ip_or_subnet + # acl ORs for when ddos_mode_enabled acl ddos_mode_enabled_override hdr_cnt(xr3la1rfFc) eq 0 # note: global only enables POW not captcha atm until acl ddos_mode_enabled hdr(host),lower,map(/etc/haproxy/ddos.map) -m bool @@ -47,7 +53,10 @@ frontend http-in default_backend servers backend servers - server server1 nginx:80 maxconn 32 + mode http + server-template websrv 1-100 0.0.0.0:80 check disabled + use-server %[req.hdr(host),lower,map(/etc/haproxy/backends.map)] if TRUE + #server default 127.0.0.1:80 backend hcaptcha mode http diff --git a/haproxy/hosts.map b/haproxy/hosts.map index 2fbb50c..e69de29 100644 --- a/haproxy/hosts.map +++ b/haproxy/hosts.map @@ -1 +0,0 @@ -localhost diff --git a/src/scripts/hcaptcha.lua b/src/scripts/hcaptcha.lua index 7cc14a9..070bff0 100644 --- a/src/scripts/hcaptcha.lua +++ b/src/scripts/hcaptcha.lua @@ -14,9 +14,28 @@ local pow_cookie_secret = os.getenv("POW_COOKIE_SECRET") local ray_id = os.getenv("RAY_ID") local captcha_provider_domain = "hcaptcha.com" - local captcha_map = Map.new("/etc/haproxy/ddos.map", Map._str); +function _M.setup_servers() + local backend_name = os.getenv("BACKEND_NAME") + local server_prefix = os.getenv("SERVER_PREFIX") + local hosts_map = Map.new("/etc/haproxy/hosts.map", Map._str); + local backends_map = Map.new("/etc/haproxy/backends.map", Map._str); + local handle = io.open("/etc/haproxy/hosts.map", "r") + local line = handle:read("*line") + local counter = 1 + while line do + local hostname, backend_address = line:match("([^%s]+)%s+([^%s]+)") + core.set_map("/etc/haproxy/backends.map", hostname, "websrv"..counter) + local proxy = core.proxies[backend_name].servers[server_prefix..counter] + proxy:set_addr(backend_address) + proxy:set_ready() + line = handle:read("*line") + counter = counter + 1 + end + handle:close() +end + -- main page template local body_template = [[ diff --git a/src/scripts/register.lua b/src/scripts/register.lua index 48802f8..ec438b1 100644 --- a/src/scripts/register.lua +++ b/src/scripts/register.lua @@ -6,3 +6,4 @@ core.register_service("hcaptcha-view", "http", hcaptcha.view) core.register_action("hcaptcha-check", { 'http-req', }, hcaptcha.check_captcha_status) core.register_action("pow-check", { 'http-req', }, hcaptcha.check_pow_status) core.register_action("decide-checks-necessary", { 'http-req', }, hcaptcha.decide_checks_necessary) +core.register_init(hcaptcha.setup_servers)