A load balancer that gets out of the way
SSLB3 is my open source L4 and L7 load balancer and Kubernetes ingress controller, written in Rust. It terminates TLS, routes HTTP/1.1, HTTP/2 and HTTP/3, runs Lua where you want a decision made in code — and hands a plain TCP service to the kernel when it has nothing to add.
Two ways to start
On Kubernetes it is an ingress controller. On a host it is a daemon with a configuration file, and a hardened systemd unit ships with it. Neither needs the other.
Kubernetes, with Helm
shell
helm install sslb3 \ oci://docker.hacking.hu/public/sslb3-ingress \ --namespace sslb3 --create-namespace
A host, with systemd
shell
cargo build --release -p sslb3 install -m 0644 crates/sslb3/systemd/sslb3.service \ /etc/systemd/system/ systemctl enable --now sslb3
What it does
HTTP/1.1, HTTP/2 and HTTP/3
All three served from the same configuration, with HTTP/3 over QUIC on the same port number as TLS. Requests are parsed and routed in Rust rather than handed to a script.
Layer 4 and layer 7
Route on host and path where the protocol allows it, and copy bytes where it does not. A TCP or UDP service needs no request to be understood.
Embedded Lua
LuaJIT for the decisions worth expressing in code: routing, per-request logic, and a session script that can own a connection outright. Optional, and off unless configured.
Kubernetes ingress controller
Watches Ingress and L4Ingress objects and configures itself. The controller runs as a sidecar, so scaling is a replica count rather than a fan-out problem.
Health checking that means it
Backends are checked and taken out of rotation on their own schedule, per farm. A backend the kernel is forwarding to is still checked here — that is the job SSLB3 keeps.
Intrusion detection
Two detectors feeding one block list: connection rates at accept, and request-shaped signals inside the HTTP module. Every threshold off by default, deliberately.
Kernel fast path
A plain layer 4 service can be handed to nftables or IPVS with SSLB3 supervising rather than forwarding. Reported per service, with the reason each one stayed.
Metrics and a live statistics page
Thirty-four Prometheus metric families and a statistics page that updates over a WebSocket, both built in. Rendered from live state when asked, so there is no second set of counters to drift.
Careful about privilege
Binds privileged ports, drops every capability, then verifies it cannot regain them. The one component that needs CAP_NET_ADMIN is a separate process with no Lua and no listener.
How it is arranged
One process. Clients on one side, a health-checked serverfarm on the other, and everything in between decided before the first byte moves.
It knows when not to be there
A plain TCP passthrough gains nothing from a proxy in the middle: SSLB3 would accept a connection, open a second one, and copy bytes to do what the kernel already does. So where a service is only that, it is handed to nftables or IPVS — and SSLB3 keeps the work only it can do: health checking with real semantics, deciding which backends exist, and reporting what the kernel is carrying.
Nothing about it can break a service. The fallback is not code, it is the absence of a rule.
How the fast path decides →Running it on Kubernetes
Ingress objects for HTTP, an L4Ingress resource for TCP and UDP, TLS from Secrets, and a Helm chart that exposes every setting worth changing.