diff --git a/haproxy/haproxy.cfg b/haproxy/haproxy.cfg index d156c81..23938f0 100644 --- a/haproxy/haproxy.cfg +++ b/haproxy/haproxy.cfg @@ -115,10 +115,13 @@ cache basic_cache max-age 86400 backend servers + balance leastconn # optional (recommended) ssl, requires CA cert installed on proxy and signeed cert on backends, you can also use "ssl verify none" but ssl can then be trivially mitm'd # default-server ssl verify required ca-file ca-certificates.crt sni req.hdr(Host) # use server based on hostname - use-server %[req.hdr(host),lower,map(/etc/haproxy/map/backends.map)] if TRUE + #use-server %[req.hdr(host),lower,map(/etc/haproxy/map/backends.map)] if TRUE + # use multiple servers with lua + use-server %[lua.get_server_names] 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/libs/utils.lua b/src/lua/libs/utils.lua index 00cd71a..3956d91 100644 --- a/src/lua/libs/utils.lua +++ b/src/lua/libs/utils.lua @@ -41,6 +41,14 @@ function _M.split(inputstr, sep) return t end +-- check if elem in list +function _M.contains(list, elem) + for _, v in pairs(list) do + if v == elem then return true end + end + return false +end + -- return true if hash passes difficulty function _M.checkdiff(hash, diff) if #hash == 0 then diff --git a/src/lua/scripts/register-bot-check.lua b/src/lua/scripts/register-bot-check.lua index 8d6a58c..b4bedb7 100644 --- a/src/lua/scripts/register-bot-check.lua +++ b/src/lua/scripts/register-bot-check.lua @@ -7,3 +7,16 @@ core.register_action("captcha-check", { 'http-req', }, bot_check.check_captcha_s core.register_action("pow-check", { 'http-req', }, bot_check.check_pow_status) core.register_action("decide-checks-necessary", { 'http-req', }, bot_check.decide_checks_necessary) core.register_action("kill-tor-circuit", { 'http-req', }, bot_check.kill_tor_circuit) + +local backends_map = Map.new('/etc/haproxy/map/backends.map', Map._str) +function get_server_names(txn) + local key = txn.sf:hdr("Host") + local value = backends_map:lookup(key or "") + if value ~= nil then + return value + else + return "" + end +end + +core.register_fetches("get_server_names", get_server_names) diff --git a/src/lua/scripts/register-servers.lua b/src/lua/scripts/register-servers.lua index 1cdf809..baa9637 100644 --- a/src/lua/scripts/register-servers.lua +++ b/src/lua/scripts/register-servers.lua @@ -1,6 +1,7 @@ package.path = package.path .. "./?.lua;/etc/haproxy/scripts/?.lua;/etc/haproxy/libs/?.lua" local pow_difficulty = tonumber(os.getenv("POW_DIFFICULTY") or 18) +local utils = require("utils") -- setup initial server backends based on hosts.map function setup_servers() @@ -22,13 +23,15 @@ function setup_servers() tcp:connect("127.0.0.1", 2000); --TODO: configurable port while line do local domain, backend_host = line:match("([^%s]+)%s+([^%s]+)") - -- local host_split = utils.split(backend_host, ":") - -- local backend_hostname = host_split[1] - -- local backend_port = host_split[2] + local new_map_value = server_prefix..counter + local existing_map_value = backends_map:lookup(domain) + if existing_map_value ~= nil then + current_backends = utils.split(existing_map_value, ",") + if not utils.contains(current_backends, new_map_value) then + new_map_value = new_map_value .. "," .. existing_map_value + end + end 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() local server_name = "servers/websrv"..counter --NOTE: if you have a proper CA setup, if verify_backend_ssl ~= nil then