ansible-roles/boost-proxy/templates-examples/haproxy/haproxy.default.cfg.j2
Jérémy Lecour d03910d5f8
All checks were successful
gitea/ansible-roles/pipeline/head This commit looks good
boost-proxy: comments in english
2022-11-27 14:23:12 +01:00

294 lines
11 KiB
Django/Jinja

# {{ ansible_managed }}
#
# Inspired by https://gist.github.com/haproxytechblog/dc5c3b5e2801d36b79e00f07b2309c14
#
# This is an example HAProxy config for a Boost Proxy.
# You should copy it into your projetct and customize it.
######################################################################################
global
log /dev/log local0
log /dev/log local1 notice
chroot {{ haproxy_chroot }}
stats socket {{ haproxy_socket }} mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
node {{ ansible_hostname }}
server-state-file {{ haproxy_server_state_file }}
maxconn 60000
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# generated 2021-05-03, Mozilla Guideline v5.6, HAProxy 2.2, OpenSSL 1.1.1d, intermediate configuration
# https://ssl-config.mozilla.org/#server=haproxy&version=2.2&config=intermediate&openssl=1.1.1d&guideline=5.6
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-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 prefer-client-ciphers no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
ssl-default-server-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /etc/ssl/dhparam-haproxy
ssl-dh-param-file /etc/ssl/dhparam-haproxy
defaults
log global
mode http
option httplog
option dontlognull
option log-separate-errors
option httpclose
option abortonclose
option http-server-close
option redispatch
timeout connect 5s
timeout client 300s
timeout server 300s
timeout queue 60s
timeout http-request 15s
load-server-state-from-file global
maxconn 50000
# Default options for "server" directive in backends
default-server maxconn 2000 on-error fail-check slowstart 60s inter 5s fastinter 1s downinter 1s weight 100 fall 3 rise 2
http-errors boost-default-errors
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
resolvers local_dns
parse-resolv-conf
resolve_retries 3
timeout resolve 1s
timeout retry 1s
hold other 30s
hold refused 30s
hold nx 30s
hold timeout 30s
hold valid 10s
hold obsolete 30s
{% if haproxy_stats_enable %}
# BEGIN Stats section
{% if haproxy_stats_users %}
userlist stats_users
{% for user in haproxy_stats_users | default([]) %}
user {{ user.login }} password {{ user.password }}
{% endfor %}
{% endif %}
listen stats
mode http
bind {{ haproxy_stats_bind_directive }}
{% if haproxy_stats_internal_enable %}
bind {{ haproxy_stats_internal_host }}:{{ haproxy_stats_internal_port }}
{% endif %}
acl stats_access_ips src -f /etc/haproxy/stats_access_ips
acl stats_admin_ips src -f /etc/haproxy/stats_admin_ips
stats enable
stats refresh 10s
stats uri {{ haproxy_stats_path }}
stats show-legends
stats show-node
stats admin if stats_admin_ips
{% if haproxy_stats_users %}
acl stats_users http_auth(stats_users)
stats http-request auth realm "HAProxy admin" if !stats_access_ips !stats_users
{% else %}
stats http-request deny if !stats_access_ips
{% endif %}
http-request set-log-level silent
# END Stats section
{% endif %}
# This frontend is the main entry point from "origin" http clients
frontend external
bind 0.0.0.0:80,:::80
bind 0.0.0.0:443,:::443 ssl strict-sni alpn h2,http/1.1 crt /etc/haproxy/ssl
option forwardfor
errorfiles boost-default-errors
# Reject the request at the TCP level if source is in the denylist
tcp-request connection reject if { src -f /etc/haproxy/deny_ips }
# Remove a possible x-forwarded-for header already present
http-request del-header x-forwarded-for if { req.hdr(x-forwarded-for) -m found }
# Store the Host header in lowercase, to speedup ACL later
http-request set-var(req.hdr_host) req.hdr(host),lower
# Capture host header in logs
http-request capture var(req.hdr_host) len 32
# Is the request coming for the server itself (stats…)
acl server_hostname var(req.hdr_host) -m str {{ ansible_fqdn }} {{ ansible_hostname }}
acl munin var(req.hdr_host) -m str munin
# List of IP that will not go the maintenance backend
acl maintenance_ips src -f /etc/haproxy/maintenance_ips
# Detect Let's Encrypt challenge requests
acl letsencrypt path_dir -i /.well-known/acme-challenge
# Determine if the request is routable to Varnish
acl varnish_available nbsrv(varnish) gt 0
acl varnish_detected res.hdr(x-varnish) -m found
acl varnish_http_verb method GET HEAD PURGE
# Reject the request at the TCP level if source is in the denylist
tcp-request connection reject if { src -f /etc/haproxy/deny_ips }
http-request set-header x-forwarded-port %[dst_port]
http-request set-header x-forwarded-proto http if !{ ssl_fc }
http-request set-header x-forwarded-proto https if { ssl_fc }
# BEGIN HTTP tagging
acl xid_req_exists req.hdr(x-request-id) -m found
http-request set-var(txn.xid) req.hdr(x-request-id) if xid_req_exists
http-request set-var(txn.xid) uuid() unless xid_req_exists
http-request capture var(txn.xid) len 64
http-request set-header x-request-id %[var(txn.xid)] unless xid_req_exists
acl xid_res_exists res.hdr(x-request-id) -m found
http-after-response set-header x-request-id %[var(txn.xid)] unless xid_res_exists
http-request set-header x-boost-step1 "haproxy-external"
http-response set-header x-boost-step1 "haproxy-external; ssl-frontend" if { ssl_fc }
http-response set-header x-boost-step1 "haproxy-external; no-ssl-frontend" if !{ ssl_fc }
http-response set-header x-boost-server {{ ansible_hostname }}
# Full log line added in header to help debug
{% if 'preprod' in group_names %}
http-response set-header x-haproxy-log-external "%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"
{% else %}
# Uncomment to enable
### http-response set-header x-haproxy-log-external "%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"
{% endif %}
# END HTTP tagging
# Global maintenance mode
# Uncomment to enable
### use_backend maintenance unless maintenance_ips
use_backend local if server_hostname
use_backend local if munin
# "letsencrypt" must stay after "local"
use_backend letsencrypt if letsencrypt
{% for site in boost_sites_enabled %}
# BEGIN frontend_external section for site '{{ site }}'
{% include "templates/boost-sites/" + site + "/haproxy/frontend_external.j2" %}
{# Do not remove the blank line below #}
# END frontend_external section for site '{{ site }}'
{% endfor %}
default_backend goto_internal
# This is used as a fallback to go to the internal frontend
# This is not supposed to happen
backend goto_internal
server haproxy-internal {{ boost_haproxy_proxy_socket }} send-proxy-v2
# This frontend is only used when returning from varnish
frontend internal
bind {{ boost_haproxy_proxy_socket }} user root mode 666 accept-proxy
capture request header Host len 32
option forwardfor
# Check URL (used by Varnish)
monitor-uri {{ boost_haproxy_check_url | mandatory }}
# Store the Host header in lowercase, to speedup ACL later
http-request set-var(req.hdr_host) req.hdr(host),lower
# Capture host header in logs
http-request capture var(req.hdr_host) len 32
acl varnish_from req.hdr(x-varnish) -m found
acl forwarded_proto req.hdr(x-forwarded-proto) -m found
# Keep header if present and coming from Varnish
http-request set-header x-forwarded-proto %[req.hdr(x-forwarded-proto)] if forwarded_proto varnish_from
# BEGIN HTTP tagging
http-request set-header x-boost-step3 "haproxy-internal"
http-response set-header x-boost-step3 "haproxy-internal; ssl-backend" if { ssl_bc }
http-response set-header x-boost-step3 "haproxy-internal; no-ssl-backend" if !{ ssl_bc }
# Full log line added in header to help debug
{% if 'preprod' in group_names %}
http-response set-header x-haproxy-log-internal "%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"
{% else %}
# Uncomment to enable
### http-response set-header x-haproxy-log-internal "%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"
{% endif %}
# END HTTP tagging
{% for site in boost_sites_enabled %}
# BEGIN frontend_internal section for site '{{ site }}'
{% include "templates/boost-sites/" + site + "/haproxy/frontend_internal.j2" %}
{# Do not remove the blank line below #}
# END frontend_internal section for site '{{ site }}'
{% endfor %}
backend varnish
option httpchk HEAD {{ boost_varnish_check_url | mandatory }}
server varnish_sock {{ boost_varnish_proxy_socket }} check observe layer7 maxconn 3000 inter 1s send-proxy-v2
{% for site in boost_sites_enabled %}
# BEGIN backend section for site '{{ site }}'
{% include "templates/boost-sites/" + site + "/haproxy/backend.j2" %}
{# Do not remove the blank line below #}
# END backend section for site '{{ site }}'
{% endfor %}
backend letsencrypt
{% if boost_certificates_server is not defined or boost_certificates_server == inventory_hostname %}
server localhost 127.0.0.1:{{ boost_nginx_proxy_port | mandatory }} send-proxy-v2 maxconn 10
{% else %}
server {{ boost_certificates_server }} {{ hostvars[boost_certificates_server].ansible_host }}:{{ boost_nginx_proxy_port | mandatory }} maxconn 10
{% endif %}
backend local
option httpchk HEAD {{ boost_nginx_check_url | mandatory }}
server localhost 127.0.0.1:{{ boost_nginx_proxy_port | mandatory }} send-proxy-v2 maxconn 10
backend maintenance
http-request set-log-level silent
errorfile 503 /etc/haproxy/errors/maintenance.http