Trying to redirect 302. (Don't want Man-in the Middle proxy)


Scenario: exist on NGINX-1 and NGINX-2 (my backend, which are both reveres-proxy)

Client request from HAproxy, and it find the least busy server and send that request to that server (NGINX-1 or NGINX-2) BUT without staying in the middle.
I don’t want HAproxy to act as reverse-proxy and pull the data for the client (from the backend),
and then send the data to the client from the HAproxy server.
Instead, I want it to send the user directly to the edge server (nginx).

I assume to do so must use redirect 302?!

I’m trying to make HAproxy to do 2 things and i’m not sure how and if possible.

  1. Make HAproxy to do redirect to the backend servers, and not stay as “Man in the middle” between the client and the server.

  2. Make HAproxy Load-balance (send to the server with the least bandwidth) between the backends while always sending to the backends with redirect.

So after stage 3 (of the picture), HA doesn’t talk anymore with the client.
Is that possible, and if so how?

I appreciate any help!

First of I’ll try to reply to your actual question: I don’t think it’s actually feasible (possible) to make this load-based redirect, simply because HAProxy doesn’t know the actual load on your NGinx servers (as it would if it proxy for them).

Think about it: HAProxy sends four clients to NGinx-1 and three clients to NGinx-2 (in a round-robin fashion); now the clients are downloading ZIP’s of varying size at various bandwidths, therefore NGinx-1 (although was served four clients) might be the “least used” one.

There is no way in which HAProxy can know which client finished first.

Now, to tackle the real issue: why don’t you want HAProxy to load-balance your NGinx servers? Is there an actual reason?

You could at least load-balance the actual TLS connections in TCP mode, thus acting more as a router than as a proxy.

Thank you ciprian.craciun for your response.

  1. I wasn’t sure what is the mechanism for HAProxy of actually doing the loadbalance,
    now I understand it must be pass through it self to do so, so thanks for clearing that.

  2. The reason I want to “redirect” and not “proxy” is the topology I’m trying to achieve is one that I have 1 Storage server and many edge servers access the same content, because:

    a. All those edge(ngx) servers will be in different countries 
        and I want to direct users based on GeoIP.
    b. All  those edge(ngx) servers are going to be 10Gbps servers and the total traffic that will "pass" 
        the loadbalance will need to be able to handle 100Gbps+, so it will be my bottleneck.  
    c. I want it to be able to scale really good, just by adding more servers, and not to cut my 
        bandwidth in half because the load-balancer acting as proxy.
    d. Bandwidth on each edge server will be the first limit (so I dont need HAProxy to handle as 
        many connections, each edge will handle only 2000~4000 users)
    e. If I have more clients, all I need is to add just more edge (ngx) servers, and I don't worry about 
        adding more Load-Balancer servers as well.

Something like this:

When you say to load-balance the actual TLS connection, it still means that the traffic will go through it, since router is routing through 1 interface to the other. right?

I assume if HAProxy can’t do that, then I’ll need a solution like IPVS? (layer 4 load balance):

Thanks again :smiley:

I think you would be better served by a custom HTTP server written in something like Go that would implement the balancing logic.

However you could still try to use HAProxy using the following “hack”, which might just work:

  • create a frontend that receives the requests from the client (i.e. listens on public 80 and 443), and routes it to a “central” backend;
  • inside the “central” backend create as many server statements as you have NGinx servers, however as IP and port use 127.xx.yy.zz:8080 (just put random numbers in there, or replace reuse the last three digits of the public IP of the real NGinx) and use the agent-check feature to configure a weight for this server direct-proportional to the load from your taget Nginx; (also configure the backend to use a load-balance mechanism based on this weight;)
  • now the tricky part: create another frontend that listens on (which based on how lo works on Linux would receive requests also for any 127.xx.yy.zz. IP;)
  • inside this frontend create a few ACL’s, one for each 127.* IP to identify on which IP it came using the dst sample; (i.e. acl dst_127_xx_yy_zz dst 127.xx.yy.zz);
  • now for each of those ACL’s create a http-requset redirect location https://NGINX-z/%[path] if dst_127_xx_yy_zz;

However as said perhaps a custom Go server (perhaps behind HAProxy) would be better, as the downside to the approach above requires that you re-create the HAProxy configuration each time you add (or remove) a new NGinx instance.

That being said, please note that you could use HAProxy also to identify the country the client IP comes from (by using maps), thus you could have the redirection HAProxy’s hosted only in one datacenter and still maintain your geographically distributed servers.