From d10bca31e6093ec05ec83b24983afbac83d9c4a9 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 12 Nov 2022 08:44:46 +0100 Subject: [PATCH] backport a few tweaks made after the talk --- etc/haproxy/haproxy.cfg | 57 +++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/etc/haproxy/haproxy.cfg b/etc/haproxy/haproxy.cfg index b8050b0..cad172f 100644 --- a/etc/haproxy/haproxy.cfg +++ b/etc/haproxy/haproxy.cfg @@ -117,9 +117,18 @@ frontend external 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 + # Is the request coming for the server itself (stats…) - acl self hdr(host) -i my-hostname my-hostname.domain.tld - acl munin hdr(host) -i munin + acl self var(req.hdr_host) -m str my-hostname my-hostname.domain.tld + 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 @@ -132,21 +141,27 @@ frontend external 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] # Set header if not coming from Varnish 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 - http-request set-header X-Unique-ID %[uuid()] unless { hdr(X-Unique-ID) -m found } - http-request add-header X-Boost-Step1 "haproxy-external" + 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-response add-header X-Boost-Step1 "haproxy-external; ssl-frontend" if { ssl_fc } - http-response add-header X-Boost-Step1 "haproxy-external; no-ssl-frontend" if !{ ssl_fc } - http-response set-header X-Boost-Server my-hostname + 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 my-hostname # Debug: Enable this to add a full log line in the response ### http-response add-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" @@ -162,20 +177,20 @@ frontend external use_backend letsencrypt if letsencrypt # BEGIN frontend_external section for site 'example' - acl example_com_domains hdr(host) -i example.com - acl example_com_domains2 hdr(host) -i example.org www.example.org + acl example_com_domains var(req.hdr_host) -m str example.com + acl example_com_domains2 var(req.hdr_host) -m str example.org www.example.org # Redirect to HTTPS without Let's Encrypt certificate - ### redirect scheme https code 301 if example_com_domains !{ ssl_fc } + ### http-request redirect scheme https code 301 if example_com_domains !{ ssl_fc } # Redirect to HTTPS with Let's Encrypt certificate (exclude LE challenge from redirection) - ### redirect scheme https code 301 if example_com_domains !{ ssl_fc } !letsencrypt + ### http-request redirect scheme https code 301 if example_com_domains !{ ssl_fc } !letsencrypt # Redirect a domain to another without Let's encrypt certificate - ### redirect prefix https://example-to.org code 301 if { hdr(host) -i example-from.org } + ### http-request redirect prefix https://example-to.org code 301 if { var(req.hdr_host) -m str example-from.org } # Redirect a domain to another with a Let's encrypt certificate (exclude Let's Enrypt challenge from redirection) - ### redirect prefix https://example-to.org code 301 if { hdr(host) -i example-from.org } !letsencrypt + ### http-request redirect prefix https://example-to.org code 301 if { var(req.hdr_host) -m str example-from.org } !letsencrypt # HSTS (31536000 seconds = 1 year) ### http-response set-header Strict-Transport-Security max-age=31536000 if example_com_domains @@ -219,17 +234,17 @@ frontend internal http-request set-header X-Forwarded-Proto %[hdr(x-forwarded-proto)] if forwarded_proto varnish_from # BEGIN HTTP tagging - http-request add-header X-Boost-Step3 "haproxy-internal" + http-request set-header x-boost-step3 "haproxy-internal" - http-response add-header X-Boost-Step3 "haproxy-internal; ssl-backend" if { ssl_bc } - http-response add-header X-Boost-Step3 "haproxy-internal; no-ssl-backend" if !{ ssl_bc } + 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 } # Debug: Enable this to add a full log line in the response ### http-response add-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" # END HTTP tagging # BEGIN frontend_internal section for site 'example' - acl example_com_domains hdr(host) -i example.com + acl example_com_domains var(req.hdr_host) -m str example.com # routing directives, all conditionned by (at least) the "example_com_domains" ACL use_backend example_com if example_com_domains @@ -244,8 +259,6 @@ backend varnish # BEGIN backend section for site 'example' backend example_com errorfile 503 /etc/haproxy/sites/example/maintenance.http - http-response set-header X-Boost-Proto https if { ssl_bc } - http-response set-header X-Boost-Proto http if !{ ssl_bc } server example-hostname 1.2.3.4:443 check observe layer4 ssl verify none