Everyone deploys one, nobody has ever opened it up. The HALB — High Availability Load Balancing — is that appliance you drop in front of the Secure Gateways, configure in two screens, and forget. I wanted to know what was inside, and above all to answer a question every architect asks: is it a fragile black box, or is it properly locked down? Static, read-only analysis on a copy of the image: the original was never mounted or booted, and no command was ever run inside the guest. The verdict up front: it is far better engineered than a plain Linux box with HAProxy bolted on.
A reminder: what a HALB is for
The HALB spreads traffic across several RAS Secure Gateways and keeps them highly available. Two or more appliances, primary/secondary, share a virtual IP (VIP); if the primary goes down, the secondary takes over the VIP. The Parallels documentation describes the mechanism — VRRP between appliances, Gateway traffic on 80/443, SSL passthrough by default with optional offload — but stops at the surface. What follows is the concrete implementation.
The Russian doll
The first surprise, and not a small one: the appliance is not a plain Linux box with HAProxy on top. It is a three-layer stack, and each layer closes a door.
- A NixOS host, version 26.05 (Yarara). An immutable system, rebuilt deterministically: the Nix store is mounted read-only (
ro,nodev,nosuid), and several kernel security modules are enabled (Landlock, Yama, BPF). An immutable NixOS host means you don’t modify the system in place: there is no classic surface where you can drop something and make it persist. - A Docker engine running on that host.
- A Debian 12 container launched by Docker, holding the entire HALB data plane.
In other words, when you manage a HALB you are talking to an agent that lives inside a Docker container, itself sitting on a NixOS you never see. The design is elegant: the host stays minimal and immutable, and everything that moves is isolated in the container.

The container and the persistence model
The container runs with elevated privileges (--privileged, --network=host, extra system capabilities). That is necessary for a network appliance — it has to drive the interfaces, VRRP and the firewall — and it is a point an architect should keep in mind, but it is a deliberate, coherent choice for that role.
More importantly, the container is ephemeral (--rm). It keeps nothing: all persistence is pushed out to dedicated Docker volumes.
| Volume | Contents |
|---|---|
agentConfig | HALB agent configuration |
keepalivedConfig | generated Keepalived/VRRP configuration |
haproxyConfig | generated HAProxy configuration |
firewallConfig | firewall rules |
parallelsLogs / sysLogs | logs |
A direct and very useful takeaway: the base image is an empty shell. The VIPs, the backends, the real certificates are not in it — they are injected into these volumes when you configure your HALB Virtual Server. So there are always three distinct states:
| State | Meaning |
|---|---|
| Shipped | present in the image template, generic |
| Generated | produced during configuration, in the volumes |
| Confirmed in the lab | actually observed on a test appliance |
HALBAgent, the conductor
The heart of the system is a Parallels binary, 2XHALBAgent, which runs continuously and always restarts. It is not a mere watchdog: it is the one that generates the configurations. It carries the Keepalived and HAProxy templates and writes them into the volumes from the parameters you enter in the RAS console:
- a full Keepalived
vrrp_instance— VIP, priority, advertisement interval, authentication — with a script that watches HAProxy; - the HAProxy frontends and backends to your Gateways, with the health-check interval;
- the reference to the offload certificate, when you enable TLS termination.
This is the piece that links the console you know to the Linux you never see. And it is also why you don’t tinker with a HALB by hand: the config is generated, not edited. If you change a file inside the container, the agent rewrites it.
Real HA: Keepalived + HAProxy
The normal mode is the classic pair Keepalived (VRRP) for the VIP failover, HAProxy for the load balancing. Keepalived periodically runs a health-check that verifies HAProxy is present and that its configuration exists. If HAProxy disappears, the VIP can fail over.
An interesting point for understanding recovery times: there is no Docker healthcheck at the container level. Supervision relies on systemd, Docker and that Keepalived health-check. A container-alive-but-data-plane-degraded state is therefore detected indirectly — a good thing to test if you want to measure your real failover times.
IPVS, the ghost mode
The appliance also ships ipvsadm and the IPVS features, but in the delivered base the rules are empty and automatic startup is disabled. IPVS looks kept as a capability or for historical compatibility, not as the active path: the default load balancing is HAProxy in TCP mode.
What closes the doors
This is where the appliance earns its well built. Beyond the immutable host, several choices point the same way:
- The effective firewall observed in the lab is deny by default (DROP policy), opening only what is needed — VRRP, the Gateway ports and the documented configuration port. No gaping surface.
- The container persists nothing: no state that piles up, no configuration drift.
- The configuration is generated, not editable: less room for human error or a rogue change.
- SSH access is temporary, not permanent. The agent can open an SSH window for support from the console, but it closes by itself after a short while. A service door that locks itself, rather than SSH left open all the time.
- Modern TLS on the HAProxy side: TLS 1.2 minimum, up-to-date 1.3 suites (ECDHE/AES-GCM, ChaCha20), tickets disabled. The appliance even carries an enableable FIPS configuration.
No appliance is perfect, and good hygiene stays on your side — regenerate the identities (certificates, SSH host keys) on any clone, restrict network access to the configuration port, and treat the support bundle as sensitive data. But the foundation itself is serious.

The support bundle
One last thing worth knowing: the agent can produce a support bundle gathering the HAProxy/Keepalived configuration, firewall state, interface and IP information, and logs. Very handy for diagnostics — but it is the full snapshot of your appliance, to handle with care before sending it anywhere.
What it changes for us
- The HALB is an immutable Docker appliance, not a classic Linux server. You don’t log in to have a look: everything goes through the agent and the console.
- The config lives in volumes, not in the image. A clone does not carry over your configuration — and remember to regenerate the identities on any clone.
- Recovery depends on Keepalived and a process health-check. For reliable failover figures, test the partial states, not just powering off the primary.
- The default mode is L4 TLS passthrough. Offload is an explicit choice, with its own certificate.
Method and ethics
This analysis is static, offline and non-destructive. The original image was neither mounted writable nor booted; everything was done on a working copy. No secret — key, password, certificate, raw log, IP address, VRRP value or real topology — is reproduced here. The goal is to document the product’s architecture and generic mechanisms, not anyone’s configuration.
