Skip to main content
Version: Next

CrowdSec WAF QuickStart for HAProxy (SPOA)

Objectives

Set up the AppSec Component to protect web applications running behind HAProxy using the HAProxy SPOA remediation component.

You will:

  • Enable CrowdSec AppSec (WAF) in the Security Engine.
  • Install and configure crowdsec-haproxy-spoa-bouncer so HAProxy can forward HTTP requests to AppSec.
  • Validate everything by triggering a test detection.

Prerequisites

  1. If you're new to the AppSec Component or Web Application Firewalls, start with the Introduction.
  2. It's assumed that you have already installed:

If you already completed the General Setup (collections + acquisition), skip to Remediation Component Setup.

AppSec Component Setup

Collection installation

Install the main AppSec rule collections:

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

These collections provide virtual patching (CVE rules), generic WAF detections, and the default AppSec configuration.

Setup the acquisition

Create /etc/crowdsec/acquis.d/appsec.yaml (see the AppSec datasource for the full reference):

/etc/crowdsec/acquis.d/appsec.yaml
appsec_configs:
- crowdsecurity/appsec-default
labels:
type: appsec
listen_addr: 127.0.0.1:7422
source: appsec

Restart CrowdSec:

sudo systemctl restart crowdsec

Do not expose the AppSec Component to the internet. It should only be reachable from your reverse proxy.

Remediation Component Setup

Install and configure the HAProxy SPOA bouncer

Read here how to install the SPOA remediation component: HAProxy SPOA remediation component docs.

Once the bouncer is installed and able to talk to CrowdSec LAPI, you only need to enable AppSec forwarding.

Enable AppSec forwarding in the bouncer (YAML)

In /etc/crowdsec/bouncers/crowdsec-spoa-bouncer.yaml, configure the AppSec endpoint the bouncer should query for WAF evaluation:

/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.

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

  • Request bodies are only available if you enable buffering (option http-buffer-request) and they must fit within tight size limits (commonly capped at ~50KB in examples).
  • 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.
  • You are not doing full “streaming” inspection: SPOA works with what HAProxy can capture and send to the agent within buffer/frame limits.

CrowdSec AppSec is still a single “source of truth” for rules/config: you can point multiple AppSec-capable integrations to the same AppSec endpoint so rule updates stay in sync across your infrastructure.

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 of AppSec-capable integrations include:

Testing the AppSec Component + Remediation Component

Adjust the URL below to match your HAProxy frontend (HTTP/HTTPS, port, hostname).

If you try to access http(s)://<your-haproxy-url>/.env, your request should be blocked:

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

appsec-denied

You can also check AppSec metrics:

sudo cscli metrics show appsec

Explanation

What happened in the test above is:

  1. You requested /.env through HAProxy.
  2. HAProxy forwarded the request to the SPOA remediation component (SPOE/SPOA).
  3. The remediation component queried the AppSec Component at appsec_url.
  4. The request matched the AppSec rule to detect .env access.
  5. AppSec returned a blocking action (HTTP 403) to the remediation component.
  6. HAProxy blocked the request.

Next steps