Re: [*EXT*] Re: Public-facing haproxy : recommandation about headers
On 12/10/2023 15:07, Tristan wrote: Cool topic! A few things struck me (of various levels of pertinence, and sorry in advance for the digressions): http-request del-header [Ff]orwarded.+ -m reg http-request del-header [Xx]-[Ff]orwarded.+ -m reg I wonder about the regex use here to handle header case. The HTTP spec mandates that headers names are case-insensitive (https://www.rfc-editor.org/rfc/rfc9110.html#fields), and the documentation (here for example: https://docs.haproxy.org/2.9/configuration.html#4.2-option%20h1-case-adjust-bogus-client) suggests that HAProxy does the right thing and normalizes them all to lower-case by default: Could be that I don't need the checks for different case. Pretty sure it isn't hurting anything to have it there, so I keep it. I'm no expert at this! http-request set-header X-H3 true if { so_name -i -m beg quic443 } you can use HTTP_3.0 as a more readable fetch here I think since: https://github.com/haproxy/haproxy/commit/89da4e9e5d8ef467d52beb9234f832aa9aa87bce in v2.9.0 Though if you are looking to get "GET /" 200 HTTP/3.0 in logs for example, you can use %HV in logs (well, almost... see: https://github.com/haproxy/haproxy/issues/2095#issuecomment-1803179697 the portion about HTTP versions). I used the "name" option on all my bind lines. The ones for quic all start with "quic443". By checking for that and setting a header, applications I can know that a given request uses HTTP3 in the browser. The custom "X-H3" header is used by a silly little PHP program I wrote: https://http3test.elyograg.org If there is something more standard, I can always adjust that. http-request set-header X-Scheme https http-request set-header X-Forwarded-Scheme https http-request set-header X-Forwarded-Proto https http-request set-header X-Forwarded-HTTPS true http-request set-header X-Forwarded-Host %[req.hdr(Host)] http-request set-header X-Forwarded-SSL true http-request set-header X-HTTPS on http-request set-header X-SSL %[ssl_fc] I don't know how demanding your backends/developers are, but I'd consider threatening them with the nearest sharp object if they asked all of these from me... I haven't got any developers. It's all personal websites, mostly using off-the-shelf applications. Gitlab, Wordpress, Plex, and others. I probably don't need all those headers, I was just setting everything I could think of that a web application might use to detect that the browser is using https. My backend connections are not encrypted, except for plex. Thanks, Shawn
Re: [*EXT*] Re: Public-facing haproxy : recommandation about headers
On 12/8/23 14:35, Ionel GARDAIS wrote: Thanks Tristan. So typically I’d say to add to every single http frontend: > http-request set-header X-Forwarded-For %[src] http-request set-header X-Forwarded-Host %[hdr(Host)] http-request set-header X-Forwarded-Proto %[ssl_fc,iif(https,http)] http-request set-header Forwarded "by=${HOSTNAME};for=%[src];host=%[hdr(Host)];proto=%[ssl_fc,iif(https,http)]"| Almost what I already did :) What about using %[hdr(host,1)] to forcefully use the first Host header if multiple headers are sent ? What I have done: In "defaults" I have: option forwardfor except 127.0.0.1 In the https frontend, I have the following header-related options, in this order: http-request del-header [Ff]orwarded.+ -m reg http-request del-header [Xx]-[Ff]orwarded.+ -m reg http-request add-header Forwarded "by=\"${HOSTNAME}\"; for=\"%[src]\"; host=\"%[hdr(Host)]\"; proto=https" http-request set-header X-H3 true if { so_name -i -m beg quic443 } http-request set-header X-Scheme https http-request set-header X-Forwarded-Scheme https http-request set-header X-Forwarded-Port %fp http-request set-header X-Forwarded-Proto https http-request set-header X-Forwarded-HTTPS true http-request set-header X-Forwarded-Host %[req.hdr(Host)] http-request set-header X-Forwarded-SSL true http-request set-header X-Haproxy-Current-Date %T http-request set-header X-HTTPS on http-request set-header X-SSL %[ssl_fc] http-request set-header X-SSL-Session_ID %[ssl_fc_session_id,hex] http-after-response set-header Strict-Transport-Security "max-age=1600; includeSubDomains; preload;" http-after-response add-header alt-svc 'h3=":443"; ma=7200' Question for the group: Does that look like a good config? Should I be doing something different? Thanks, Shawn
Re: [*EXT*] Re: Public-facing haproxy : recommandation about headers
> On 8 Dec 2023, at 22:38, Ionel GARDAIS > wrote: > > What about using %[hdr(host,1)] to forcefully use the first Host header if > multiple headers are sent ? I just deny requests with multiple Host headers with an error message telling clients to fix their stuff, personally. But yes, that works too Tristan
Re: [*EXT*] Re: Public-facing haproxy : recommandation about headers
Hi Ionel, On Fri, Dec 08, 2023 at 10:35:52PM +0100, Ionel GARDAIS wrote: > Thanks Tristan. > > So typically I'd say to add to every single http frontend: > http-request set-header X-Forwarded-For %[src] > http-request set-header X-Forwarded-Host %[hdr(Host)] > http-request set-header X-Forwarded-Proto %[ssl_fc,iif(https,http)] > http-request set-header Forwarded > "by=${HOSTNAME};for=%[src];host=%[hdr(Host)];proto=%[ssl_fc,iif(https,http)]" > > Almost what I already did :) > What about using %[hdr(host,1)] to forcefully use the first Host header if > multiple headers are sent ? This one is already deduplicated and checked against authority at the lower layers, no worries. Regards, Willy
Re: [*EXT*] Re: Public-facing haproxy : recommandation about headers
Thanks Tristan. So typically I’d say to add to every single http frontend: http-request set-header X-Forwarded-For %[src] http-request set-header X-Forwarded-Host %[hdr(Host)] http-request set-header X-Forwarded-Proto %[ssl_fc,iif(https,http)] http-request set-header Forwarded "by=${HOSTNAME};for=%[src];host=%[hdr(Host)];proto=%[ssl_fc,iif(https,http)]" Almost what I already did :) What about using %[hdr(host,1)] to forcefully use the first Host header if multiple headers are sent ? Ionel -- 232 avenue Napoleon BONAPARTE 92500 RUEIL MALMAISON Capital EUR 219 300,00 - RCS Nanterre B 408 832 301 - TVA FR 09 408 832 301
Re: Public-facing haproxy : recommandation about headers
Hi Ionel, > On 8 Dec 2023, at 17:28, Ionel GARDAIS > wrote: > > > Hi all, > > Regarding a public facing haproxy, what would you recommend about headers > like X-Forwarded-* and Forwarded ? > Delete them with http-request del-header ? > Replace them with http-request set-header ? Always delete, or replace. You have to be careful to *never* only append. Otherwise the client sends X-Forwarded-For: foo, and your backend sees X-Forwarded-For: foo, 1.2.3.4 In that case your backend would likely (wrongfully) decide the client ip is « foo » (or whatever IP the client puts). So typically I’d say to add to every single http frontend: http-request set-header X-Forwarded-For %[src] http-request set-header X-Forwarded-Host %[hdr(Host)] http-request set-header X-Forwarded-Proto %[ssl_fc,iif(https,http)] http-request set-header Forwarded "by=${HOSTNAME};for=%[src];host=%[hdr(Host)];proto=%[ssl_fc,iif(https,http)]" Another one to be careful with is the difference between hdr(…) and fhdr(…). The first one splits on ",", which can give surprising results sometimes. Finally, you might want to deny requests with a Via header. This typically indicates usage of a proxy. Maybe your clients legitimately use those, but more often than not this is just abuse of compromised routers for DoS attacks (at least in our case, it is). > > Do the options forwardfor and forwarded behave like a set-header or a > add-header directive ? If I remember correctly, the baked-in directives work by *appending*, so they’re only ok for intermediate proxies, not for edge ones. Tristan
Public-facing haproxy : recommandation about headers
Hi all, Regarding a public facing haproxy, what would you recommend about headers like X-Forwarded-* and Forwarded ? Delete them with http-request del-header ? Replace them with http-request set-header ? Do the options forwardfor and forwarded behave like a set-header or a add-header directive ? Thanks, Ionel -- 232 avenue Napoleon BONAPARTE 92500 RUEIL MALMAISON Capital EUR 219 300,00 - RCS Nanterre B 408 832 301 - TVA FR 09 408 832 301