5

Is it possible to set a dynamic variable which will hold the content of HTTP header e.g. Host/X-Forwarded-Host and would be used later in ACLs?

frontend web1
  # ...
  set-var s1(Host)
  acl site1 hdr_end(host) -i %[s1]
  # ...
  use_backend %[s1] if site1
mwp
  • 8,217
  • 20
  • 26
aristit
  • 51
  • 1
  • 1
  • 4

1 Answers1

5

You have a mix of techniques here. You don't need variables at all to set ACLs based on the host address and select a backend using those ACLs. That would be something simple like:

frontend web1
  # ...
  acl site1 hdr(host) -i example.com
  acl site2 hdr(host) -i example.net
  # ...
  use_backend com if site1
  use_backend net if site2

Is that all you're trying to do, or are you trying to accomplish something more sophisticated?

UPDATE: Here's how to select a backend based on the Host header:

frontend web1
  # ..
  http-request set-var(req.s1) req.hdr(Host),field(1,:),lower,regsub(\.,_,g)
  use_backend %[var(req.s1)]

backend example_com
  # ..

backend example_net
  # ..

This sets a variable that is valid in the context of the request, using the value of the Host header lowercased and with periods replaced with underscores. Actually, you don't even need a variable:

frontend web1
  # ..
  use_backend %[req.hdr(Host),field(1,:),lower,regsub(\.,_,g)]

HAproxy will return 503 if a backend that matches the Host header cannot be found. You can set a default_backend if you want such requests to go somewhere else (I tested this and it works in 1.6.3, at least).

mwp
  • 8,217
  • 20
  • 26
  • It is not about a list of few app/sites. There might be multiple unknown "backends". All requests should be redirected dynamically to the HTTP host header(IP/domain). – aristit Sep 05 '16 at 19:36
  • @aristit Well, all of the backends must be enumerated in the haproxy.cfg at runtime, so you can't have any "unknown" backends. You will need to check the Host header against a list of known backends to prevent HAproxy from trying to use a backend that doesn't exist. The larger problem is I'm not sure you can interpolate a variable as the first argument to `use_backend`. I'll play around with it... – mwp Sep 05 '16 at 19:41
  • @aristit That wasn't as bad as I thought it was going to be! Take a look and see if this meets your needs. – mwp Sep 05 '16 at 20:17
  • This scenario helped me, thanks ! The only thing I was worried about and you also mentioned it: it's not possible to use variable as a backend name/destination_server – aristit Sep 06 '16 at 10:42
  • @aristit Happy to help! Please check the answer if it was helpful to you. :) – mwp Sep 07 '16 at 20:17
  • Hi @nwp, thanks for your answer. It's being useful for me (+1), but I have a question you may be able to help: How could you test that those commands which involve some logic like "regex" are actually taking the expected values? – Héctor Valverde Nov 22 '16 at 10:38
  • 1
    @HéctorValverdePareja Unfortunately, there's no good way (or at least none that I know of) to test HAProxy configuration files. I will usually run HAProxy in debugging mode (i.e. with `-d`) and send a few requests to test the desired behavior. – mwp Nov 22 '16 at 21:24