From 9531049aa99f1cd75a48dfce6f585090396f72a0 Mon Sep 17 00:00:00 2001 From: Thomas Lynch Date: Sat, 11 Feb 2023 21:39:38 +1100 Subject: [PATCH] Update haproxy config, scripts & docker-compose to use simpler mroe organised files layout Make cookies sent from captcha/pow response be httponly --- docker-compose.yml | 10 ++-------- haproxy/haproxy.cfg | 18 +++++++++--------- src/lua/scripts/bot-check.lua | 12 ++++++------ 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 86edc5c..d0b413f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,14 +10,8 @@ services: dockerfile: haproxy/Dockerfile volumes: - ./haproxy/haproxy.cfg:/etc/haproxy/haproxy.cfg - - ./haproxy/map/ddos.map:/etc/haproxy/ddos.map - - ./haproxy/map/hosts.map:/etc/haproxy/hosts.map - - ./haproxy/map/backends.map:/etc/haproxy/backends.map - - ./haproxy/map/blocked.map:/etc/haproxy/blocked.map - - ./haproxy/map/whitelist.map:/etc/haproxy/whitelist.map - - ./haproxy/map/maintenance.map:/etc/haproxy/maintenance.map - - ./haproxy/template/maintenance.html:/etc/haproxy/maintenance.html - - ./haproxy/template/trace.txt:/etc/haproxy/trace.txt + - ./haproxy/map/:/etc/haproxy/map/ + - ./haproxy/template/:/etc/haproxy/template/ - ./src/lua/scripts/:/etc/haproxy/scripts/ - ./src/lua/libs/:/etc/haproxy/libs/ - ./src/js/:/etc/haproxy/js/ diff --git a/haproxy/haproxy.cfg b/haproxy/haproxy.cfg index d03dce1..f302c1b 100644 --- a/haproxy/haproxy.cfg +++ b/haproxy/haproxy.cfg @@ -40,14 +40,14 @@ frontend http-in #option forwardfor # drop requests with invalid host header - acl is_existing_vhost hdr(host),lower,map_str(/etc/haproxy/hosts.map) -m found + acl is_existing_vhost hdr(host),lower,map_str(/etc/haproxy/map/hosts.map) -m found http-request silent-drop unless is_existing_vhost # debug information at /.basedflare/cgi/trace - http-request return status 200 content-type "text/plain; charset=utf-8" lf-file /etc/haproxy/trace.txt if { path /.basedflare/cgi/trace } + http-request return status 200 content-type "text/plain; charset=utf-8" lf-file /etc/haproxy/template/trace.txt if { path /.basedflare/cgi/trace } # acl for blocked IPs/subnets - acl blocked_ip_or_subnet src,map_ip(/etc/haproxy/blocked.map) -m found + acl blocked_ip_or_subnet src,map_ip(/etc/haproxy/map/blocked.map) -m found http-request deny deny_status 403 if blocked_ip_or_subnet # ratelimit (and for tor, kill circuit) on POST bot-check. legitimate users shouldn't hit this. @@ -56,13 +56,13 @@ frontend http-in http-request tarpit if { sc_http_req_rate(0) gt 1 } # acl for lua check whitelisted IPs/subnets and some excluded paths - acl is_excluded src,map_ip(/etc/haproxy/whitelist.map) -m found + acl is_excluded src,map_ip(/etc/haproxy/map/whitelist.map) -m found acl is_excluded path /favicon.ico #add more # acl ORs for when ddos_mode_enabled acl ddos_mode_enabled_override hdr_cnt(xr3la1rfFc) eq 0 - acl ddos_mode_enabled hdr(host),lower,map(/etc/haproxy/ddos.map) -m bool - acl ddos_mode_enabled base,map(/etc/haproxy/ddos.map) -m bool + acl ddos_mode_enabled hdr(host),lower,map(/etc/haproxy/map/ddos.map) -m bool + acl ddos_mode_enabled base,map(/etc/haproxy/map/ddos.map) -m bool # serve challenge page scripts directly from haproxy http-request return file /etc/haproxy/js/argon2.js status 200 content-type "application/javascript; charset=utf-8" hdr "cache-control" "public, max-age=300" if { path /.basedflare/js/argon2.js } @@ -70,8 +70,8 @@ frontend http-in http-request return file /etc/haproxy/js/worker.js status 200 content-type "application/javascript; charset=utf-8" hdr "cache-control" "public, max-age=300" if { path /.basedflare/js/worker.js } # acl for domains in maintenance mode to return maintenance page (after challenge page htp-request return rules, for the footerlogo) - acl maintenance_mode hdr(host),lower,map_str(/etc/haproxy/maintenance.map) -m found - http-request return lf-file /etc/haproxy/maintenance.html status 200 content-type "text/html; charset=utf-8" hdr "cache-control" "private, max-age=30" if maintenance_mode + acl maintenance_mode hdr(host),lower,map_str(/etc/haproxy/map/maintenance.map) -m found + http-request return lf-file /etc/haproxy/template/maintenance.html status 200 content-type "text/html; charset=utf-8" hdr "cache-control" "private, max-age=30" if maintenance_mode # create acl for bools updated by lua acl captcha_passed var(txn.captcha_passed) -m bool @@ -111,7 +111,7 @@ backend servers # placeholder servers, activated by LUA or the control panel server-template websrv 1-100 0.0.0.0:80 check disabled # use server based on hostname - use-server %[req.hdr(host),lower,map(/etc/haproxy/backends.map)] if TRUE + use-server %[req.hdr(host),lower,map(/etc/haproxy/map/backends.map)] if TRUE backend bot_check_post_throttle stick-table type ipv6 size 100k expire 60s store http_req_rate(60s) diff --git a/src/lua/scripts/bot-check.lua b/src/lua/scripts/bot-check.lua index 946b55f..c8e5236 100644 --- a/src/lua/scripts/bot-check.lua +++ b/src/lua/scripts/bot-check.lua @@ -38,7 +38,7 @@ local hmac_cookie_secret = os.getenv("HMAC_COOKIE_SECRET") local ray_id = os.getenv("RAY_ID") -- load captcha map and set hcaptcha/recaptch based off env vars -local captcha_map = Map.new("/etc/haproxy/ddos.map", Map._str); +local captcha_map = Map.new("/etc/haproxy/map/ddos.map", Map._str); local captcha_provider_domain = "" local captcha_classname = "" local captcha_script_src = "" @@ -68,8 +68,8 @@ function _M.setup_servers() if backend_name == nil or server_prefix == nil then return; end - local hosts_map = Map.new("/etc/haproxy/hosts.map", Map._str); - local handle = io.open("/etc/haproxy/hosts.map", "r") + local hosts_map = Map.new("/etc/haproxy/map/hosts.map", Map._str); + local handle = io.open("/etc/haproxy/map/hosts.map", "r") local line = handle:read("*line") local counter = 1 while line do @@ -77,7 +77,7 @@ function _M.setup_servers() local port_index = backend_host:match'^.*():' local backend_hostname = backend_host:sub(0, port_index-1) local backend_port = backend_host:sub(port_index + 1) - core.set_map("/etc/haproxy/backends.map", domain, server_prefix..counter) + core.set_map("/etc/haproxy/map/backends.map", domain, server_prefix..counter) local proxy = core.proxies[backend_name].servers[server_prefix..counter] proxy:set_addr(backend_hostname, backend_port) proxy:set_ready() @@ -214,7 +214,7 @@ function _M.view(applet) applet:add_header( "set-cookie", string.format( - "_basedflare_pow=%s; Expires=Thu, 31-Dec-37 23:55:55 GMT; Path=/; Domain=.%s; SameSite=Strict;%s", + "_basedflare_pow=%s; Expires=Thu, 31-Dec-37 23:55:55 GMT; Path=/; Domain=.%s; SameSite=Strict; HttpOnly;%s", combined_cookie, applet.headers['host'][0], secure_cookie_flag @@ -268,7 +268,7 @@ function _M.view(applet) applet:add_header( "set-cookie", string.format( - "_basedflare_captcha=%s; Expires=Thu, 31-Dec-37 23:55:55 GMT; Path=/; Domain=.%s; SameSite=Strict;%s", + "_basedflare_captcha=%s; Expires=Thu, 31-Dec-37 23:55:55 GMT; Path=/; Domain=.%s; SameSite=Strict; HttpOnly;%s", combined_cookie, applet.headers['host'][0], secure_cookie_flag