diff --git a/states/haproxy/defaults.yaml b/states/haproxy/defaults.yaml index aeee366..d303e16 100644 --- a/states/haproxy/defaults.yaml +++ b/states/haproxy/defaults.yaml @@ -1,7 +1,7 @@ --- haproxy: enabled: true - packages: + pkgs: - haproxy - liblua5.3-dev - lua-filesystem @@ -56,7 +56,14 @@ haproxy: - name: scripts/collector.lua lib: false - name: scripts/weight.lua + enabled: false lib: false + args: + - 5 + - name: scripts/state.lua + lib: false + args: + - 30 namespace: paulbsd user: haproxy group: haproxy @@ -65,6 +72,7 @@ haproxy: defaults: #log: global #log: 127.0.0.1 local0 + load-server-state-from-file: global log: stdout format raw daemon info retries: 2 timeout check: 4s diff --git a/states/haproxy/install.sls b/states/haproxy/install.sls index 745405f..6cb23cd 100644 --- a/states/haproxy/install.sls +++ b/states/haproxy/install.sls @@ -2,7 +2,7 @@ {%- from "haproxy/map.jinja" import haproxy with context %} haproxy-pkg: pkg.installed: - - pkgs: {{ haproxy.packages }} + - pkgs: {{ haproxy.pkgs }} - watch_in: - service: haproxy-service diff --git a/states/haproxy/scripts/compile.lua b/states/haproxy/scripts/compile.lua index 35bb7ee..f8c697f 100644 --- a/states/haproxy/scripts/compile.lua +++ b/states/haproxy/scripts/compile.lua @@ -1,11 +1,12 @@ -lfs = require("lfs") +local lfs = require("lfs") -modpath = "/etc/haproxy/mods" +local modpath = "/etc/haproxy/mods" local compile = {} +local lua_version = "5.3" local user = "haproxy" local group = "haproxy" -local libs = {"-lcurl", "-ljansson", "-lmaxminddb"} +local libs = {"-ljansson", "-lmaxminddb"} function compile.check(module) local sourcepath = modpath.."/"..module..".c" @@ -14,7 +15,7 @@ function compile.check(module) local binexists = io.open(binpath) if not binexists or (binexists and lfs.attributes(sourcepath).change > lfs.attributes(binpath).change ) then - local cmd = "cc -I/usr/include/ -I/usr/include/lua5.3/ -fPIC -shared -o " .. binpath .. " " .. sourcepath .. " " ..table.concat(libs," ") + local cmd = "cc -I/usr/include/ -I/usr/include/lua" .. lua_version .. "/ -fPIC -shared -o " .. binpath .. " " .. sourcepath .. " " ..table.concat(libs," ") local res = io.popen(cmd) local aa = res:read("a*") io.popen("chown "..user..":"..group.." "..binpath) diff --git a/states/haproxy/scripts/state.lua b/states/haproxy/scripts/state.lua new file mode 100644 index 0000000..25819f8 --- /dev/null +++ b/states/haproxy/scripts/state.lua @@ -0,0 +1,39 @@ +--local socket = require("socket") +local sleep_secs=15 + +local args = table.pack(...) +if args[1] ~= nil then sleep_secs = args[1] end + +function create_state() + local try = 0 + local lastconns = 0 + + while true do + if lastconns == core.get_info()["CumConns"] then + try = try+1 + end + + local a = io.popen('echo "show servers state" | socat tcp-connect:127.0.0.1:9990 -') + local content = a:read("*a") + + if content ~= nil then + if #content>0 then + local f = io.open("/var/run/haproxy.state","w") + f:write(content) + io.close(f) + end + end + + lastconns = core.get_info()["CumConns"] + + if try == 10 then + local msg = "Worker with pid ".. core.get_info()["Pid"] .. " exited for create_state task" + print(msg) + core.done(msg) + end + + core.sleep(sleep_secs) + end +end + +core.register_task(create_state) diff --git a/states/haproxy/scripts/weight.lua b/states/haproxy/scripts/weight.lua index e88fc4f..834e53d 100644 --- a/states/haproxy/scripts/weight.lua +++ b/states/haproxy/scripts/weight.lua @@ -1,4 +1,9 @@ -local function getmax(t) +local sleep_secs=15 + +local args = table.pack(...) +if args[1] ~= nil then sleep_secs = args[1] end + +function getmax(t) local tmpvalue = 100000 local svname local value @@ -8,17 +13,28 @@ local function getmax(t) svname = k value = v end + tmpvalue = v end + return svname, value end -local function arrange_backends() +function arrange_backends() + local try = 0 + local lastconns = 0 + while true do + if lastconns == core.get_info()["CumConns"] then + try = try+1 + end + for _, backend in pairs(core.backends) do local results = {} for n,server in pairs(backend.servers) do - if server:get_stats()["check_status"] ~= nil then + if server:get_stats()["check_status"] ~= nil + and server:get_stats()["status"] == "UP" + and server:get_stats()["bck"] == 0 then if string.find(server:get_stats()["check_status"],"OK") ~= nil then local svname = server:get_stats()["svname"] local latency = server:get_stats()["check_duration"] @@ -38,7 +54,16 @@ local function arrange_backends() end end end - core.msleep(1000) + + lastconns = core.get_info()["CumConns"] + + if try == 10 then + local msg = "Worker with pid ".. core.get_info()["Pid"] .. " exited for arrange_backends task" + print(msg) + core.done(msg) + end + + core.sleep(sleep_secs) end end diff --git a/states/haproxy/templates/haproxy.cfg.j2 b/states/haproxy/templates/haproxy.cfg.j2 index a6eac40..e96ebe2 100644 --- a/states/haproxy/templates/haproxy.cfg.j2 +++ b/states/haproxy/templates/haproxy.cfg.j2 @@ -30,7 +30,7 @@ {%- macro tcpendpoints(servers=[], check=True) -%} {%- for server in servers %} - server {{ server.name }} {{ server.name }}:{{ server.port }}{{ " check" if check }}{{ " backup" if server.backup|default(False) }} port {{ server.port }} + server {{ server.name }} {{ server.name }}:{{ server.port }}{{ " check" if check }}{{ " backup" if server.backup|default(False) }} port {{ server.port }}{{ " on-marked-down shutdown-sessions on-marked-up shutdown-backup-sessions" if server.killsessions|default(False) }} {%- endfor %} {%- endmacro -%} @@ -50,7 +50,7 @@ backend admin from {{ haproxy.config.namespace }} mode http stats enable stats admin if TRUE - #stats refresh 10s + stats refresh 10s stats show-modules stats show-legends stats uri / @@ -64,12 +64,15 @@ backend admin from {{ haproxy.config.namespace }} # Global config global + master-worker + server-state-file /var/run/haproxy.state + mworker-max-reloads 2 maxconn 1000 lua-prepend-path {{ haproxy.config.dir }}/mods/?.so cpath lua-prepend-path {{ haproxy.config.dir }}/scripts/?.lua -{%- for file in haproxy.config.scripts %} - {%- if not file.lib %} - lua-load {{ haproxy.config.dir }}/{{ file.name }} {% if "args" in file.keys() %}{{ file.args|join(" ")}}{% endif %} +{%- for script in haproxy.config.scripts %} + {%- if not script.lib and script.enabled|default(true) %} + lua-load {{ haproxy.config.dir }}/{{ script.name }} {% if "args" in script.keys() %}{{ script.args|join(" ") }}{% endif %} {%- endif %} {%- endfor %} {%- if haproxy.config.api.enable %} @@ -179,6 +182,9 @@ frontend https from {{ haproxy.config.namespace }} http-request capture req.hdr(Content-Type) len 50 http-request capture sc_http_req_rate(0) len 4 + ## Silent drop all external requests with no host header + http-request silent-drop if !domains !internal + ## DDoS http-request deny deny_status 429 if max_req_rate !internal