Coraza WAF via SPOE: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
 
(4 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
 
===Was ist das?===
 
===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.
 
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===
 
===Schaubild===
{{#Coraza WAF}}
+
{{#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 coraza-spoa ./...
+
go build -o /usr/local/bin/coraza-spoa .
cp coraza-spoa /usr/local/bin/
+
cd /
 
</syntaxhighlight>
 
</syntaxhighlight>
  
===OWASP Core Rule Set herunterladen===
+
;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.
 
 
<syntaxhighlight lang="bash">
 
mkdir -p /etc/coraza/crs
 
git clone https://github.com/coreruleset/coreruleset.git /etc/coraza/crs
 
cp /etc/coraza/crs/crs-setup.conf.example /etc/coraza/crs/crs-setup.conf
 
</syntaxhighlight>
 
  
 
===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.conf
+
*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="text">
+
<syntaxhighlight lang="yaml">
Include /etc/coraza/crs/crs-setup.conf
+
bind: 127.0.0.1:9000
Include /etc/coraza/crs/rules/*.conf
+
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>
  
*mkdir -p /var/log/coraza
+
;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="text">
+
<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.conf
+
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/spoe-coraza.conf
+
*nano /etc/haproxy/coraza.cfg
  
 
<syntaxhighlight lang="text">
 
<syntaxhighlight lang="text">
[config]
+
[coraza]
  spoe-agent coraza
+
spoe-agent coraza-agent
     messages   coraza-req
+
     messages       coraza-req
     option     var-prefix      coraza
+
     option         var-prefix      coraza
     timeout     hello          100ms
+
    option          set-on-error    error
     timeout     idle            30s
+
     timeout         hello          2s
     timeout     processing      500ms
+
     timeout         idle            2m
     use-backend coraza_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
  
  spoe-message coraza-req
 
    args        src                    method=method    path=path    query=query    ver=req.ver    hdrs_bin=req.hdrs.bin    body_size=req.body_size    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:
  
<syntaxhighlight lang="text">
 
frontend ft_https
 
    # ... bestehende Einträge ...
 
    filter spoe engine coraza config /etc/haproxy/spoe-coraza.conf
 
    http-request deny deny_status 403 if { var(txn.coraza.action) -m str "deny" }
 
</syntaxhighlight>
 
  
Backend für den Coraza-Agent hinzufügen:
+
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>
 +
 
  
<syntaxhighlight lang="text">
+
;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.
backend coraza_backend
 
    server coraza 127.0.0.1:9000
 
</syntaxhighlight>
 
  
 
===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
  
Audit-Log beobachten:
+
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 separater cp-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
chown und chmod sind zwingend – coraza-spoa läuft als User haproxy und 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 in haproxy.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 tcp ist zwingend – ohne das schlägt der Config-Check fehl. alpn http/1.1 in 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):

Erwartet: HTTP 403

XSS-Test:

Erwartet: HTTP 403

Logs beobachten:

  • journalctl -fu coraza-spoa
  • tail -f /var/log/coraza/audit.log