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
check
s 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.
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:
Solution 2:
Note This one is officially not recommended. Read the comment on http-send-name-header: it has been reported that this directive is currently being used as a way to overwrite the Host header field in outgoing requests; while this trick has been known to work as a side effect of the feature for some time, it is not officially supported and might possibly not work anymore in a future version depending on the technical difficulties this feature induces... [Credits to rustyx.]
I want to complement gf_ answer. So the idea of his answer is to add a custom Host header which value is the source hostname itself. In solution one, basically, he set the header manually with a condition from
srv_id
thing.The second on shortcut the first solution by sending the name of the host as a Host header.
But in his solution, he doesn't mention that it only set-header, if the header is already there it can't replace the existing header, so if your case need to replace Host header, you can do somethinghing like this