#####################################
## Global Configuration & Defaults ##
#####################################

global
  log stderr format iso local7

  # generated 2021-06-05, Mozilla Guideline v5.6, HAProxy 2.1, OpenSSL 1.1.1d, intermediate configuration
  # https://ssl-config.mozilla.org/#server=haproxy&version=2.1&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 > /path/to/dhparam
  ssl-dh-param-file /etc/ssl/dhparam.pem

defaults
  log global
  timeout connect 30000
  timeout check 300000
  timeout client 300000
  timeout server 300000

############################################################################
## Frontends: HTTP; HTTPS → HTTPS SNI-based; HTTPS → HTTP(S) header-based ##
############################################################################

frontend http_redirect_frontend
  # HTTP backend to redirect everything to HTTPS
  bind :::80 v4v6
  mode http
  http-request redirect scheme https

frontend https_sni_frontend
  # TCP backend to forward to HTTPS backends based on SNI
  bind :::443 v4v6
  mode tcp

  # Wait up to 5s for a SNI header & only accept TLS connections
  tcp-request inspect-delay 5s
  tcp-request content capture req.ssl_sni len 255
  log-format "%ci:%cp -> %[capture.req.hdr(0)] @ %f (%fi:%fp) -> %b (%bi:%bp)"
  tcp-request content accept if { req.ssl_hello_type 1 }

  ###################################################
  ## Rules: forward to HTTPS(S) header-based rules ##
  ###################################################
  acl use_http_backend req.ssl_sni -i "codeberg.org"
  acl use_http_backend req.ssl_sni -i "join.codeberg.org"
  # TODO: use this if no SNI exists
  use_backend https_termination_backend if use_http_backend

  ############################
  ## Rules: HTTPS SNI-based ##
  ############################
  # use_backend xyz_backend if { req.ssl_sni -i "xyz" }
  default_backend pages_backend

frontend https_termination_frontend
  # Terminate TLS for HTTP backends
  bind /tmp/haproxy-tls-termination.sock accept-proxy ssl strict-sni alpn h2,http/1.1 crt /etc/ssl/private/haproxy/
  mode http

  # HSTS (63072000 seconds)
  http-response set-header Strict-Transport-Security max-age=63072000

  http-request capture req.hdr(Host) len 255
  log-format "%ci:%cp -> %[capture.req.hdr(0)] @ %f (%fi:%fp) -> %b (%bi:%bp)"

  ##################################
  ## Rules: HTTPS(S) header-based ##
  ##################################
  use_backend gitea_backend if { hdr(host) -i codeberg.org }

backend https_termination_backend
  # Redirect to the terminating HTTPS frontend for all HTTP backends
  server https_termination_server /tmp/haproxy-tls-termination.sock send-proxy-v2-ssl-cn
  mode tcp

###############################
## Backends: HTTPS SNI-based ##
###############################

backend pages_backend
  # Pages server is a HTTP backend that uses its own certificates for custom domains
  server pages_server pages:443
  mode tcp

####################################
## Backends: HTTP(S) header-based ##
####################################

backend gitea_backend
  server gitea_server gitea:80
  mode http