1

I have been trying to configure HAProxy to send traffic to different backend servers based on hostnames. I tried using the directions found in How to divert traffic based on hostname using HAProxy? but unfortunately am not having luck.

I am trying to have it so that if a client goes to bk1.domain.com:80, traffic is sent to the "backend1" backend. Similarly, if someone goes to bk2.domain.com:80, traffic should be sent to the "backend2" backend. All other traffic should be sent to the "default" backend. For clarification, domain.com, bk1.domain.com, bk2.domain.com all resolve to the same IP address.

Unfortunately, when going to bk1.domain.com or bk2.domain.com, the "default" backend is used for all requests. It seems that HAProxy is not recognizing the host headers and as a result is unable to forward requests to the appropriate backend.

Below is the current haproxy.cfg. Any help is appreciated.

global
    log 127.0.0.1   local0
    maxconn 4096
    user haproxy
    group haproxy
    daemon

defaults
    log     global
    retries 3
    option redispatch
    maxconn 2000
    timeout http-request 5s 
    timeout connect      5s
    timeout client       30s
    timeout server       10s

frontend all_clients
    bind 0.0.0.0:80
    acl back1 hdr(host) -i bk1.domain.com
    acl back2 hdr(host) -i bk2.domian.com
    use_backend backend1 if back1
    use_backend backend2 if back2
    default_backend default

backend default
    balance roundrobin
    server  a1 192.168.0.1:8080
    server  a2 192.168.0.2:8080
    server  a3 192.168.0.3:8080

backend backend1
    balance roundrobin
    server  b1 10.0.0.1:8080
    server  b2 10.0.0.2:8080

backend backend2
    balance roundrobin
    server  c1 172.16.0.1:8080
    server  c2 172.16.0.2:8080
6
  • Have you tried without the dots?
    – JamesRyan
    Jan 30, 2016 at 3:01
  • I just tried "acl back1 hdr_beg(host) -i bk1" without the period at the end and unfortunately all requests are still going to the "default" backend.
    – Ron F
    Jan 30, 2016 at 3:05
  • 1
    This pattern definately works, i'm using it. Try putting default_backend at bottom of section and all acls before use_backends. Try renaming the backends so they arnt the same as the text you match. try using 'hdr(host) -i bk1.domain.com'. Also try not repeating server names, you have 3 server1s currently, they might need to be unique. It will be something simple like that.
    – JamesRyan
    Jan 30, 2016 at 3:28
  • Thanks for your suggestions. I’ve seen this pattern used on multiple sites as well so I’m not sure why it is not working for me. I implemented each suggestion of yours one at a time, restarted haproxy each time and then checked to see if the problem was fixed. I even restarted the entire server. Unfortunately, after implementing everything, all requests are still being forwarded to the “default” backend. I have updated the original post with all your suggestions.
    – Ron F
    Jan 30, 2016 at 3:54
  • What happens if you take default_backend out altogether?
    – JamesRyan
    Jan 30, 2016 at 12:48

2 Answers 2

2

Old question, but the answer is simple: The string bk1.example.com:80 is not identical to the string bk1.example.com. Most - but not all - modern clients strip the port number from their host header before sending it, if it's the default port for the protocol.

If a client does send the port number explicitly in its host header, you need an additional ACL for that case unless you want to go the less secure route of using hdr_beg(Host).

In other words the correct syntax to catch both headers exactly might look something like this:

frontend all_clients
    bind 0.0.0.0:80
    acl back1 hdr(Host) -i bk1.domain.com
    acl back1 hdr(Host) -i bk1.domain.com:80
    acl back2 hdr(Host) -i bk2.domian.com
    acl back2 hdr(Host) -i bk2.domian.com:80
    use_backend backend1 if back1
    use_backend backend2 if back2
    default_backend default
0

snipped your code, and edited. what you need to do is define an acl, then route based on the acl:

frontend all_clients
    bind 0.0.0.0:80
    default_backend default
    acl back1 if hdr_beg(host) -i bk1.
    acl back2 if hdr_beg(host) -i bk2.
    use_backend bk1 if back1
    use_backend bk2 if back2
1
  • Your configuration produces errors as it does not appear to be valid syntax but I changed my original post to what I believe you were attempting to do. It is now also using the exact same configuration as posted in serverfault.com/questions/105824/…. Unfortunately, it still is not working properly.
    – Ron F
    Jan 30, 2016 at 2:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.