puppet-prod/hieradata/roles/infra/halb/haproxy2.yaml
Ben Vincent 368a8a5e89
All checks were successful
Build / precommit (pull_request) Successful in 5m1s
feat: add SMTP submission listener and enhance stalwart configuration
- add SMTP submission listener on port 587 with TLS requirement
- configure HAProxy frontend/backend for submission with send-proxy-v2 support
- add send-proxy-v2 support to all listeners
- add dynamic HAProxy node discovery for proxy trusted networks
- use service hostname instead of node FQDN for autoconfig/autodiscover
- remove redundant IMAP/IMAPS/SMTP alt-names from TLS certificates
- update VRRP CNAME configuration to use mail.main.unkin.net
2025-11-09 17:04:16 +11:00

232 lines
6.2 KiB
YAML

---
hiera_include:
- frrouting
- profiles::haproxy::server
- exporters::frr_exporter
# networking
anycast_ip: 198.18.19.17
systemd::manage_networkd: true
systemd::manage_all_network_files: true
networking::interfaces:
eth0:
type: physical
forwarding: true
dhcp: true
anycast0:
type: dummy
ipaddress: "%{hiera('anycast_ip')}"
netmask: 255.255.255.255
mtu: 1500
# frrouting
exporters::frr_exporter::enable: true
frrouting::ospfd_router_id: "%{facts.networking.ip}"
frrouting::ospfd_redistribute:
- connected
frrouting::ospfd_interfaces:
eth0:
area: 0.0.0.0
anycast0:
area: 0.0.0.0
frrouting::daemons:
ospfd: true
# additional repos
profiles::yum::global::repos:
frr-extras:
name: frr-extras
descr: frr-extras repository
target: /etc/yum.repos.d/frr-extras.repo
baseurl: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
frr-stable:
name: frr-stable
descr: frr-stable repository
target: /etc/yum.repos.d/frr-stable.repo
baseurl: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
# haproxy metrics
consul::services:
haproxy-metrics:
service_name: 'haproxy-metrics'
tags:
- 'metrics'
- 'metrics_scheme=https'
- 'metrics_job=haproxy'
address: "%{facts.networking.ip}"
port: 8405
checks:
- id: 'haproxy_metrics_https_check'
name: 'HAProxy Metrics Check'
http: "https://%{facts.networking.fqdn}:8405/metrics"
method: 'GET'
tls_skip_verify: true
interval: '10s'
timeout: '1s'
profiles::consul::client::node_rules:
- resource: service
segment: haproxy-metrics
disposition: write
- resource: service
segment: frr_exporter
disposition: write
# haproxy
profiles::haproxy::peers::enable: true
profiles::haproxy::resolvers::enable: true
profiles::haproxy::ls_stats::port: 9090
profiles::haproxy::ls_stats::user: 'admin'
profiles::selinux::setenforce::mode: permissive
profiles::haproxy::server::globals:
log:
- /dev/log local0
- /dev/log local1 notice
stats:
- timeout 30s
- socket /var/lib/haproxy/stats
- socket /var/lib/haproxy/admin.sock mode 660 level admin
ca-base: /etc/ssl/certs
crt-base: /etc/ssl/private
ssl-default-bind-ciphers: EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
ssl-default-bind-options: 'ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.3'
ssl-default-server-ciphers: kEECDH+aRSA+AES:kRSA+AES:+AES256:RC4-SHA:!kEDH:!LOW:!EXP:!MD5:!aNULL:!eNULL
ssl-default-server-options: no-sslv3
tune.ssl.default-dh-param: 2048
profiles::haproxy::server::defaults:
mode: http
option:
- httplog
- dontlognull
- http-server-close
- forwardfor except 127.0.0.0/8
- redispatch
timeout:
- http-request 10s
- queue 1m
- connect 10s
- client 5m
- server 5m
- http-keep-alive 10s
- 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/'
use_backend:
- 'be_letsencrypt if acl-letsencrypt'
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/'
use_backend:
- 'be_letsencrypt if acl-letsencrypt'
http-request:
- 'set-header X-Forwarded-Proto https'
- 'set-header X-Real-IP %[src]'
fe_metrics:
description: 'Metrics Frontend'
bind:
0.0.0.0:8405:
- ssl
- crt /etc/pki/tls/vault/certificate.pem
- ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
- force-tlsv12
mode: 'http'
options:
http-request:
- 'set-header X-Forwarded-Proto https'
- 'set-header X-Real-IP %[src]'
- 'use-service prometheus-exporter if { path /metrics }'
fe_imap:
description: 'Frontend for Stalwart IMAP (STARTTLS)'
bind:
0.0.0.0:143: []
mode: 'tcp'
options:
log: global
default_backend: be_stalwart_imap
tcp-request:
- inspect-delay 5s
- content accept if { req_len 0 }
fe_imaps:
description: 'Frontend for Stalwart IMAPS (implicit TLS)'
bind:
0.0.0.0:993: []
mode: 'tcp'
options:
log: global
default_backend: be_stalwart_imaps
tcp-request:
- inspect-delay 5s
- content accept if { req_len 0 }
fe_smtp:
description: 'Frontend for Stalwart SMTP'
bind:
0.0.0.0:25: []
mode: 'tcp'
options:
log: global
default_backend: be_stalwart_smtp
tcp-request:
- inspect-delay 5s
- content accept if { req_len 0 }
fe_submission:
description: 'Frontend for Stalwart SMTP Submission'
bind:
0.0.0.0:587: []
mode: 'tcp'
options:
log: global
default_backend: be_stalwart_submission
tcp-request:
- inspect-delay 5s
- content accept if { req_len 0 }
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 }
prometheus::haproxy_exporter::cnf_scrape_uri: unix:/var/lib/haproxy/stats
prometheus::haproxy_exporter::export_scrape_job: true