HAProxy community

Multiple bind lines, how to check which one?

frontend https

bind *:443 ssl …
server local 127.0.0.1:8080 send-proxy-v2

frontend http
bind *:80
bind 127.0.0.1:8080 accept-proxy

in http, how to check how client connected?
Using nginx behind, setting X-Forwarded-Proto (and Forwarded when available).

frontend https sets them.
want to kill them if client is connecting via http but setting the header(s).

Thanks in advance,
Gerardo

Use http-request set-header, which removes existing headers first (so what the clients sends doesn’t matter):

frontend https
 http-request set-header X-Forwarded-Proto https
frontend http
 http-request set-header X-Forwarded-Proto http

Or, if you have a single frontend:

frontend front1
 http-request set-header X-Forwarded-Proto https if { ssl_fc }
 http-request set-header X-Forwarded-Proto http if ! { ssl_fc }

I do use http-request set-header in the https frontend

It does https frontend (termination) -> http frontend -> backend

But clients can also connect to the http frontend directly.

How to check if connection came via *:80 (nuke X-Forwarded-Proto headers, or set to http) or 127.0.0.1:8080 (the https frontend set the header already, leave it alone).

Thanks,
Gerardo

Why the double termination? Please explain what it is that you are trying to achieve with a HTTPS frontend that short-circuits back to a HTTP frontend which at the same time terminates regular HTTP clients. This can almost certainly be simplified or at the very least setup in a way that doesn’t interfere with basic security task like this.

Basically to dedicate CPUs to SSL processing.

Hap VM started small, then SSL volume grew, and the VM needed more CPUs to manage it.

frontend https bind lines are:

bind-process 2 3
bind *:443 ssl crt /etc/haproxy/ssl/certs/default_cert.pem crt
/etc/haproxy/ssl/certs/ alpn http/1.1 process 2
bind *:443 ssl crt /etc/haproxy/ssl/certs/default_cert.pem crt
/etc/haproxy/ssl/certs/ alpn http/1.1 process 3

Are you suggesting to add the bind:80 line here, no process (?) ?
then can use ssl_fc to decide on the header.

Thanks,
Gerardo

Oh! This was a related issue:

[WARNING] 301/040546 (6326) : Proxy ‘stats’: in multi-process mode, stats will be limited to process assigned to the current request.
[WARNING] 301/040546 (6326) : Proxy ‘stats’: stats admin will not work correctly in multi-process mode.
[WARNING] 301/040546 (6326) : Proxy ‘blah’: sticking rules will not work correctly in multi-process mode.
[ALERT] 301/040546 (6326) : Peers section ‘prod’: peers referenced by sections running in different processes (3 different ones).

(this was conflating the https and http frontends)

There is a default bind-process 1 except for the 2 bind :443 lines.

I suggest dropping multi processes mode for multi threading.

nbproc 1
nbthread 5

Otherwise, if you want to retain this double termination with multiple processes, use a another http frontend dedicated to what comes in locally from the https termination (and trust it’s X-Forwarded-Proto header).

frontend https
bind *:443 ssl …
http-request set-header X-Forwarded-Proto https
server local 127.0.0.1:8080 send-proxy-v2 #<-- you would of course put the server backends in a dedicated backend

frontend https_to_http
bind 127.0.0.1:8080 accept-proxy

frontend http
 http-request set-header X-Forwarded-Proto http
 bind *:80

Moving to multithreading. solves the issue nicely.

And your solution close to my config also solves my issue.

Thank you very much!