# PPLG HAProxy - Internal TLS Termination for Prospero # Services: Grafana, PgAdmin, Prometheus (via OAuth2-Proxy), Loki, Alertmanager # Managed by Ansible - Red Panda Approved global log 127.0.0.1:{{pplg_haproxy_syslog_port}} local0 stats timeout 30s # Default SSL material locations ca-base /etc/ssl/certs crt-base /etc/ssl/private # SSL/TLS configuration ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384 ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets defaults log global mode http option httplog option dontlognull 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" timeout connect 5s timeout client 50s timeout server 50s # Stats page with Prometheus metrics listen stats bind *:{{pplg_haproxy_stats_port}} mode http stats enable stats uri /metrics stats refresh 15s stats show-legends stats show-node # Prometheus metrics endpoint http-request use-service prometheus-exporter if { path /metrics } # HTTP frontend - redirect all traffic to HTTPS frontend http_frontend bind *:80 mode http option httplog http-request redirect scheme https code 301 # HTTPS frontend with subdomain-based routing frontend https_frontend bind *:443 ssl crt {{pplg_haproxy_cert_path}} mode http option httplog option forwardfor # Forward original protocol and host http-request set-header X-Forwarded-Proto https http-request set-header X-Forwarded-Port %[dst_port] http-request set-header X-Forwarded-Host %[req.hdr(Host)] # 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" # Subdomain ACLs acl host_grafana hdr_beg(host) -i grafana.{{pplg_haproxy_domain}} acl host_pgadmin hdr_beg(host) -i pgadmin.{{pplg_haproxy_domain}} acl host_prometheus hdr_beg(host) -i prometheus.{{pplg_haproxy_domain}} acl host_loki hdr_beg(host) -i loki.{{pplg_haproxy_domain}} acl host_alertmanager hdr_beg(host) -i alertmanager.{{pplg_haproxy_domain}} # Prometheus write API - bypass OAuth2-Proxy (machine-to-machine) acl is_prometheus_write path_beg /api/v1/write use_backend backend_grafana if host_grafana use_backend backend_pgadmin if host_pgadmin use_backend backend_prometheus_direct if host_prometheus is_prometheus_write use_backend backend_prometheus if host_prometheus use_backend backend_loki if host_loki use_backend backend_alertmanager if host_alertmanager # Grafana - Native Casdoor OAuth SSO backend backend_grafana mode http balance roundrobin option httpchk GET /api/health http-check expect status 200 server grafana_1 127.0.0.1:3000 check # PgAdmin - Native Casdoor OAuth SSO backend backend_pgadmin mode http balance roundrobin option httpchk GET /misc/ping http-check expect status 200 server pgadmin_1 127.0.0.1:{{pgadmin_port}} check # Prometheus UI - via OAuth2-Proxy sidecar backend backend_prometheus mode http balance roundrobin option httpchk GET /ping http-check expect status 200 server prometheus_1 127.0.0.1:{{prometheus_proxy_port}} check # Prometheus Write API - direct (no auth, machine-to-machine) backend backend_prometheus_direct mode http balance roundrobin server prometheus_write_1 127.0.0.1:9090 check # Loki - no auth (machine-to-machine log ingestion) backend backend_loki mode http balance roundrobin option httpchk GET /ready http-check expect status 200 server loki_1 127.0.0.1:{{loki_port}} check # Alertmanager - internal only backend backend_alertmanager mode http balance roundrobin option httpchk GET /-/healthy http-check expect status 200 server alertmanager_1 127.0.0.1:{{alertmanager_port}} check