I am exploring the use of HAProxy as a balancer in front of a set of web apis that run on IIS.

  • node1.myapp.mycompany.com
  • node2.myapp.mycomapny.com

We are currently using Host Headers to correctly resolve the right web application on IIS. For example, we may have otherapp.mycompany.com running on the same server/port, but using Host Headers IIS knows which one to serve up.

My initial attempt at HAProxy left me with 404 errors, because I was not including the host headers in my request, and so IIS was serving back the default site bound to the given IP, and not resolving by host name.

The fix left me with something like this:

frontend localnodes
    bind *:80
    mode http
    default_backend nodes

backend nodes
    mode http
    balance roundrobin
    option forwardfor
    reqirep ^Host: Host:\ node1.myapp.mycompany.com
    server web01 node1.myapp.mycompany.com:80

This works great for a single backend, but I am left scracthing my head on how to include the correct host headers depending on which backend is serving up the request:

backend nodes
    mode http
    balance roundrobin
    option forwardfor
    reqirep ^Host: Host:\ node1.myapp.mycompany.com
    server web01 node1.myapp.mycompany.com:80
    server web02 node2.myapp.mycompany.com:80

The above does not work whenever node2 is used because it doesn't resolve correctly in IIS (node2 in this case is on a different server, and therefore different IP. In fact, if they were running on the same server/ip I suspect the request work "work", but they would all be served by node1 per the host header).

  • Is it possible to set the host based on the url of the backend used to serve up the request?
  • If so, this implies my checks also need to provide the correct host header based on backend, how would that be done?

Edit: Am using HA-Proxy version 1.7.9 2017/08/18

Let me give this just a little more background. We used to have just myapp.mycompany.com serving up api requests. We need to expand it. Our clients will still call myapp.mycompany.com, but that will just point to the HAProxy, which will balance it out to node1.myapp.mycompany.com and node2.myapp.mycompany.com. Our current server configurations have us binding a single IP address on each server, so we use host headers to resolve.

  • Which version are you using? – gf_ Oct 4 '17 at 15:36
  • @gf_ 1.7.9 from 2017/08/18 – Matt Oct 4 '17 at 15:40
  • Do I understand correctly, that node{1,2}.myapp.mycompany.com are the HTTP host headers, the clients are using? If so, why is node{1,2} relevant, why is it not only myapp.mycompany.com? This would simplify things a lot, IMHO. – gf_ Oct 4 '17 at 15:43
  • So, from the clients perspective, they will be calling myapp.mycompany.com. However, the webapps themselves are hosted with the additional subdomain. This is hold over from the current networking structure where we bind multiple apps to the same IP/port and need the headers to differentiate. Does that answer your question? – Matt Oct 4 '17 at 15:51
  • @gf_ added some additional clarifying info in the question at the bottom – Matt Oct 4 '17 at 15:57
up vote 3 down vote accepted

I'm not sure if the following will work, and can't test right now, but maybe this is still helpful. (I'll have a look again later with some more time):

Solution 1 (people reported that this one doesn't work, therefore, please try the second solution first):

backend nodes
    mode http
    balance roundrobin
    option forwardfor
    http-request set-header Host node1.myapp.mycompany.com if { srv_id 1 }
    http-request set-header Host node2.myapp.mycompany.com if { srv_id 2 }
    server web01 node1.myapp.mycompany.com:80
    server web02 node2.myapp.mycompany.com:80

Solution 2:

backend nodes
    mode http
    balance roundrobin
    option forwardfor
    http-send-name-header Host
    server node1.myapp.mycompany.com node1.myapp.mycompany.com:80
    server node1.myapp.mycompany.com node2.myapp.mycompany.com:80
  • Thanks, your 2nd example did the trick for me. Couldn't get the first one to work, though I don't remember what the error was right off hand (I think something to do with the conditional expression). – Matt Oct 16 '17 at 18:49
  • @Matt Thanks.. could you still get the "proper" error message? I'm curious.. – gf_ Oct 16 '17 at 20:40
  • @gf_ none of these solutions work for me. In the first solution, it never sets the header. If I remove de if then it works but I have two backend servers so I need the if. The second solution does not add the Host and I get a 404 because IIS cannot find the right binding. Could you make Solution 1 work? – Rubanov Jul 6 at 15:25
  • @Rubanov I'm pretty sure this worked, for the question raised back then. If it doesn't for you, there might be differences. Please ask a new question giving details etc. – gf_ Jul 6 at 15:58
  • @gf_ the first solutions works if there is only one server. So when I do http-request set-header Host node1.myapp.mycompany.com I do not get a 404 and IIS correcty binds to right host. It is the srv_id variable that is not working. It is never equal to 1 or 2. I don't know what it is equal to but the acl is always false because it does not do the set-header. If you have no idea what might be wrong with srv_id then I will ask a new question. – Rubanov Jul 6 at 16:32

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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