mirror of
https://gitgud.io/fatchan/haproxy-protection.git
synced 2025-05-09 02:05:37 +00:00
Fully convert to data plane api
Change global ACL to a map to realtime update with data plane api Change how on setartup servers are registered in lua
This commit is contained in:
@ -5,8 +5,7 @@ services:
|
|||||||
network_mode: host
|
network_mode: host
|
||||||
ports:
|
ports:
|
||||||
- 80:80
|
- 80:80
|
||||||
# - 2000:2000 #runtime api
|
- 2001:2001 #dataplaneapi
|
||||||
# - 2001:2001 #dataplaneapi
|
|
||||||
build:
|
build:
|
||||||
context: ./
|
context: ./
|
||||||
dockerfile: haproxy/Dockerfile
|
dockerfile: haproxy/Dockerfile
|
||||||
|
@ -1,23 +1,34 @@
|
|||||||
config_version = 2
|
config_version = 2
|
||||||
|
|
||||||
name = "basedflare"
|
name = "basedflare"
|
||||||
|
|
||||||
mode = "single"
|
mode = "single"
|
||||||
|
|
||||||
dataplaneapi {
|
dataplaneapi {
|
||||||
host = "127.0.0.1"
|
host = "127.0.0.1"
|
||||||
port = 2001
|
port = 2001
|
||||||
|
|
||||||
user "admin" {
|
user "admin" {
|
||||||
insecure = true
|
insecure = true
|
||||||
password = "admin"
|
password = "admin"
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction {
|
transaction {
|
||||||
transaction_dir = "/tmp/haproxy"
|
transaction_dir = "/tmp/haproxy"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
maps_dir = "/etc/haproxy/map"
|
||||||
|
ssl_certs_dir = "/etc/haproxy/ssl"
|
||||||
|
}
|
||||||
|
|
||||||
advertised {}
|
advertised {}
|
||||||
}
|
}
|
||||||
|
|
||||||
haproxy {
|
haproxy {
|
||||||
config_file = "/etc/haproxy/haproxy.cfg"
|
config_file = "/etc/haproxy/haproxy.cfg"
|
||||||
haproxy_bin = "/usr/local/sbin/haproxy"
|
haproxy_bin = "/usr/local/sbin/haproxy"
|
||||||
|
|
||||||
reload {
|
reload {
|
||||||
reload_delay = 5
|
reload_delay = 5
|
||||||
reload_cmd = "service haproxy reload"
|
reload_cmd = "service haproxy reload"
|
||||||
|
@ -2,7 +2,8 @@ global
|
|||||||
daemon
|
daemon
|
||||||
maxconn 256
|
maxconn 256
|
||||||
log stdout format raw local0 debug
|
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 /var/run/haproxy.sock mode 666 level admin
|
||||||
stats socket 127.0.0.1:1999 level admin
|
stats socket 127.0.0.1:1999 level admin
|
||||||
httpclient.ssl.verify none
|
httpclient.ssl.verify none
|
||||||
@ -18,21 +19,21 @@ defaults
|
|||||||
timeout server 50000ms
|
timeout server 50000ms
|
||||||
timeout tarpit 5000ms
|
timeout tarpit 5000ms
|
||||||
|
|
||||||
# program api
|
program api
|
||||||
# command dataplaneapi -f /etc/haproxy/dataplaneapi.hcl --update-map-files
|
command dataplaneapi -f /etc/haproxy/dataplaneapi.hcl --update-map-files
|
||||||
# no option start-on-reload
|
no option start-on-reload
|
||||||
#
|
|
||||||
# frontend stats-frontend
|
frontend stats-frontend
|
||||||
# bind *:2000
|
bind 127.0.0.1:2000
|
||||||
# option tcplog
|
option tcplog
|
||||||
# mode tcp
|
mode tcp
|
||||||
# acl white_list src 127.0.0.1
|
acl white_list src 127.0.0.1
|
||||||
# tcp-request connection reject unless white_list
|
tcp-request connection reject unless white_list
|
||||||
# default_backend stats-backend
|
default_backend stats-backend
|
||||||
#
|
|
||||||
# backend stats-backend
|
backend stats-backend
|
||||||
# mode tcp
|
mode tcp
|
||||||
# server stats-localhost 127.0.0.1:1999
|
server stats-localhost 127.0.0.1:1999
|
||||||
|
|
||||||
frontend http-in
|
frontend http-in
|
||||||
|
|
||||||
@ -64,7 +65,7 @@ frontend http-in
|
|||||||
acl is_excluded path /favicon.ico #add more
|
acl is_excluded path /favicon.ico #add more
|
||||||
|
|
||||||
# acl ORs for when ddos_mode_enabled
|
# 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 hdr(host),lower,map(/etc/haproxy/map/ddos.map) -m bool
|
||||||
acl ddos_mode_enabled base,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 HIT if !{ srv_id -m found }
|
||||||
http-response set-header X-Cache-Status MISS 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
|
default_backend servers
|
||||||
|
|
||||||
cache basic_cache
|
cache basic_cache
|
||||||
@ -105,15 +112,6 @@ cache basic_cache
|
|||||||
max-age 86400
|
max-age 86400
|
||||||
|
|
||||||
backend servers
|
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 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
|
||||||
|
|
||||||
|
@ -1 +1,2 @@
|
|||||||
localhost websrv1
|
127.0.0.1 websrv1
|
||||||
|
localhost websrv2
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
localhost 1
|
|
||||||
localhost/test 2
|
|
||||||
|
0
haproxy/map/ddos_global.map
Normal file
0
haproxy/map/ddos_global.map
Normal file
@ -1 +1,2 @@
|
|||||||
|
127.0.0.1 127.0.0.1:81
|
||||||
localhost 127.0.0.1:81
|
localhost 127.0.0.1:81
|
||||||
|
@ -5,6 +5,7 @@ uag=%[req.fhdr(user-agent)]
|
|||||||
http=%HV
|
http=%HV
|
||||||
tls=%[ssl_fc]
|
tls=%[ssl_fc]
|
||||||
tlsv=%sslv
|
tlsv=%sslv
|
||||||
|
tlsf=%[ssl_c_sha1,hex]
|
||||||
sni=%[ssl_fc_sni]
|
sni=%[ssl_fc_sni]
|
||||||
vey_id=%[env(RAY_ID)]
|
vey_id=%[env(RAY_ID)]
|
||||||
expiry=%[env(CHALLENGE_EXPIRY)]
|
expiry=%[env(CHALLENGE_EXPIRY)]
|
||||||
|
BIN
nginx/favicon.ico
Normal file
BIN
nginx/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
@ -56,35 +56,6 @@ else
|
|||||||
captcha_backend_name = "recaptcha"
|
captcha_backend_name = "recaptcha"
|
||||||
end
|
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
|
-- kill a tor circuit
|
||||||
function _M.kill_tor_circuit(txn)
|
function _M.kill_tor_circuit(txn)
|
||||||
local ip = txn.sf:src()
|
local ip = txn.sf:src()
|
||||||
|
@ -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("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("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_action("kill-tor-circuit", { 'http-req', }, bot_check.kill_tor_circuit)
|
||||||
core.register_init(bot_check.setup_servers)
|
|
41
src/lua/scripts/register-servers.lua
Normal file
41
src/lua/scripts/register-servers.lua
Normal file
@ -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)
|
@ -13,7 +13,7 @@ _M.body = [[
|
|||||||
.h-captcha,.g-recaptcha{min-height:85px;display:block}
|
.h-captcha,.g-recaptcha{min-height:85px;display:block}
|
||||||
.red{color:red;font-weight:bold}
|
.red{color:red;font-weight:bold}
|
||||||
.left{text-align:left}
|
.left{text-align:left}
|
||||||
.powstatus{color:green;font-weight:bold}
|
.powstatus{color:green;font-size:small;}
|
||||||
a,a:visited{color:var(--text-color)}
|
a,a:visited{color:var(--text-color)}
|
||||||
body,html{height:100%%;text-align:center;}
|
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}
|
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}
|
||||||
|
Reference in New Issue
Block a user