Coraza WAF via SPOE: Unterschied zwischen den Versionen
(Die Seite wurde neu angelegt: „===Was ist das?=== Coraza ist eine moderne WAF-Engine (Go), die das OWASP Core Rule Set (CRS) ausführt. Die Integration in HAProxy erfolgt über SPOE – dens…“) |
|||
| (5 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 2: | Zeile 2: | ||
Coraza ist eine moderne WAF-Engine (Go), die das OWASP Core Rule Set (CRS) ausführt. Die Integration in HAProxy erfolgt über SPOE – denselben Mechanismus wie bei CrowdSec. | Coraza ist eine moderne WAF-Engine (Go), die das OWASP Core Rule Set (CRS) ausführt. Die Integration in HAProxy erfolgt über SPOE – denselben Mechanismus wie bei CrowdSec. | ||
| − | + | ===Schaubild=== | |
| + | {{#drawio:Coraza WAF}} | ||
===Installation des SPOE-Agents=== | ===Installation des SPOE-Agents=== | ||
| + | Coraza läuft als eigenständiger Prozess neben HAProxy. Das Binary wird direkt aus dem Quellcode gebaut – Go ist dafür erforderlich. | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
| − | apt install golang git | + | apt install -y golang-go git |
| − | |||
git clone https://github.com/corazawaf/coraza-spoa.git /opt/coraza-spoa | git clone https://github.com/corazawaf/coraza-spoa.git /opt/coraza-spoa | ||
cd /opt/coraza-spoa | cd /opt/coraza-spoa | ||
| − | go build -o | + | go build -o /usr/local/bin/coraza-spoa . |
| − | + | cd / | |
</syntaxhighlight> | </syntaxhighlight> | ||
| − | + | ;Hinweis: <code>./...</code> funktioniert hier nicht, da das Repo mehrere Packages enthält. Das Binary landet direkt unter <code>/usr/local/bin/</code> – kein separater <code>cp</code>-Schritt nötig. | |
| − | |||
| − | < | ||
| − | |||
| − | |||
| − | cp / | ||
| − | |||
===Coraza-Konfiguration=== | ===Coraza-Konfiguration=== | ||
| + | Die Konfiguration erfolgt als YAML-Datei. Die OWASP-Regeln (<code>@owasp_crs/</code>) sind im Binary eingebaut – ein separater CRS-Clone ist nicht nötig. | ||
| − | *nano /etc/coraza/coraza. | + | *mkdir -p /etc/coraza-spoa |
| + | *mkdir -p /var/log/coraza | ||
| + | *chown haproxy:haproxy /var/log/coraza | ||
| + | *chmod 750 /var/log/coraza | ||
| + | *nano /etc/coraza-spoa/coraza-spoa.yaml | ||
| − | <syntaxhighlight lang=" | + | <syntaxhighlight lang="yaml"> |
| − | + | bind: 127.0.0.1:9000 | |
| − | + | log_level: info | |
| + | log_file: /var/log/coraza/coraza-spoa.log | ||
| + | log_format: json | ||
| + | default_application: sample_app | ||
| − | SecRuleEngine On | + | applications: |
| − | SecRequestBodyAccess On | + | - name: sample_app |
| − | SecResponseBodyAccess On | + | directives: | |
| − | SecAuditLog /var/log/coraza/audit.log | + | Include @coraza.conf-recommended |
| − | SecAuditLogType Serial | + | Include @crs-setup.conf.example |
| − | SecAuditEngine RelevantOnly | + | Include @owasp_crs/*.conf |
| + | SecRuleEngine On | ||
| + | SecRequestBodyAccess On | ||
| + | SecResponseBodyAccess On | ||
| + | SecAuditLog /var/log/coraza/audit.log | ||
| + | SecAuditLogType Serial | ||
| + | SecAuditEngine RelevantOnly | ||
| + | response_check: false | ||
| + | transaction_ttl_ms: 60000 | ||
| + | log_level: info | ||
| + | log_file: /var/log/coraza/coraza-spoa.log | ||
| + | log_format: json | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| − | + | ;Hinweis: <code>chown</code> und <code>chmod</code> sind zwingend – coraza-spoa läuft als User <code>haproxy</code> und benötigt Schreibrecht auf das Log-Verzeichnis. | |
===SPOE-Agent als Systemd-Service=== | ===SPOE-Agent als Systemd-Service=== | ||
| + | Coraza-SPOA wird als eigener Systemd-Service betrieben. Bei einem Absturz startet systemd den Prozess automatisch neu. | ||
*nano /etc/systemd/system/coraza-spoa.service | *nano /etc/systemd/system/coraza-spoa.service | ||
| − | <syntaxhighlight lang=" | + | <syntaxhighlight lang="ini"> |
[Unit] | [Unit] | ||
Description=Coraza SPOA for HAProxy | Description=Coraza SPOA for HAProxy | ||
| Zeile 51: | Zeile 66: | ||
[Service] | [Service] | ||
| − | ExecStart=/usr/local/bin/coraza-spoa -config /etc/coraza/coraza. | + | ExecStart=/usr/local/bin/coraza-spoa -config /etc/coraza-spoa/coraza-spoa.yaml |
Restart=on-failure | Restart=on-failure | ||
User=haproxy | User=haproxy | ||
| Zeile 65: | Zeile 80: | ||
===SPOE-Konfiguration für HAProxy=== | ===SPOE-Konfiguration für HAProxy=== | ||
| + | SPOE (Stream Processing Offload Engine) ist der HAProxy-Mechanismus um Requests an externe Prozesse auszulagern. Die Konfigurationsdatei verbindet HAProxy mit dem laufenden Coraza-Prozess. | ||
| − | *nano /etc/haproxy/ | + | *nano /etc/haproxy/coraza.cfg |
<syntaxhighlight lang="text"> | <syntaxhighlight lang="text"> | ||
| − | [ | + | [coraza] |
| − | + | spoe-agent coraza-agent | |
| − | messages | + | messages coraza-req |
| − | option | + | option var-prefix coraza |
| − | timeout | + | option set-on-error error |
| − | timeout | + | timeout hello 2s |
| − | timeout | + | timeout idle 2m |
| − | use-backend | + | timeout processing 500ms |
| + | use-backend coraza-spoa | ||
| + | |||
| + | spoe-message coraza-req | ||
| + | args app=str(sample_app) id=unique-id src-ip=src src-port=src_port dst-ip=dst dst-port=dst_port method=method path=path query=query version=req.ver headers=req.hdrs body=req.body | ||
| + | event on-frontend-http-request | ||
| − | |||
| − | |||
| − | |||
</syntaxhighlight> | </syntaxhighlight> | ||
| + | |||
| + | ;Wichtig: Der Section-Header <code>[coraza]</code> muss exakt mit dem engine-Namen in <code>haproxy.cfg</code> übereinstimmen. Leerzeile am Dateiende ist zwingend, sonst meldet HAProxy ''Missing LF on last line''. | ||
===HAProxy Konfiguration erweitern=== | ===HAProxy Konfiguration erweitern=== | ||
| + | HAProxy übergibt jeden eingehenden Request via SPOE an Coraza. Liefert Coraza den Verdict <code>deny</code> zurück, blockiert HAProxy den Request mit HTTP 403 und zeigt die eigene Fehlerseite an. | ||
Im <code>frontend ft_https</code> ergänzen: | Im <code>frontend ft_https</code> ergänzen: | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | Backend für den Coraza- | + | frontend ft_https |
| + | <span style="color:#60a5fa">bind 10.88.2XX.41:443 ssl crt /etc/haproxy/ssl/revproxy.pem alpn http/1.1</span> | ||
| + | # ... bestehende Einträge ... | ||
| + | <span style="color:#a855f7">filter spoe engine coraza config /etc/haproxy/coraza.cfg</span> | ||
| + | <span style="color:#a855f7">http-request deny deny_status 403 if { var(txn.coraza.action) -m str deny }</span> | ||
| + | |||
| + | Backend für den Coraza-SPOA hinzufügen: | ||
| + | |||
| + | <span style="color:#a855f7">backend coraza-spoa</span> | ||
| + | <span style="color:#a855f7">mode tcp</span> | ||
| + | <span style="color:#a855f7">server coraza 127.0.0.1:9000</span> | ||
| + | |||
| − | < | + | ;Wichtig: <code>mode tcp</code> ist zwingend – ohne das schlägt der Config-Check fehl. <code>alpn http/1.1</code> in der bind-Zeile ist erforderlich damit HAProxy eigene Fehlerseiten ausliefert. |
| − | |||
| − | |||
| − | </ | ||
===Konfiguration testen und neu laden=== | ===Konfiguration testen und neu laden=== | ||
| − | |||
*haproxy -c -f /etc/haproxy/haproxy.cfg | *haproxy -c -f /etc/haproxy/haproxy.cfg | ||
*systemctl reload haproxy | *systemctl reload haproxy | ||
===Test=== | ===Test=== | ||
| − | |||
Klassischer WAF-Test mit einem OWASP-typischen Angriff (SQL Injection): | Klassischer WAF-Test mit einem OWASP-typischen Angriff (SQL Injection): | ||
| Zeile 120: | Zeile 141: | ||
Erwartet: HTTP 403 | Erwartet: HTTP 403 | ||
| − | + | Logs beobachten: | |
| + | *journalctl -fu coraza-spoa | ||
*tail -f /var/log/coraza/audit.log | *tail -f /var/log/coraza/audit.log | ||
Aktuelle Version vom 23. Mai 2026, 17:21 Uhr
Was ist das?
Coraza ist eine moderne WAF-Engine (Go), die das OWASP Core Rule Set (CRS) ausführt. Die Integration in HAProxy erfolgt über SPOE – denselben Mechanismus wie bei CrowdSec.
Schaubild
Installation des SPOE-Agents
Coraza läuft als eigenständiger Prozess neben HAProxy. Das Binary wird direkt aus dem Quellcode gebaut – Go ist dafür erforderlich.
apt install -y golang-go git
git clone https://github.com/corazawaf/coraza-spoa.git /opt/coraza-spoa
cd /opt/coraza-spoa
go build -o /usr/local/bin/coraza-spoa .
cd /
- Hinweis
./...funktioniert hier nicht, da das Repo mehrere Packages enthält. Das Binary landet direkt unter/usr/local/bin/– kein separatercp-Schritt nötig.
Coraza-Konfiguration
Die Konfiguration erfolgt als YAML-Datei. Die OWASP-Regeln (@owasp_crs/) sind im Binary eingebaut – ein separater CRS-Clone ist nicht nötig.
- mkdir -p /etc/coraza-spoa
- mkdir -p /var/log/coraza
- chown haproxy:haproxy /var/log/coraza
- chmod 750 /var/log/coraza
- nano /etc/coraza-spoa/coraza-spoa.yaml
bind: 127.0.0.1:9000
log_level: info
log_file: /var/log/coraza/coraza-spoa.log
log_format: json
default_application: sample_app
applications:
- name: sample_app
directives: |
Include @coraza.conf-recommended
Include @crs-setup.conf.example
Include @owasp_crs/*.conf
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess On
SecAuditLog /var/log/coraza/audit.log
SecAuditLogType Serial
SecAuditEngine RelevantOnly
response_check: false
transaction_ttl_ms: 60000
log_level: info
log_file: /var/log/coraza/coraza-spoa.log
log_format: json
- Hinweis
chownundchmodsind zwingend – coraza-spoa läuft als Userhaproxyund benötigt Schreibrecht auf das Log-Verzeichnis.
SPOE-Agent als Systemd-Service
Coraza-SPOA wird als eigener Systemd-Service betrieben. Bei einem Absturz startet systemd den Prozess automatisch neu.
- nano /etc/systemd/system/coraza-spoa.service
[Unit]
Description=Coraza SPOA for HAProxy
After=network.target
[Service]
ExecStart=/usr/local/bin/coraza-spoa -config /etc/coraza-spoa/coraza-spoa.yaml
Restart=on-failure
User=haproxy
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now coraza-spoa
SPOE-Konfiguration für HAProxy
SPOE (Stream Processing Offload Engine) ist der HAProxy-Mechanismus um Requests an externe Prozesse auszulagern. Die Konfigurationsdatei verbindet HAProxy mit dem laufenden Coraza-Prozess.
- nano /etc/haproxy/coraza.cfg
[coraza]
spoe-agent coraza-agent
messages coraza-req
option var-prefix coraza
option set-on-error error
timeout hello 2s
timeout idle 2m
timeout processing 500ms
use-backend coraza-spoa
spoe-message coraza-req
args app=str(sample_app) id=unique-id src-ip=src src-port=src_port dst-ip=dst dst-port=dst_port method=method path=path query=query version=req.ver headers=req.hdrs body=req.body
event on-frontend-http-request
- Wichtig
- Der Section-Header
[coraza]muss exakt mit dem engine-Namen inhaproxy.cfgübereinstimmen. Leerzeile am Dateiende ist zwingend, sonst meldet HAProxy Missing LF on last line.
HAProxy Konfiguration erweitern
HAProxy übergibt jeden eingehenden Request via SPOE an Coraza. Liefert Coraza den Verdict deny zurück, blockiert HAProxy den Request mit HTTP 403 und zeigt die eigene Fehlerseite an.
Im frontend ft_https ergänzen:
frontend ft_https
bind 10.88.2XX.41:443 ssl crt /etc/haproxy/ssl/revproxy.pem alpn http/1.1
# ... bestehende Einträge ...
filter spoe engine coraza config /etc/haproxy/coraza.cfg
http-request deny deny_status 403 if { var(txn.coraza.action) -m str deny }
Backend für den Coraza-SPOA hinzufügen:
backend coraza-spoa mode tcp server coraza 127.0.0.1:9000
- Wichtig
mode tcpist zwingend – ohne das schlägt der Config-Check fehl.alpn http/1.1in der bind-Zeile ist erforderlich damit HAProxy eigene Fehlerseiten ausliefert.
Konfiguration testen und neu laden
- haproxy -c -f /etc/haproxy/haproxy.cfg
- systemctl reload haproxy
Test
Klassischer WAF-Test mit einem OWASP-typischen Angriff (SQL Injection):
- curl -vk "https://revproxy.it2XX.int/?id=1'+OR+'1'='1"
Erwartet: HTTP 403
XSS-Test:
- curl -vk "https://revproxy.it2XX.int/?q=<script>alert(1)</script>"
Erwartet: HTTP 403
Logs beobachten:
- journalctl -fu coraza-spoa
- tail -f /var/log/coraza/audit.log
