Refactor HAProxy configuration and certificate management

- Updated HAProxy configuration template to reflect changes for the Taurus Production Environment, including SSL settings and rate limiting for specific endpoints.
- Introduced new playbooks for certificate distribution and validation with OCI Vault, ensuring certificates are correctly managed and renewed.
- Added hooks for uploading renewed certificates to OCI Vault and validating their integrity.
- Enhanced the HAProxy configuration playbook to ensure proper service management and verification of the HAProxy service.
- Updated inventory variables for certificate management and ensured compatibility with the new structure.
This commit is contained in:
2026-03-17 13:13:38 -04:00
parent 856d7e2ef2
commit 0a053c1cd6
13 changed files with 1268 additions and 204 deletions

View File

@@ -1,9 +1,15 @@
# HAProxy configuration for Ouranos Titania
# HAProxy configuration for Taurus Production Environment
# Managed by Ansible - Red Panda Approved
#
# SSL: Let's Encrypt certificate for helu.ca subdomains
# HTTP backends: Casdoor (talos), Gitea (xenia), SearXNG (xenia)
# TCP backend: Gitea SSH (xenia)
global
log 127.0.0.1:{{ haproxy_syslog_port }} local0
log /dev/log local0
log /dev/log local1 notice
stats timeout 30s
# Ubuntu systemd service handles user/group and daemonization
# Default SSL material locations
ca-base /etc/ssl/certs
@@ -38,29 +44,47 @@ listen stats
# Prometheus metrics endpoint
http-request use-service prometheus-exporter if { path /metrics }
# HTTP frontend - redirect all traffic to HTTPS
# HTTP to HTTPS redirect
frontend http_frontend
bind *:{{ haproxy_http_port }}
mode http
option httplog
# Redirect all HTTP to HTTPS
http-request redirect scheme https code 301
# HTTPS frontend with dynamic routing
frontend https_frontend
bind *:{{ haproxy_https_port }} ssl crt {{ haproxy_cert_path }}
bind *:{{ haproxy_https_port }} ssl crt {{ haproxy_cert_path }} alpn h2,http/1.1
mode http
option httplog
option forwardfor
# Forward original protocol and host for reverse-proxied services
http-request set-header X-Forwarded-Proto https
http-request set-header X-Forwarded-Port %[dst_port]
# Security headers
http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains"
http-response set-header X-Frame-Options "SAMEORIGIN"
http-response set-header X-Content-Type-Options "nosniff"
http-response set-header X-XSS-Protection "1; mode=block"
# -------------------------------------------------------------------------
# Rate limiting via stick-tables
# -------------------------------------------------------------------------
# General rate limit: 1000 req/min per source IP
stick-table type ip size 100k expire 1m store http_req_rate(1m)
http-request track-sc0 src
# Auth endpoint rate limit: 20 req/min per source IP
acl is_auth_endpoint path_beg /api/login /api/signup /api/get-captcha /login/oauth/authorize /api/login/oauth/access_token
acl host_id hdr_beg(host) -i id.{{ haproxy_domain }}
# Use backend stick-table for auth endpoint tracking
http-request track-sc1 src table st_casdoor_auth if host_id is_auth_endpoint
# Deny if general rate exceeded
http-request deny deny_status 429 if { sc_http_req_rate(0) gt 1000 }
# Deny if auth endpoint rate exceeded
http-request deny deny_status 429 if host_id is_auth_endpoint { sc_http_req_rate(1,st_casdoor_auth) gt 20 }
{% for backend in haproxy_backends %}
{% if backend.subdomain %}
@@ -86,29 +110,37 @@ backend backend_root
{% endif %}
mode http
balance roundrobin
{% if backend.ssl_backend | default(false) %}
option httpchk
http-check send meth GET uri {{ backend.health_path }} hdr Host {{ backend.subdomain }}.{{ haproxy_domain }}
{% else %}
option httpchk GET {{ backend.health_path }}
{% endif %}
http-check send meth GET uri {{ backend.health_path }} ver HTTP/1.1 hdr Host {{ backend.health_host | default(backend.backend_host) }}
http-check expect status 200
{% if backend.timeout_server is defined %}
timeout server {{ backend.timeout_server }}
{% endif %}
server {{ backend.subdomain or 'root' }}_1 {{ backend.backend_host }}:{{ backend.backend_port }} check{% if backend.ssl_backend | default(false) %} ssl verify none{% endif %}
server {{ backend.subdomain or 'root' }}_1 {{ backend.backend_host }}:{{ backend.backend_port }} check
{% endfor %}
# Stick-table for auth endpoint rate limiting (referenced by frontend)
backend st_casdoor_auth
stick-table type ip size 100k expire 1m store http_req_rate(1m)
# =============================================================================
# TCP Frontends/Backends (non-HTTP protocols)
# =============================================================================
{% for tcp_backend in haproxy_tcp_backends | default([]) %}
# TCP passthrough: {{ tcp_backend.name }}
frontend {{ tcp_backend.name }}_frontend
bind *:{{ tcp_backend.listen_port }}
mode tcp
option tcplog
timeout client 1h
default_backend {{ tcp_backend.name }}_backend
backend {{ tcp_backend.name }}_backend
mode tcp
option tcp-check
timeout server 1h
server {{ tcp_backend.name }}_1 {{ tcp_backend.backend_host }}:{{ tcp_backend.backend_port }} check
{% endfor %}