Re: [*EXT*] Re: Public-facing haproxy : recommandation about headers

2023-12-10 Thread Shawn Heisey

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

2023-12-09 Thread Shawn Heisey

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

2023-12-09 Thread Tristan

> 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

2023-12-08 Thread Willy Tarreau
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

2023-12-08 Thread Ionel GARDAIS
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

2023-12-08 Thread Tristan
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

2023-12-08 Thread Ionel GARDAIS
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