Skip to main content
Security Engine version:
Version: Next

CrowdSec WAF QuickStart for HAProxy (SPOA)

Protect web applications running behind HAProxy with CrowdSec's AppSec (WAF) Component, using the HAProxy SPOA remediation component to forward HTTP requests.

Prerequisites

Make sure the following are already done on the machine running HAProxy (each is a single-page install guide):

  1. CrowdSec Security Engine installed and running — see the Linux quickstart.
  2. HAProxy already running and proxying your application(s).
  3. HAProxy SPOA bouncer (crowdsec-haproxy-spoa-bouncer) installed and registered against the CrowdSec LAPI — see the SPOA bouncer guide.

1. Install the AppSec rule collections

sudo cscli collections install \
crowdsecurity/appsec-virtual-patching \
crowdsecurity/appsec-generic-rules

This pulls the appsec-virtual-patching collection (rules for known CVEs, auto-updated daily) and the appsec-generic-rules collection (common attack patterns), plus the default AppSec configuration.

2. Turn on the AppSec Component

Create the acquisition file, then restart CrowdSec:

sudo mkdir -p /etc/crowdsec/acquis.d
sudo tee /etc/crowdsec/acquis.d/appsec.yaml > /dev/null <<'EOF'
appsec_configs:
- crowdsecurity/appsec-default
labels:
type: appsec
listen_addr: 127.0.0.1:7422
source: appsec
EOF
sudo systemctl restart crowdsec

Keep listen_addr on 127.0.0.1 — the AppSec Component must only be reachable from your reverse proxy.

3. Enable AppSec forwarding in the SPOA bouncer

Edit /etc/crowdsec/bouncers/crowdsec-spoa-bouncer.yaml and add the appsec_url plus the appsec block under your host(s):

/etc/crowdsec/bouncers/crowdsec-spoa-bouncer.yaml
# AppSec (WAF forwarding)
appsec_url: "http://127.0.0.1:7422"
appsec_timeout: "200ms"

hosts:
- host: "*"
appsec:
always_send: false

Restart the bouncer:

sudo systemctl restart crowdsec-spoa-bouncer

If AppSec runs on a different host (or in containers), update appsec_url to the correct reachable address.

4. Verify

Hit an endpoint that should trip an AppSec rule (adjust the URL to match your HAProxy frontend):

curl -I http://<your-haproxy-url>/.env

You should get an HTTP/1.1 403 Forbidden response.

Check that CrowdSec recorded the block:

sudo cscli metrics show appsec
What just happened?
  1. curl hit HAProxy at /.env.
  2. HAProxy forwarded the request to the SPOA remediation component.
  3. The bouncer queried the AppSec Component at appsec_url.
  4. The request matched the vpatch-env-access rule.
  5. AppSec answered 403; HAProxy blocked the request.

AppSec limitations with HAProxy SPOA

HAProxy SPOA forwarding is constrained by HAProxy/SPOE/SPOA mechanics:

  • Request bodies are only available if you enable buffering (option http-buffer-request) and must fit within tight size limits (commonly capped at ~50 KB).
  • When the body is too large (uploads, large JSON, etc.), you typically fall back to a "no-body" SPOE group, which means body-dependent WAF rules cannot match.
  • This is not full streaming inspection: SPOA works with what HAProxy can capture within buffer/frame limits.

CrowdSec AppSec is a single source of truth for rules — you can point multiple WAF-capable integrations at the same AppSec endpoint so rule updates stay in sync.

Recommended layered approach:

  • Use HAProxy SPOA for edge enforcement (IP/range/country decisions, ban/captcha) and lightweight WAF evaluation when the request fits within the configured limits.
  • Put a full-featured L7 proxy/WAF-capable integration downstream (or protect the app directly) when you need deeper inspection of large bodies, file uploads, or application-specific request parsing. Examples:

Next steps