Coraza SPOA is a system daemon which brings the Coraza Web Application Firewall (WAF) as a backing service for HAProxy. It is written in Go, Coraza supports ModSecurity SecLang rulesets and is 100% compatible with the OWASP Core Rule Set v4.
HAProxy includes a Stream Processing Offload Engine SPOE to offload request processing to a Stream Processing Offload Agent (SPOA). Coraza SPOA embeds the Coraza Engine, loads the ruleset and filters http requests or application responses which are passed forwarded by HAProxy for inspection.
The command make will compile the source code and produce the executable file coraza-spoa.
When you need to re-compile the source code, you can use the command make clean to clean the executable file.
The example configuration file is config.yaml.default, you can copy it and modify the related configuration information. You can start the service by running the command:
coraza-spoa -config /etc/coraza-spoa/coraza.yaml
You will also want to download & extract the OWASP Core Ruleset (version 4+ supported) to the /etc/coraza-spoa directory.
Configure HAProxy to exchange messages with the SPOA. The example SPOE configuration file is coraza.cfg, you can copy it and modify the related configuration information. Default directory to place the config is /etc/haproxy/coraza.cfg.
# /etc/haproxy/coraza.cfg
spoe-agent coraza-agent
...
use-backend coraza-spoa
spoe-message coraza-req
args app=str(sample_app) id=unique-id src-ip=src ...
event on-frontend-http-requestThe application name from config.yaml must match the app= name, or the default_application will be used.
The backend defined in use-backend must match a haproxy.cfg backend which directs requests to the SPOA daemon reachable via 127.0.0.1:9000.
Instead of the hard coded application name str(sample_app) you can use some HAProxy variables. For example, frontend name fe_name.
Configure HAProxy with a frontend, which contains a filter statement to forward requests to the SPOA and deny based on the returned action. Also add a backend section, which is referenced by use-backend in coraza.cfg.
# /etc/haproxy/haproxy.cfg
frontend web
filter spoe engine coraza config /etc/haproxy/coraza.cfg
...
http-request deny deny_status 403 hdr waf-block "request" if { var(txn.coraza.action) -m str deny }
...
backend coraza-spoa
mode tcp
server s1 127.0.0.1:9000A comprehensive HAProxy configuration example can be found in docs/config/haproxy.cfg.
Because, in the SPOE configuration file (coraza.cfg), we declare to use the backend coraza-spoa to communicate with the service, so we need also to define it in the HAProxy file:
- Build the coraza-spoa image
docker-compose build - Run haproxy, coraza-spoa and a mock server
docker-compose up - Perform a request which gets blocked by the WAF:
curl http://localhost:4000/\?x\=/etc/passwd
