Load-balancing first sticky?

Hello,

Newbie here, but long-lapsed CCIE, so no stranger to all things networking.

I’ve been tasked with generating a VyOS configuration from a Sophos UTM config dump, due to the pending EOL of that platform, and Sophos not having a suitable replacement (understatement!).

So far not a lot of issues, but I’m stuck on the conversion of its reverse proxy config.

I’ve been looking at the load-balancing docs (haproxy) and from what I can see it should be suitable, but I have one scenario that I can’t map.

Sophos UTM has a balance mechanism called “hot standby”, which basically balances all traffic to the first backend defined (the “first” keyword in native haproxy config), always, until that backend is no longer available.

It is being used to redirect to a holding page informing the user of the fact the backend is not available for whatever reasons, with contact info etc. So there aren’t actually multiple backends, just one backend serving the site or service, and a generic http backend serving a single holding page.

It is possible to create something similar in VyOS, without having to resort to something like Caddy in a container (which I would like to avoid)?

Also, something else I couldn’t find, it is possible to define x509 certs in the config (as a string), instead of referring to PEM files which will have to be created seperately of the generated configuration?

So you want to loadbalance all clients to a single server until that no longer replies, then all queries should go to the 2nd server until the 1st server starts to reply again?

Regarding PEM vs in config the config for haproxy is slightly limited in VyOS. Workaround here is to run haproxy as a container to get full access to its syntax. Using official container from haproxy - Official Image | Docker Hub should be doable. Looking in haproxy docs it doesnt seem to support using PEM files from a config, only path on accessible storage.

No, not a single server.

The UTM config I’m currenly working on has about 75 reverse proxy entries ( = 75 different hostnames). Some backends serve multiple sites, some sites have multiple backends.

For the sites that have only one backend server, a second has been added as “hot standby”, which indeed only responds if the primary is down. It has a simple lighthttpd config on IP, so it responds on requests for all hostnames, and no matter which URL is requested, it responds with a single “sorry we’re down now” page.

So I have RP profiles for

  • site A, backend servers 1, 2 and 3
  • site B, backend servers 1 and 2
  • site C, backend 3 (and this one has hot-standby webserver as second backend)
    and so on.

The sole purpose of this hot-standby is to avoid connection errors or timeouts or hanging browser windows or some error from the load balancer (no idea what haproxy does when no backends are available) client-side if the backend goes down. If there is some other way to have haproxy respond with something useful (as in an HTML file) if no backends are available, fine by me, I’m open for alternatives.

And indeed, as soon as the LB probe detects the primary is back up, it switches back to it.

If I have to go the container route to implement the reverse proxy, I probably go for Caddy instead of Haproxy, I think that makes more sense, as it has much more web specific features.

The UTM imports certificates into its config repository, which are than written to disk by their UI (they use apache as RP btw, but I don’t want that overhead on the VyOS box, not even in a container.

So my programme for generating the VyOS config has to generate seperate files for de crt and ca, which then need to be copied over. Not a big issue, I can live with that, but not as clean as I would have liked.

What you are describing is HAProxy balance first combined with the backup keyword on the standby servers. In a standard HAProxy config it looks like this:

backend site_a
    balance first
    server srv1 10.0.0.1:80 check
    server srv2 10.0.0.2:80 check backup

With balance first, all traffic goes to the first available server in the list. The backup keyword means srv2 only receives traffic when all non-backup servers are down. When srv1 recovers, traffic automatically returns to it.

The VyOS HAProxy integration may not expose the “first” balance algorithm through the CLI config model though. If it only offers round-robin, leastconn, and source, then running HAProxy as a container with a full config file as Apachez suggested would be the way to go. You get the complete HAProxy syntax including balance first, backup servers, and native PEM certificate handling on the bind line with ssl crt /path/to/cert.pem.

For 75 reverse proxy entries that is probably cleaner anyway than trying to manage them all through VyOS CLI commands.

Was afraid of that, yeah, and was looking to avoid that, especially since haproxy is already running, and the issue is just CLI..

If I have to go the container route, I’d probably go for Caddy instead of HA proxy, so I have its Lets Encrypt support as well.

Any pointers on how to run HAproxy in a container instead of native?

Also, Sophos uses iptables load balancing, like so:
-A LOAD_BALANCING -d 172.18.5.10/32 -p tcp -m tcp --sport 1:65535 --dport 3306
-j ASG_BALANCE --balance_name REF_LB1
--balance_server 172.18.5.11,172.18.5.12,172.18.5.14
--balance_alg weight --balance_weight 100,100,0 --balance_persist
--balance_persist_size 4000 --balance_persist_time 900

(example of an LB rule for a MariaDB cluster.

I assume weights and presistence is something that isn’t implemented in the CLI either?

Something else I realised:

The VIP address in this case, 172.18.5.10, is just a random address. And I assume the haproxy listen-address must be an valid address defined on a local interface?

Or is the VyOS kernel setup to allow binding to non-existing IP addresses?