From 86974926115ff1f05a1aad6f2aa3961555af050f Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sun, 28 Apr 2024 22:19:44 +1000 Subject: [PATCH] feat: haproxy refactor - configure deep merging in hiera - move fe_http and fe_https to hiera - configure pve backends for standard and api traffic --- hieradata/common.yaml | 12 +++ .../au/region/drw1/infra/halb/haproxy.yaml | 42 --------- .../au/region/syd1/infra/halb/haproxy.yaml | 88 ++++++++----------- hieradata/roles/infra/halb/haproxy.yaml | 51 +++++++++++ site/profiles/manifests/haproxy/fe_http.pp | 23 ----- site/profiles/manifests/haproxy/fe_https.pp | 23 ----- site/profiles/manifests/haproxy/listener.pp | 21 ----- site/profiles/manifests/haproxy/server.pp | 2 - site/profiles/manifests/proxmox/weblb.pp | 14 ++- 9 files changed, 113 insertions(+), 163 deletions(-) delete mode 100644 site/profiles/manifests/haproxy/fe_http.pp delete mode 100644 site/profiles/manifests/haproxy/fe_https.pp delete mode 100644 site/profiles/manifests/haproxy/listener.pp diff --git a/hieradata/common.yaml b/hieradata/common.yaml index f5422e6..4d7b5d0 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -30,6 +30,18 @@ lookup_options: profiles::haproxy::server::globals: merge: strategy: deep + profiles::haproxy::server::frontends: + merge: + strategy: deep + profiles::haproxy::server::backends: + merge: + strategy: deep + profiles::haproxy::server::mappings: + merge: + strategy: deep + profiles::haproxy::server::listeners: + merge: + strategy: deep haproxy::backend: merge: strategy: deep diff --git a/hieradata/country/au/region/drw1/infra/halb/haproxy.yaml b/hieradata/country/au/region/drw1/infra/halb/haproxy.yaml index 017eb4d..20a8e44 100644 --- a/hieradata/country/au/region/drw1/infra/halb/haproxy.yaml +++ b/hieradata/country/au/region/drw1/infra/halb/haproxy.yaml @@ -52,48 +52,6 @@ profiles::haproxy::backends: - set-header X-Forwarded-Port %[dst_port] - add-header X-Forwarded-Proto https if { dst_port 443 } redirect: 'scheme https if !{ ssl_fc }' - be_letsencrypt: - description: Backend for LetsEncrypt Verifications - collect_exported: true - options: - balance: roundrobin - be_default: - description: Backend for unmatched HTTP traffic - collect_exported: true - options: - balance: roundrobin - option: - - httpchk GET / - - forwardfor - cookie: SRVNAME insert - http-request: - - set-header X-Forwarded-Port %[dst_port] - - add-header X-Forwarded-Proto https if { dst_port 443 } - -# fe_http -profiles::haproxy::fe_http::bind_addr: 0.0.0.0 -profiles::haproxy::fe_http::bind_port: 80 -profiles::haproxy::fe_http::bind_opts: - - transparent -profiles::haproxy::fe_http::acls: - - 'acl-letsencrypt path_beg /.well-known/acme-challenge/' -profiles::haproxy::fe_http::http_request: - - 'set-header X-Forwarded-Proto https' - - 'set-header X-Real-IP %[src]' - -# fe_https -profiles::haproxy::fe_https::bind_addr: 0.0.0.0 -profiles::haproxy::fe_https::bind_port: 443 -profiles::haproxy::fe_https::bind_opts: - - ssl - - crt-list /etc/haproxy/certificate.list - - ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH - - force-tlsv12 -profiles::haproxy::fe_https::acls: - - 'acl-letsencrypt path_beg /.well-known/acme-challenge/' -profiles::haproxy::fe_https::http_request: - - 'set-header X-Forwarded-Proto https' - - 'set-header X-Real-IP %[src]' profiles::haproxy::certlist::enabled: true profiles::haproxy::certlist::certificates: diff --git a/hieradata/country/au/region/syd1/infra/halb/haproxy.yaml b/hieradata/country/au/region/syd1/infra/halb/haproxy.yaml index 5bcf4c8..c7877aa 100644 --- a/hieradata/country/au/region/syd1/infra/halb/haproxy.yaml +++ b/hieradata/country/au/region/syd1/infra/halb/haproxy.yaml @@ -4,81 +4,65 @@ profiles::haproxy::mappings: fe_http: ensure: present mappings: - - 'au-syd1-pve.main.unkin.net be_ausyd1pve' + - 'au-syd1-pve.main.unkin.net be_ausyd1pve_web' + - 'au-syd1-pve-api.main.unkin.net be_ausyd1pve_api' fe_https: ensure: present mappings: - - 'au-syd1-pve.main.unkin.net be_ausyd1pve' + - 'au-syd1-pve.main.unkin.net be_ausyd1pve_web' + - 'au-syd1-pve-api.main.unkin.net be_ausyd1pve_api' -# profiles::haproxy::listeners: -# ls_puppetdbapi_direct: -# collect_exported: false # handled in custom function -# ipaddress: "%{facts.networking.ip}" -# ports: -# - 8081 -# mode: tcp -# options: -# option: -# - tcplog -# - ssl-hello-chk -# balance: roundrobin +profiles::haproxy::frontends: + fe_http: + options: + use_backend: + - "%[req.hdr(host),lower,map(/etc/haproxy/fe_http.map,be_default)]" + fe_https: + options: + acl: + - 'acl_ausyd1pve req.hdr(host) -i https://au-syd1-pve.main.unkin.net' + - 'acl_internalsubnets src 198.18.0.0/16 10.10.12.0/24' + use_backend: + - "%[req.hdr(host),lower,map(/etc/haproxy/fe_https.map,be_default)]" + http-request: + - 'deny if { hdr_dom(host) -i au-syd1-pve.main.unkin.net } !acl_internalsubnets' + http-response: + - 'set-header X-Frame-Options DENY if acl_ausyd1pve' + - 'set-header X-Content-Type-Options nosniff' + - 'set-header X-XSS-Protection 1;mode=block' profiles::haproxy::backends: - be_ausyd1pve: - description: Backend for au-syd1 pve cluster + be_ausyd1pve_web: + description: Backend for au-syd1 pve cluster (Web) collect_exported: false # handled in custom function options: balance: roundrobin option: - httpchk GET / - forwardfor - cookie: SRVNAME insert + - http-keep-alive + - prefer-last-server + cookie: SRVNAME insert indirect nocache + http-reuse: always http-request: - set-header X-Forwarded-Port %[dst_port] - add-header X-Forwarded-Proto https if { dst_port 443 } redirect: 'scheme https if !{ ssl_fc }' - be_letsencrypt: - description: Backend for LetsEncrypt Verifications - collect_exported: true - options: - balance: roundrobin - be_default: - description: Backend for unmatched HTTP traffic - collect_exported: true + be_ausyd1pve_api: + description: Backend for au-syd1 pve cluster (API only) + collect_exported: false # handled in custom function options: balance: roundrobin option: - httpchk GET / - forwardfor - cookie: SRVNAME insert + - http-keep-alive + - prefer-last-server + http-reuse: always http-request: - set-header X-Forwarded-Port %[dst_port] - add-header X-Forwarded-Proto https if { dst_port 443 } - -# fe_http -profiles::haproxy::fe_http::bind_addr: 0.0.0.0 -profiles::haproxy::fe_http::bind_port: 80 -profiles::haproxy::fe_http::bind_opts: - - transparent -profiles::haproxy::fe_http::acls: - - 'acl-letsencrypt path_beg /.well-known/acme-challenge/' -profiles::haproxy::fe_http::http_request: - - 'set-header X-Forwarded-Proto https' - - 'set-header X-Real-IP %[src]' - -# fe_https -profiles::haproxy::fe_https::bind_addr: 0.0.0.0 -profiles::haproxy::fe_https::bind_port: 443 -profiles::haproxy::fe_https::bind_opts: - - ssl - - crt-list /etc/haproxy/certificate.list - - ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH - - force-tlsv12 -profiles::haproxy::fe_https::acls: - - 'acl-letsencrypt path_beg /.well-known/acme-challenge/' -profiles::haproxy::fe_https::http_request: - - 'set-header X-Forwarded-Proto https' - - 'set-header X-Real-IP %[src]' + redirect: 'scheme https if !{ ssl_fc }' profiles::haproxy::certlist::enabled: true profiles::haproxy::certlist::certificates: @@ -87,7 +71,9 @@ profiles::haproxy::certlist::certificates: # additional altnames profiles::pki::vault::alt_names: - au-syd1-pve.main.unkin.net + - au-syd1-pve-api.main.unkin.net # additional cnames profiles::haproxy::dns::cnames: - au-syd1-pve.main.unkin.net + - au-syd1-pve-api.main.unkin.net diff --git a/hieradata/roles/infra/halb/haproxy.yaml b/hieradata/roles/infra/halb/haproxy.yaml index f6e352d..cd212ad 100644 --- a/hieradata/roles/infra/halb/haproxy.yaml +++ b/hieradata/roles/infra/halb/haproxy.yaml @@ -9,6 +9,9 @@ profiles::haproxy::selinux::sebooleans: - haproxy_connect_any profiles::haproxy::server::globals: + log: + - /dev/log local0 + - /dev/log local1 notice stats: - timeout 30s - socket /var/lib/haproxy/stats @@ -38,3 +41,51 @@ profiles::haproxy::server::defaults: - check 10s retries: 3 maxconn: 5000 + +profiles::haproxy::frontends: + fe_http: + description: 'Global HTTP Frontend' + bind: + 0.0.0.0:80: + - transparent + mode: 'http' + options: + acl: + - 'acl-letsencrypt path_beg /.well-known/acme-challenge/' + http-request: + - 'set-header X-Forwarded-Proto https' + - 'set-header X-Real-IP %[src]' + fe_https: + description: 'Global HTTPS Frontend' + bind: + 0.0.0.0:443: + - ssl + - crt-list /etc/haproxy/certificate.list + - ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH + - force-tlsv12 + mode: 'http' + options: + acl: + - 'acl-letsencrypt path_beg /.well-known/acme-challenge/' + http-request: + - 'set-header X-Forwarded-Proto https' + - 'set-header X-Real-IP %[src]' + +profiles::haproxy::backends: + be_letsencrypt: + description: Backend for LetsEncrypt Verifications + collect_exported: true + options: + balance: roundrobin + be_default: + description: Backend for unmatched HTTP traffic + collect_exported: true + options: + balance: roundrobin + option: + - httpchk GET / + - forwardfor + cookie: SRVNAME insert + http-request: + - set-header X-Forwarded-Port %[dst_port] + - add-header X-Forwarded-Proto https if { dst_port 443 } diff --git a/site/profiles/manifests/haproxy/fe_http.pp b/site/profiles/manifests/haproxy/fe_http.pp deleted file mode 100644 index 1d91f11..0000000 --- a/site/profiles/manifests/haproxy/fe_http.pp +++ /dev/null @@ -1,23 +0,0 @@ -# default http frontend -class profiles::haproxy::fe_http ( - Stdlib::IP::Address $bind_addr = $facts['networking']['ip'], - Stdlib::Port $bind_port = 80, - Array $bind_opts = ['transparent'], - Array $acls = [], - Array $http_request = [], - Array $http_response = [], -) { - haproxy::frontend { 'fe_http': - description => 'Default HTTP Frontend', - bind => { "${bind_addr}:${bind_port}" => $bind_opts }, - mode => 'http', - options => { - 'acl' => $acls, - 'http-request' => $http_request, - 'http-response' => $http_response, - 'use_backend' => [ - '%[req.hdr(host),lower,map(/etc/haproxy/fe_http.map,be_default)]', - ], - }, - } -} diff --git a/site/profiles/manifests/haproxy/fe_https.pp b/site/profiles/manifests/haproxy/fe_https.pp deleted file mode 100644 index e7c9b0f..0000000 --- a/site/profiles/manifests/haproxy/fe_https.pp +++ /dev/null @@ -1,23 +0,0 @@ -# default https frontend -class profiles::haproxy::fe_https ( - Stdlib::IP::Address $bind_addr = $facts['networking']['ip'], - Stdlib::Port $bind_port = 443, - Array $bind_opts = [], - Array $acls = [], - Array $http_request = [], - Array $http_response = [], -) { - haproxy::frontend { 'fe_https': - description => 'Default HTTPS Frontend', - bind => { "${bind_addr}:${bind_port}" => $bind_opts }, - mode => 'http', - options => { - 'acl' => $acls, - 'http-request' => $http_request, - 'http-response' => $http_response, - 'use_backend' => [ - '%[req.hdr(host),lower,map(/etc/haproxy/fe_https.map,be_default)]', - ], - }, - } -} diff --git a/site/profiles/manifests/haproxy/listener.pp b/site/profiles/manifests/haproxy/listener.pp deleted file mode 100644 index 3df3b35..0000000 --- a/site/profiles/manifests/haproxy/listener.pp +++ /dev/null @@ -1,21 +0,0 @@ -# profiles::haproxy::listener -define profiles::haproxy::listener ( - Boolean $bind = false, - Boolean $listen = false, - Enum['roundrobin', 'leastconn'] $balance = 'roundrobin', - Array $option = ['tcplog'], - Enum['tcp', 'http'] $mode = 'http', - Stdlib::Port $ports = 443, -) { - - haproxy::listen { 'puppet00': - ipaddress => $facts['networking']['ip'], - ports => $ports, - mode => $mode, - options => { - 'option' => $option, - 'balance' => $balance, - }, - } -} - diff --git a/site/profiles/manifests/haproxy/server.pp b/site/profiles/manifests/haproxy/server.pp index 0a27fea..3ac313e 100644 --- a/site/profiles/manifests/haproxy/server.pp +++ b/site/profiles/manifests/haproxy/server.pp @@ -51,8 +51,6 @@ class profiles::haproxy::server ( include profiles::haproxy::certlist # manage the certificate list file include profiles::haproxy::mappings # manage the domain to backend mappings include profiles::haproxy::ls_stats # default status listener - include profiles::haproxy::fe_http # default http frontend - include profiles::haproxy::fe_https # default https frontend include profiles::haproxy::dns # manage dns for haproxy include profiles::haproxy::frontends # create frontends include profiles::haproxy::backends # create backends diff --git a/site/profiles/manifests/proxmox/weblb.pp b/site/profiles/manifests/proxmox/weblb.pp index 2f6f4e5..a1bd2c0 100644 --- a/site/profiles/manifests/proxmox/weblb.pp +++ b/site/profiles/manifests/proxmox/weblb.pp @@ -6,7 +6,7 @@ class profiles::proxmox::weblb { # export haproxy balancemember profiles::haproxy::balancemember { "${facts['networking']['fqdn']}_${profiles::proxmox::params::pve_webport}}": - service => "be_${facts['country']}${facts['region']}pve", + service => "be_${facts['country']}${facts['region']}pve_web", ports => [$profiles::proxmox::params::pve_webport], options => [ "cookie ${facts['networking']['hostname']}", @@ -18,4 +18,16 @@ class profiles::proxmox::weblb { 'fall 2', ] } + profiles::haproxy::balancemember { "${facts['networking']['fqdn']}_${profiles::proxmox::params::pve_webport}_api2}": + service => "be_${facts['country']}${facts['region']}pve_api", + ports => [$profiles::proxmox::params::pve_webport], + options => [ + 'ssl', + 'verify none', + 'check', + 'inter 2s', + 'rise 3', + 'fall 2', + ] + } }