updated haproxy state

This commit is contained in:
Paul 2023-02-04 19:51:20 +01:00
parent 993fa3f591
commit ad98d3c6d2
7 changed files with 79 additions and 38 deletions

View File

@ -11,19 +11,18 @@ haproxy:
config: config:
dir: /etc/haproxy dir: /etc/haproxy
configfile: haproxy.cfg configfile: haproxy.cfg
peers:
dirs: dirs:
- maps - maps
- scripts - scripts
- mods - mods
- errors - errors
scripts: scripts:
- name: scripts/http.lua
lib: true
- name: scripts/json.lua - name: scripts/json.lua
lib: true lib: true
- name: scripts/collector.lua - name: scripts/collector.lua
lib: false lib: false
- name: scripts/weight_by_latency.lua - name: scripts/weight.lua
lib: false lib: false
namespace: paulbsd namespace: paulbsd
user: haproxy user: haproxy
@ -75,6 +74,7 @@ haproxy:
ddos: ddos:
timeperiod: 10s timeperiod: 10s
maxrequests: 200 maxrequests: 200
size: 1m
domains: {} domains: {}
vhosts: {} vhosts: {}
services: {} services: {}

View File

@ -3,4 +3,20 @@
{%- set haproxy = salt['pillar.get']('haproxy', default=defaults.haproxy, merge=True) -%} {%- set haproxy = salt['pillar.get']('haproxy', default=defaults.haproxy, merge=True) -%}
{%- set users = salt['pillar.get']('htpasswds') -%} {%- set users = salt['pillar.get']('htpasswds') -%}
{%- set net = salt['pillar.get']('net') -%} {%- set net = salt['pillar.get']('net') -%}
{% set peers = salt['mine.get'](
tgt='G@lb:true',
fun='internal_ip_addrs',
tgt_type='compound') %}
{% set peers_ip = [] %}
{%- for k,v in peers.items() %}
{%- if k != salt['grains.get']('fqdn') %}
{%- for i in v %}
{% set _ = peers_ip.append([k,i]) %}
{%- endfor %}
{%- endif %}
{%- endfor %}
{% do haproxy.config.update({"peers": peers_ip }) %}

View File

@ -1,9 +1,6 @@
--require = GLOBAL.require
--require("http.request")
local request = require("http")
local json = require("json") local json = require("json")
core.register_action("test", { "http-req" }, function(txn) core.register_action("collector", { "http-req" }, function(txn)
local info = {} local info = {}
local headers = {} local headers = {}
@ -27,9 +24,8 @@ core.register_action("test", { "http-req" }, function(txn)
info["path"] = reqpath info["path"] = reqpath
local infojson = json.encode(info) local infojson = json.encode(info)
--local req = request.new_from_uri("https://ipbl.paulbsd.com") -- httpclient is a haproxy 2.5 class
--local headers, stream = req:go() local req = httpclient:post{url="https://ipbl.paulbsd.com", body=infojson}
--local body = assert(stream:get_body_as_string())
txn.Info(txn, infojson) txn.Info(txn, infojson)
end end

View File

@ -2,20 +2,20 @@
{%- from "haproxy/map.jinja" import haproxy,certs with context %} {%- from "haproxy/map.jinja" import haproxy,certs with context %}
{%- set fqdn = salt["grains.get"]("fqdn") %} {%- set fqdn = salt["grains.get"]("fqdn") %}
{%- set default_backend = "test" %}
{%- set ns = namespace(default_backend='notdefined') %} {%- set ns = namespace(default_backend='notdefined') %}
{%- for name, values in haproxy.config.vhosts.items() %}{% if values.default_backend|default(false) %}{% set ns.default_backend = name %}{% endif %}{% endfor %} {%- for name, values in haproxy.config.vhosts.items() %}{% if values.default_backend|default(false) %}{% set ns.default_backend = name %}{% endif %}{% endfor %}
{%- macro internal() -%} {%- macro internal() -%}
acl internal src -f {{ haproxy.config.dir }}/maps/access acl internal src -f {{ haproxy.config.dir }}/maps/access
http-response return status 403 content-type text/html string "403 forbidden" if ! internal http-response return status 403 content-type text/html string "403 forbidden" if !internal
{%- endmacro -%} {%- endmacro -%}
{%- macro head() -%} {%- macro head() -%}
http-request return status 200 if { method -i HEAD } http-request return status 200 if METH_HEAD
{%- endmacro -%} {%- endmacro -%}
{%- macro statusresponses() -%} {%- macro statusresponses() -%}
http-response return status 403 content-type text/html string "403 forbidden" if { status 403 }
http-response return status 404 content-type text/html string "404 not found" if { status 404 } http-response return status 404 content-type text/html string "404 not found" if { status 404 }
{%- endmacro -%} {%- endmacro -%}
@ -89,20 +89,33 @@ defaults {{ haproxy.config.namespace }}
{{ key }} {{ value }} {{ key }} {{ value }}
{%- endfor %} {%- endfor %}
{% if haproxy.config.peers|length > 0 -%}
peers paulbsd
bind *:4096 ssl crt {{ haproxy.config.acme_fullchains_dir }}
default-server ssl verify none
server {{ salt['grains.get']('fqdn') }}
{%- for peer in haproxy.config.peers %}
server {{ peer[0] }} {{ peer[1] }}:4096
{%- endfor %}
{%- endif %}
# Cache # Cache
cache static cache static
total-max-size 64 total-max-size 64
max-object-size {{ haproxy.config.cache.size|default(50000) }} max-object-size {{ haproxy.config.cache.size|default(5000) }}
max-age 120 max-age 120
# Per IP rates stick table # Per IP rates stick table
backend per_ip_rates from {{ haproxy.config.namespace }} backend per_ip_rates from {{ haproxy.config.namespace }}
stick-table type string size 1m expire {{ haproxy.config.ddos.timeperiod|default("10s") }} store http_req_rate({{ haproxy.config.ddos.timeperiod|default("10s")}}) stick-table type string size {{ haproxy.config.ddos.size|default("1m") }} expire {{ haproxy.config.ddos.timeperiod|default("10s") }} store http_req_rate({{ haproxy.config.ddos.timeperiod|default("10s")}}) peers paulbsd
# Default HTTP frontend # Default HTTP frontend
frontend http from {{ haproxy.config.namespace }} frontend http from {{ haproxy.config.namespace }}
bind *:{{ haproxy.config.http_port }},:::{{ haproxy.config.http_port }} v4v6 name http bind *:{{ haproxy.config.http_port }},:::{{ haproxy.config.http_port }} v4v6 name http
mode http mode http
{% for name, service in haproxy.config.spoe.items() %}
filter spoe engine {{ name }} config {{ haproxy.config.dir }}/spoe.cfg
{%- endfor %}
## ACLs ## ACLs
acl http ssl_fc,not acl http ssl_fc,not
@ -126,14 +139,17 @@ frontend https from {{ haproxy.config.namespace }}
#bind quic4@*:{{ haproxy.config.https_port }},quic6@:::{{ haproxy.config.https_port }} v4v6 ssl crt {{ haproxy.config.acme_fullchains_dir }}{% if haproxy.config.http2 %} alpn h2,http/1.1{% endif %} #bind quic4@*:{{ haproxy.config.https_port }},quic6@:::{{ haproxy.config.https_port }} v4v6 ssl crt {{ haproxy.config.acme_fullchains_dir }}{% if haproxy.config.http2 %} alpn h2,http/1.1{% endif %}
mode http mode http
option httplog option httplog
{% for name, service in haproxy.config.spoe.items() %}
filter spoe engine {{ name }} config {{ haproxy.config.dir }}/spoe.cfg
{%- endfor %}
## ACLs ## ACLs
acl internal src -f {{ haproxy.config.dir }}/maps/access acl internal src -f {{ haproxy.config.dir }}/maps/access
acl domains req.hdr(Host),map_dom({{ haproxy.config.dir }}/maps/domains) -m found req.hdr(host) -m str %H acl domains req.hdr(Host),map_dom({{ haproxy.config.dir }}/maps/domains) -m found req.hdr(host) -m str %H
acl robots_txt path /robots.txt acl robots_txt path /robots.txt
acl max_req_rate sc_http_req_rate(0) gt {{ haproxy.config.ddos.maxrequests|default(200) }}
acl self_host req.hdr(Host) {{ fqdn }} acl self_host req.hdr(Host) {{ fqdn }}
acl path_root path / acl path_root path /
acl path_admin path_beg /;
acl path_host path_dir /host acl path_host path_dir /host
acl path_date path_dir /date acl path_date path_dir /date
acl path_srchash path /srchash acl path_srchash path /srchash
@ -153,7 +169,7 @@ frontend https from {{ haproxy.config.namespace }}
http-request capture sc_http_req_rate(0) len 4 http-request capture sc_http_req_rate(0) len 4
## DDoS ## DDoS
http-request deny deny_status 429 if { sc_http_req_rate(0) gt {{ haproxy.config.ddos.maxrequests|default(200)}} } !internal http-request deny deny_status 429 if max_req_rate !internal
## Returns ## Returns
http-request return status 200 content-type text/plain string "User-agent: *\r\nDisallow: /" if robots_txt http-request return status 200 content-type text/plain string "User-agent: *\r\nDisallow: /" if robots_txt
@ -170,15 +186,17 @@ frontend https from {{ haproxy.config.namespace }}
http-response set-header X-Random "%[var(txn.random)]" http-response set-header X-Random "%[var(txn.random)]"
log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r" log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"
http-request redirect location %[req.hdr(Host),map_dom({{ haproxy.config.dir }}/maps/redirects)] code 301 if { req.hdr(Host),map_dom({{ haproxy.config.dir }}/maps/redirects) -m found } http-request redirect location %[req.hdr(Host),map_dom({{ haproxy.config.dir }}/maps/redirects)] code 301 if { req.hdr(Host),map_dom({{ haproxy.config.dir }}/maps/redirects) -m found }
http-request deny deny_status 404 unless domains http-request deny deny_status 404 unless domains
{%- if haproxy.config.admin %} {%- if haproxy.config.admin %}
use_backend admin if self_host internal path_admin use_backend admin if self_host internal
{%- endif %} {%- endif %}
use_backend %[req.hdr(Host),lower,map({{ haproxy.config.dir }}/maps/vhosts,nginx)] use_backend %[req.hdr(Host),lower,map({{ haproxy.config.dir }}/maps/vhosts,nginx)]
monitor-uri /dead_or_alive monitor-uri /dead_or_alive
default_backend {{ ns.default_backend }} default_backend {{ ns.default_backend }}
# HTTP Backends # HTTP Backends
{%- for name, values in haproxy.config.vhosts.items() %} {%- for name, values in haproxy.config.vhosts.items() %}
{%- if not values.redirect|default(False) %} {%- if not values.redirect|default(False) %}
@ -191,6 +209,7 @@ backend {{ name }} from {{ haproxy.config.namespace }}
{%- for step in values.check_steps|default([]) %} {%- for step in values.check_steps|default([]) %}
http-check {{ step }} http-check {{ step }}
{%- endfor %} {%- endfor %}
{{ statusresponses() }}
{%- endif %} {%- endif %}
{%- if values.head|default(False) %} {%- if values.head|default(False) %}
{{ head() }} {{ head() }}
@ -217,9 +236,14 @@ listen {{ name }} from {{ haproxy.config.namespace }}
bind *:{{ values.port }},:::{{ values.port }} v4v6 name {{ name }} bind *:{{ values.port }},:::{{ values.port }} v4v6 name {{ name }}
mode tcp mode tcp
option tcplog option tcplog
option tcpka
{%- if values.type == "postgres" %} {%- if values.type == "postgres" %}
option pgsql-check user repmgr option pgsql-check user repmgr
option tcpka {%- endif %}
{%- if values.type == "spoe" %}
timeout connect 1s
timeout server 1s
option spop-check
{%- endif %} {%- endif %}
default-server inter 3s fall 3 default-server inter 3s fall 3
{{- tcpendpoints(servers=values.servers, check=values.check|default(haproxy.config.check)) }} {{- tcpendpoints(servers=values.servers, check=values.check|default(haproxy.config.check)) }}
@ -227,8 +251,12 @@ listen {{ name }} from {{ haproxy.config.namespace }}
# SPOE Agents # SPOE Agents
{%- for name, values in haproxy.config.spoe.items() %} {%- for name, values in haproxy.config.spoe.items() %}
listen {{ name }} from {{ haproxy.config.namespace }} backend {{ name }} from {{ haproxy.config.namespace }}
bind *:{{ values.port }},:::{{ values.port }} v4v6 mode tcp
timeout connect 5s
timeout server 3m
option spop-check
{{- tcpendpoints(servers=values.servers, check=values.check|default(haproxy.config.check)) }}
{% endfor %} {% endfor %}
{%- if haproxy.config.admin %} {%- if haproxy.config.admin %}

View File

@ -1,23 +1,24 @@
## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} ## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }}
{%- from "haproxy/map.jinja" import haproxy with context %} {%- from "haproxy/map.jinja" import haproxy with context %}
{%- for name, values in haproxy.config.spoe.items() %} {% for name, values in haproxy.config.spoe.items() -%}
[{{ name }}] [{{ name }}]
spoe-agent {{ name }} spoe-agent {{ name }}
messages {{ " ".join(values.messages.keys()) }} option var-prefix {{ name }} messages {{ " ".join(values.messages.keys()) }}
timeout hello 2s option var-prefix {{ name }}
timeout idle 2m
timeout processing 50ms
use-backend {{ name }}
log global log global
timeout hello {{ values.timeout_hello|default("2s") }}
timeout idle {{ values.timeout_idle|default("2m") }}
timeout processing {{ values.timeout_processing|default("300ms") }}
use-backend {{ name }}
#{%- for m, m_values in values.messages.items() %} {% for m, m_values in values.messages.items() -%}
#spoe-message {{ m }} spoe-message {{ m }}
# {%- if m_values.args.keys() > 0 %} {%- if m_values.args.keys()|length > 0 %}
# args {# " ".join(["%s=%s".format(i,v) for (i, v) in m_values.args.items()]) #} args {% for i,v in m_values.args.items() %}{{ "{}={}".format(i,v) }} {% endfor %}
# {%- endif %} {%- endif %}
# {%- if m_values.event %} {%- if m_values.event %}
# event {{ m_values.event }} event {{ m_values.event }}
# {%- endif %} {%- endif %}
#{% endfor %} {% endfor -%}
#{% endfor -%} {% endfor -%}