Skip to content

maxuru ~ % cat haproxy

Hardening HAProxy

HAProxy is unusual on this site: it is supposed to be exposed. A load balancer that nothing can reach is not doing its job, so “close the port” is not the shape of the advice here. The exposures that matter are the two side doors — the runtime API socket and the stats page — and the fact that HAProxy sits between two HTTP parsers that have to agree with each other.

That last point is where its real vulnerability history lives. Almost every serious HAProxy CVE of the last five years has been a request smuggling bug: HAProxy and the backend disagreeing about where one request ends and the next begins. See request smuggling.

Start here, because HAProxy has no fork story but it has a version lag story, and the difference between branches is large.

Terminal window
haproxy -vv

Branches alternate: even numbers are LTS (five years of maintenance), odd numbers get 12–18 months.

Branch Released Status
3.4 June 2026 Current LTS
3.3 November 2025 Stable, shorter support
3.2 May 2025 LTS
3.0 May 2024 LTS
2.8 May 2023 LTS, critical fixes only
2.6 May 2022 LTS, critical fixes only

Distribution packages routinely sit several branches behind, which matters more here than for most software: the configuration language changed materially at 2.1, and options that hardening guides still recommend have been removed outright. See directives removed in 2.1.

You may also be running HAProxy without having chosen it. OpenShift’s default router is HAProxy, and the Kubernetes HAProxy Ingress Controller wraps it. In those cases the configuration is generated for you, and the controls below apply to the controller’s settings rather than to a file you edit by hand.

HAProxy is GPLv2 at its core, with LGPL on the exportable headers so that non-GPL modules can be built against them. HAProxy Enterprise is a separate commercial product from HAProxy Technologies; the community version is not crippled, and nothing on this checklist requires a licence.

Terminal window
/etc/haproxy/haproxy.cfg

Sections are global (process-wide: user, chroot, TLS defaults, the runtime socket), defaults, frontend (what listens), backend (where it goes), and listen (both at once).

Check the file before you load it:

Terminal window
haproxy -c -f /etc/haproxy/haproxy.cfg

This catches syntax errors and removed directives, but it will not tell you that a security setting is missing — an insecure config is a valid config.

HAProxy reloads without dropping connections, which is one of the reasons it is worth configuring properly rather than fearing changes:

Terminal window
sudo systemctl reload haproxy

A reload starts a new worker and lets the old one finish its in-flight requests. Prefer reload to restart; a restart is what drops traffic.