diff --git a/docker-compose.yml b/docker-compose.yml index 2b98432..36f426f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,8 +5,7 @@ services: network_mode: host ports: - 80:80 - # - 2000:2000 #runtime api - # - 2001:2001 #dataplaneapi + - 2001:2001 #dataplaneapi build: context: ./ dockerfile: haproxy/Dockerfile diff --git a/haproxy/dataplaneapi.hcl b/haproxy/dataplaneapi.hcl index 5ab0f82..7d61788 100644 --- a/haproxy/dataplaneapi.hcl +++ b/haproxy/dataplaneapi.hcl @@ -1,23 +1,34 @@ config_version = 2 + name = "basedflare" + mode = "single" dataplaneapi { host = "127.0.0.1" port = 2001 + user "admin" { insecure = true password = "admin" } + transaction { transaction_dir = "/tmp/haproxy" } + + resources { + maps_dir = "/etc/haproxy/map" + ssl_certs_dir = "/etc/haproxy/ssl" + } + advertised {} } haproxy { config_file = "/etc/haproxy/haproxy.cfg" haproxy_bin = "/usr/local/sbin/haproxy" + reload { reload_delay = 5 reload_cmd = "service haproxy reload" diff --git a/haproxy/haproxy.cfg b/haproxy/haproxy.cfg index daeb518..205ce17 100644 --- a/haproxy/haproxy.cfg +++ b/haproxy/haproxy.cfg @@ -2,7 +2,8 @@ global daemon maxconn 256 log stdout format raw local0 debug - lua-load-per-thread /etc/haproxy/scripts/register.lua + lua-load /etc/haproxy/scripts/register-servers.lua + lua-load-per-thread /etc/haproxy/scripts/register-bot-check.lua stats socket /var/run/haproxy.sock mode 666 level admin stats socket 127.0.0.1:1999 level admin httpclient.ssl.verify none @@ -18,21 +19,21 @@ defaults timeout server 50000ms timeout tarpit 5000ms -# program api - # command dataplaneapi -f /etc/haproxy/dataplaneapi.hcl --update-map-files - # no option start-on-reload -# -# frontend stats-frontend - # bind *:2000 - # option tcplog - # mode tcp - # acl white_list src 127.0.0.1 - # tcp-request connection reject unless white_list - # default_backend stats-backend -# -# backend stats-backend - # mode tcp - # server stats-localhost 127.0.0.1:1999 +program api + command dataplaneapi -f /etc/haproxy/dataplaneapi.hcl --update-map-files + no option start-on-reload + +frontend stats-frontend + bind 127.0.0.1:2000 + option tcplog + mode tcp + acl white_list src 127.0.0.1 + tcp-request connection reject unless white_list + default_backend stats-backend + +backend stats-backend + mode tcp + server stats-localhost 127.0.0.1:1999 frontend http-in @@ -64,7 +65,7 @@ frontend http-in 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_override str("true"),map(/etc/haproxy/map/ddos_global.map) -m found 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 @@ -97,6 +98,12 @@ frontend http-in http-response set-header X-Cache-Status HIT if !{ srv_id -m found } http-response set-header X-Cache-Status MISS if { srv_id -m found } + # simple example cache for files + http-request set-var(txn.path) path + acl can_cache var(txn.path) -i -m end .png .jpg .jpeg .jpe .ico .webmanifest .xml .apng .bmp .webp .pjpeg .jfif .gif .mp4 .webm .mov .mkv .svg .m4a .aac .flac .mp3 .ogg .wav .opus .txt .pdf .sid + http-request cache-use basic_cache if can_cache + http-response cache-store basic_cache if can_cache + default_backend servers cache basic_cache @@ -105,15 +112,6 @@ cache basic_cache max-age 86400 backend servers - - # simple example cache for files - http-request set-var(txn.path) path - acl can_cache var(txn.path) -i -m end .png .jpg .jpeg .jpe .ico .webmanifest .xml .apng .bmp .webp .pjpeg .jfif .gif .mp4 .webm .mov .mkv .svg .m4a .aac .flac .mp3 .ogg .wav .opus .txt .pdf .sid - http-request cache-use basic_cache if can_cache - http-response cache-store basic_cache if can_cache - - # 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/map/backends.map)] if TRUE diff --git a/haproxy/map/backends.map b/haproxy/map/backends.map index 4479d20..ac09232 100644 --- a/haproxy/map/backends.map +++ b/haproxy/map/backends.map @@ -1 +1,2 @@ -localhost websrv1 +127.0.0.1 websrv1 +localhost websrv2 diff --git a/haproxy/map/ddos.map b/haproxy/map/ddos.map index 4baa168..e69de29 100644 --- a/haproxy/map/ddos.map +++ b/haproxy/map/ddos.map @@ -1,2 +0,0 @@ -localhost 1 -localhost/test 2 diff --git a/haproxy/map/ddos_global.map b/haproxy/map/ddos_global.map new file mode 100644 index 0000000..e69de29 diff --git a/haproxy/map/hosts.map b/haproxy/map/hosts.map index ce38125..fc61161 100644 --- a/haproxy/map/hosts.map +++ b/haproxy/map/hosts.map @@ -1 +1,2 @@ +127.0.0.1 127.0.0.1:81 localhost 127.0.0.1:81 diff --git a/haproxy/template/trace.txt b/haproxy/template/trace.txt index 48410ef..91fc547 100644 --- a/haproxy/template/trace.txt +++ b/haproxy/template/trace.txt @@ -5,6 +5,7 @@ uag=%[req.fhdr(user-agent)] http=%HV tls=%[ssl_fc] tlsv=%sslv +tlsf=%[ssl_c_sha1,hex] sni=%[ssl_fc_sni] vey_id=%[env(RAY_ID)] expiry=%[env(CHALLENGE_EXPIRY)] diff --git a/nginx/favicon.ico b/nginx/favicon.ico new file mode 100644 index 0000000..00f3a3a Binary files /dev/null and b/nginx/favicon.ico differ diff --git a/src/lua/scripts/bot-check.lua b/src/lua/scripts/bot-check.lua index bca23bd..38f26a7 100644 --- a/src/lua/scripts/bot-check.lua +++ b/src/lua/scripts/bot-check.lua @@ -56,35 +56,6 @@ else captcha_backend_name = "recaptcha" end --- setup initial server backends based on hosts.map into backends.map -function _M.setup_servers() - if pow_difficulty < 8 then - error("POW_DIFFICULTY must be > 8. Around 16-32 is better") - end - local backend_name = os.getenv("BACKEND_NAME") - local server_prefix = os.getenv("SERVER_PREFIX") - if backend_name == nil or server_prefix == nil then - return; - end - 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 - local domain, backend_host = line:match("([^%s]+)%s+([^%s]+)") - 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/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() - line = handle:read("*line") - counter = counter + 1 - end - handle:close() -end - -- kill a tor circuit function _M.kill_tor_circuit(txn) local ip = txn.sf:src() diff --git a/src/lua/scripts/register.lua b/src/lua/scripts/register-bot-check.lua similarity index 92% rename from src/lua/scripts/register.lua rename to src/lua/scripts/register-bot-check.lua index 6ba84ef..8d6a58c 100644 --- a/src/lua/scripts/register.lua +++ b/src/lua/scripts/register-bot-check.lua @@ -7,4 +7,3 @@ 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) -core.register_init(bot_check.setup_servers) diff --git a/src/lua/scripts/register-servers.lua b/src/lua/scripts/register-servers.lua new file mode 100644 index 0000000..92ec7f9 --- /dev/null +++ b/src/lua/scripts/register-servers.lua @@ -0,0 +1,41 @@ +package.path = package.path .. "./?.lua;/etc/haproxy/scripts/?.lua;/etc/haproxy/libs/?.lua" + +local pow_difficulty = tonumber(os.getenv("POW_DIFFICULTY") or 18) + +-- setup initial server backends based on hosts.map +function setup_servers() + if pow_difficulty < 8 then + error("POW_DIFFICULTY must be > 8. Around 16-32 is better") + end + local backend_name = os.getenv("BACKEND_NAME") + local server_prefix = os.getenv("SERVER_PREFIX") + if backend_name == nil or server_prefix == nil then + return; + end + local handle = io.open("/etc/haproxy/map/hosts.map", "r") + local line = handle:read("*line") + local counter = 1 + -- NOTE: using tcp socket to interact with runtime API because lua can't add servers + local tcp = core.tcp(); + tcp:settimeout(1); + 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] + 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 + tcp:send(string.format("add server %s %s check\n", server_name, backend_host)) + tcp:send(string.format("enable server %s\n", server_name)) + line = handle:read("*line") + counter = counter + 1 + end + handle:close() + tcp:close() +end + +core.register_task(setup_servers) diff --git a/src/lua/scripts/templates.lua b/src/lua/scripts/templates.lua index 03c9b4c..2280f51 100644 --- a/src/lua/scripts/templates.lua +++ b/src/lua/scripts/templates.lua @@ -13,7 +13,7 @@ _M.body = [[ .h-captcha,.g-recaptcha{min-height:85px;display:block} .red{color:red;font-weight:bold} .left{text-align:left} - .powstatus{color:green;font-weight:bold} + .powstatus{color:green;font-size:small;} a,a:visited{color:var(--text-color)} body,html{height:100%%;text-align:center;} body{display:flex;flex-direction:column;background-color:var(--bg-color);color:var(--text-color);font-family:Helvetica,Arial,sans-serif;max-width:60em;margin:0 auto;padding: 0 20px}