Beta. Only nodes with Also offer beta versions ticked (Settings → Updates) are offered this. It replaces 2.0.0-beta.1 to beta.5, whose notes are folded in below.
2.0: address lists, rules with any-of and all-of, a rule wizard and a condition wizard, per-service rules, error pages, CrowdSec
Three issues from the same week (#19, #20, #21), and the reason this is a 2.0 rather than a 1.101: a rule's shape changed. Upgrade every node of a cluster before editing rules or services on the new one; a node still on 1.100 reads only the old shape, and a rule written in the new one would apply to it without its conditions.
CrowdSec (#21)
Sign-in › CrowdSec. Optional, and off until switched on. CrowdSec decides who is banned from what its agents see across the fleet; HAProxy asks about each visitor through a small local agent, the SPOA bouncer, and answers a banned address with a 403 page — or a captcha first (hCaptcha, reCAPTCHA, Cloudflare Turnstile). One API key (cscli bouncers add haproxy-manager on the CrowdSec host) serves every node; Test the LAPI connection says whether it is accepted.
The container image carries the bouncer, and so do nodes installed with install.sh or the Proxmox script. A node that lacks it — one installed or upgraded from the .deb or .rpm — installs it itself when the app starts, once, from CrowdSec's repository; install.sh --without-crowdsec marks a node that must not carry it, and the Install on this node button removes that mark. It stays stopped until CrowdSec is on and Apply runs, and is stopped again when CrowdSec is switched off. Every HTTP listener asks the bouncer before anything else is done for a request; Never ask about names address lists — the LAN — that are let through without a question; the 403 page is the one under Error Pages for 403 when there is one. Fail-open, by design: a bouncer that is down, slow or missing leaves requests alone and Apply says so.
Rules for a service alone
The publish wizard's new Rules section (and Rules on Backend Pools) picks rules — deny, headers, redirects, raw lines, with their conditions — that are acted on inside the service's pool, so they reach that service alone and never its neighbours on the same port. Routing rules belong on the listener, where the rule wizard puts them, and are not offered.
The rule wizard
Advanced › HAProxy › Rules › Rule wizard builds a rule in one dialog, read as a sentence: On these Public Services, When these conditions hold — typed in place, sorted into any-of and all-of, an existing one picked instead when you like — Then do this. The wizard makes the conditions, attaches the rule to the listeners and places it by how specific it is. Preview asks HAProxy: the result is checked with haproxy -c, the dialog shows the verdict and the generated lines, and a rule HAProxy would not load is refused on Save with HAProxy's own words.
The condition wizard
Advanced › HAProxy › Conditions › Condition wizard asks one test in words — what to look at, what it should be, whether to turn it around — and Try it takes a sample request (a host, a path, an address, a header value) and says whether the condition would match it, shows the acl line, and gives HAProxy's verdict. A raw ACL is left to HAProxy alone, and one it refuses is refused on Save; a test identical to an existing condition is reused.
Address lists (#19)
Advanced › HAProxy › Address Lists: a named set of networks. A service's Allowed networks, the networks that skip its sign-in, a source_list condition and CrowdSec's Never ask about can name a list. Edit the list and every service that names it follows at the next Apply. A list of more than forty networks is declared over several lines, since HAProxy reads at most 64 words from one.
Rules: any of these, and all of those (#19)
A rule tests two lists: Any of these (one must match) and All of these (every one must, with one of the first), written out as if host-tv lan || host-films lan. A rule saved before 2.0 still renders as it did; the editor opens it in the new shape. The wizard no longer throws away a condition added to a service's rule by hand, and such a condition now holds for every name the service answers to. A condition's value can hold several patterns separated by spaces, and matches any of them.
Error pages (#20)
Advanced › HAProxy › Error Pages: what visitors see when HAProxy itself answers with an error. A page serves one or more status codes, with {error_code} and {error_message} filled in; Load from file reads a local .html into the editor. Every node writes its pages to /etc/haproxy/error-pages/ before validating or applying. A page is used for every service, or only by the pools that pick it — in the publish wizard or on the Backend Pools page; a paused service answers with its 503 page too. HAProxy can only replace the responses it generates itself, and the whole response must fit its 16 kB buffer.
Fixed along the way
A node upgraded from 1.100 came up saying unapplied changes with nothing to apply. The applied marker is now carried over when the stored file lacks nothing but defaults — the CrowdSec section included.
After upgrading
Nothing to do on a single node. In a cluster, upgrade every node before editing rules or services, as above. CrowdSec is off until you switch it on.
Image: ghcr.io/avandeputte/haproxy-manager:2.0.0-beta.6