TransWikia.com

HAProxy as selective forward proxy and load balancer

Server Fault Asked by Brian Sidebotham on December 18, 2021

I’m looking at doing some sidecar proxying. At the moment we have squid proxies as internet proxies and haproxy successfully load balancing those proxy connections.

What I want to do though is separate out some internal services for local load balancing. All are TLS.

Therefore if the connect http request has a specific domain name, I’d like to use a different backend. But at the moment I cannot figure out how to do this.

This works fine:

curl -v -x http://127.0.0.1:5000 https://google.com

Going to our squid forward proxies successfully. But the following does not use the alternative backend for out git servers:

curl -v -x http://127.0.0.1:5000 https://git.business.dom

I’ve tried matching the domain name on the incoming request, but I can’t get a match. I also cannot see any other way of matching for the URL in a HTTP CONNECT method request.

This always ends up getting routed to the default backend squid proxies

frontend main
    mode http
    bind 127.0.0.1:5000

    acl connect_git req.payload(0,0) -m sub git.business.dom
    use_backend git if connect_git

    default_backend             forward_internet_proxies

backend git
    mode http
    option httpclose
    option forwardfor header X-Client
    option forwardfor
    balance roundrobin
    http-check expect rstatus (2..|3..)
    server git1 git1.business.dom:443 weight 1 ssl verify none
    server git2 git2.business.dom:443 weight 1 ssl verify none

backend forward_internet_proxies
    balance     roundrobin
    mode http
    server proxy1 192.168.1.220:3128 check
    server proxy2 192.168.1.221:3128 check

One Answer

The dumb thing is, the HTTP CONNECT method is just that - a plain HTTP connect request. This includes a host header which can be matched to select the backend.

HAProxy also has a pre-defined ACL for the CONNECT method so that can also be used.

The confusion came because of using -i git.business.dom but the host header contains the domain and port number for the connect. So we need to match -i git.business.dom:443 or else use the -m sub option instead.

So we end up with:

    acl githost hdr(host) -i git.business.dom:443
    use_backend git if githost METH_CONNECT

This would require the git backend servers to handle the HTTP CONNECT request, otherwise this will not work.

If you're using nginx then you can use a plugin to enable support of the HTTP CONNECT request.

Answered by Brian Sidebotham on December 18, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP