WAF mit HAProxy und Coraza Rocky: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
 
(13 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
= WAF-Demo: HAProxy mit Coraza auf Rocky Linux =
+
== WAF-Demo: HAProxy mit Coraza auf Rocky Linux ==
  
== Ziel ==
 
 
WAF mit HAProxy und Coraza (OWASP CRS) vor www.it2XX.int, TLS-Terminierung auf revproxy.it2XX.int.
 
WAF mit HAProxy und Coraza (OWASP CRS) vor www.it2XX.int, TLS-Terminierung auf revproxy.it2XX.int.
 +
==Maschine==
 +
*Wir klonen das Rocky Template
 +
 +
==Vorgaben==
 +
{| class="wikitable"
 +
! Einstellung !! Wert
 +
|-
 +
| '''Name''' || revproxy.it2XX.int
 +
|-
 +
| '''IP-Adresse''' || 10.88.2XX.41/24
 +
|-
 +
| '''Gateway''' || 10.88.2XX.1
 +
|-
 +
| '''Nameserver''' || 10.88.2XX.21
 +
|-
 +
| '''Search-Domain''' || it2XX.int
 +
|-
 +
| '''Benutzername''' || kit
 +
|-
 +
| '''Benutzerpasswort''' || kit
 +
|-
 +
| '''Administrator''' || root
 +
|-
 +
| '''Administratorpasswort''' || radler
 +
|-
 +
| '''Netz''' || DMZ
 +
|}
 +
 +
==Einstellungen==
 +
;Selbterklärend
 +
*rocky-setup.sh -f revproxy.it2XX.int -a 10.88.2XX.41/24 -g 10.88.2XX.1 -n 10.88.2XX.21
 +
==Übliche Dinge==
 +
*.ssh/config anpassen
 +
*Pubkey übertragen
 +
==Zertifikate besorgen==
 +
*wget https://xinux.de/downloads/script/get-cert.sh
 +
*sudo bash get-cert.sh
  
 
== Topologie ==
 
== Topologie ==
Zeile 18: Zeile 54:
 
*chmod 600 /etc/haproxy/own-combined.pem
 
*chmod 600 /etc/haproxy/own-combined.pem
  
;SELinux-Kontext setzen
+
==Härtung SELinux-Kontext setzen==
 
*semanage fcontext -a -t cert_t "/etc/haproxy/own-combined\.pem"
 
*semanage fcontext -a -t cert_t "/etc/haproxy/own-combined\.pem"
 
*restorecon -v /etc/haproxy/own-combined.pem
 
*restorecon -v /etc/haproxy/own-combined.pem
Zeile 33: Zeile 69:
 
*semanage port -l | grep http_port_t
 
*semanage port -l | grep http_port_t
 
*ls -Z /etc/haproxy/own-combined.pem
 
*ls -Z /etc/haproxy/own-combined.pem
== Haproxy ausgehende Verbindungen erlauben ==
+
unconfined_u:object_r:'''cert_t''':s0 /etc/haproxy/own-combined.pem
 +
 
 +
== Härtung - Haproxy ausgehende Verbindungen erlauben ==
 
*setsebool -P haproxy_connect_any on
 
*setsebool -P haproxy_connect_any on
 
*systemctl restart haproxy
 
*systemctl restart haproxy
  
 
== Coraza (coraza-spoa) installieren ==
 
== Coraza (coraza-spoa) installieren ==
*mkdir -p /etc/coraza-spoa
+
;coraza-spoa Binary installieren
*curl -L -o /usr/local/bin/coraza-spoa https://github.com/corazawaf/coraza-spoa/releases/latest/download/coraza-spoa_linux_amd64
+
*dnf install -y golang git
 +
*git clone --depth=1 https://github.com/corazawaf/coraza-spoa /usr/local/src/coraza-spoa
 +
*cd /usr/local/src/coraza-spoa
 +
*go run mage.go build
 +
*cp build/coraza-spoa /usr/local/bin/coraza-spoa
 
*chmod +x /usr/local/bin/coraza-spoa
 
*chmod +x /usr/local/bin/coraza-spoa
 +
  
 
;OWASP Core Rule Set und Basisregeln laden
 
;OWASP Core Rule Set und Basisregeln laden
 +
*mkdir -p /etc/coraza-spoa
 
*git clone --depth=1 https://github.com/coreruleset/coreruleset /etc/coraza-spoa/coreruleset
 
*git clone --depth=1 https://github.com/coreruleset/coreruleset /etc/coraza-spoa/coreruleset
 
*curl -L -o /etc/coraza-spoa/coraza.conf https://raw.githubusercontent.com/corazawaf/coraza/main/coraza.conf-recommended
 
*curl -L -o /etc/coraza-spoa/coraza.conf https://raw.githubusercontent.com/corazawaf/coraza/main/coraza.conf-recommended
Zeile 52: Zeile 96:
 
# /etc/coraza-spoa/config.yaml
 
# /etc/coraza-spoa/config.yaml
 
bind: 127.0.0.1:9000
 
bind: 127.0.0.1:9000
loglevel: info
+
log_level: info
 +
log_file: /dev/stdout
 +
log_format: console
  
 
applications:
 
applications:
   revproxy:
+
   - name: revproxy
 +
    log_level: info
 +
    log_file: /dev/stdout
 +
    log_format: console
 
     directives: |
 
     directives: |
       Include /etc/coraza-spoa/coraza.conf
+
       Include @coraza.conf-recommended
      SecRuleEngine On
 
 
       Include /etc/coraza-spoa/crs-setup.conf
 
       Include /etc/coraza-spoa/crs-setup.conf
 
       Include /etc/coraza-spoa/coreruleset/rules/*.conf
 
       Include /etc/coraza-spoa/coreruleset/rules/*.conf
 +
      SecRuleEngine On
 +
    response_check: false
 +
    transaction_ttl_ms: 5000                           
 
</pre>
 
</pre>
  
Zeile 83: Zeile 134:
  
 
== HAProxy-Konfiguration ==
 
== HAProxy-Konfiguration ==
 +
;Konfiguration
 
*vim /etc/haproxy/haproxy.cfg
 
*vim /etc/haproxy/haproxy.cfg
 
<pre>
 
<pre>
Zeile 111: Zeile 163:
 
     server spoa1 127.0.0.1:9000 check
 
     server spoa1 127.0.0.1:9000 check
 
</pre>
 
</pre>
 +
;Check
 +
*haproxy -c -f  /etc/haproxy/haproxy.cfg
  
 
== SPOE-Konfiguration für Coraza ==
 
== SPOE-Konfiguration für Coraza ==
Zeile 141: Zeile 195:
 
</pre>
 
</pre>
  
 +
*systemctl restart haproxy
 
*systemctl enable --now haproxy
 
*systemctl enable --now haproxy
  

Aktuelle Version vom 6. August 2026, 08:22 Uhr

WAF-Demo: HAProxy mit Coraza auf Rocky Linux

WAF mit HAProxy und Coraza (OWASP CRS) vor www.it2XX.int, TLS-Terminierung auf revproxy.it2XX.int.

Maschine

  • Wir klonen das Rocky Template

Vorgaben

Einstellung Wert
Name revproxy.it2XX.int
IP-Adresse 10.88.2XX.41/24
Gateway 10.88.2XX.1
Nameserver 10.88.2XX.21
Search-Domain it2XX.int
Benutzername kit
Benutzerpasswort kit
Administrator root
Administratorpasswort radler
Netz DMZ

Einstellungen

Selbterklärend
  • rocky-setup.sh -f revproxy.it2XX.int -a 10.88.2XX.41/24 -g 10.88.2XX.1 -n 10.88.2XX.21

Übliche Dinge

  • .ssh/config anpassen
  • Pubkey übertragen

Zertifikate besorgen

Topologie

  • revproxy.it2XX.int (10.88.2XX.41) – HAProxy terminiert TLS auf Port 443, coraza-spoa läuft lokal auf 127.0.0.1:9000
  • www.it2XX.int (10.88.2XX.11) – bestehender Backend-Webserver, TLS auf Port 443

HAProxy installieren

  • dnf install -y haproxy git

Zertifikat auf dem Reverse Proxy vorbereiten

Beschreibung

HAProxy erwartet Zertifikat und Key als eine gemeinsame PEM-Datei.

  • cat /etc/ssl/own.crt /etc/ssl/own.key > /etc/haproxy/own-combined.pem
  • chmod 600 /etc/haproxy/own-combined.pem

Härtung SELinux-Kontext setzen

  • semanage fcontext -a -t cert_t "/etc/haproxy/own-combined\.pem"
  • restorecon -v /etc/haproxy/own-combined.pem

Härtung mit firewalld (revproxy)

  • firewall-cmd --permanent --add-service=https
  • firewall-cmd --reload
Kontrolle
  • firewall-cmd --list-services

Härtung mit SELinux (revproxy)

Kontrolle der Kontexte
  • semanage port -l | grep http_port_t
  • ls -Z /etc/haproxy/own-combined.pem
unconfined_u:object_r:cert_t:s0 /etc/haproxy/own-combined.pem

Härtung - Haproxy ausgehende Verbindungen erlauben

  • setsebool -P haproxy_connect_any on
  • systemctl restart haproxy

Coraza (coraza-spoa) installieren

coraza-spoa Binary installieren
  • dnf install -y golang git
  • git clone --depth=1 https://github.com/corazawaf/coraza-spoa /usr/local/src/coraza-spoa
  • cd /usr/local/src/coraza-spoa
  • go run mage.go build
  • cp build/coraza-spoa /usr/local/bin/coraza-spoa
  • chmod +x /usr/local/bin/coraza-spoa


OWASP Core Rule Set und Basisregeln laden
Coraza-Konfiguration
  • vim /etc/coraza-spoa/config.yaml
# /etc/coraza-spoa/config.yaml
bind: 127.0.0.1:9000
log_level: info
log_file: /dev/stdout
log_format: console

applications:
  - name: revproxy
    log_level: info
    log_file: /dev/stdout
    log_format: console
    directives: |
      Include @coraza.conf-recommended
      Include /etc/coraza-spoa/crs-setup.conf
      Include /etc/coraza-spoa/coreruleset/rules/*.conf
      SecRuleEngine On
    response_check: false
    transaction_ttl_ms: 5000                             
systemd-Unit
  • vim /etc/systemd/system/coraza-spoa.service
# /etc/systemd/system/coraza-spoa.service
[Unit]
Description=Coraza SPOA für HAProxy
After=network.target

[Service]
ExecStart=/usr/local/bin/coraza-spoa -config /etc/coraza-spoa/config.yaml
Restart=on-failure

[Install]
WantedBy=multi-user.target
  • systemctl daemon-reload
  • systemctl enable --now coraza-spoa

HAProxy-Konfiguration

Konfiguration
  • vim /etc/haproxy/haproxy.cfg
# /etc/haproxy/haproxy.cfg
global
    log /dev/log local0
    maxconn 2000

defaults
    mode http
    timeout connect 5s
    timeout client 30s
    timeout server 30s
    errorfile 403 /etc/haproxy/errors/403-waf.http

frontend fe_web
    bind 10.88.2XX.41:443 ssl crt /etc/haproxy/own-combined.pem
    filter spoe engine coraza config /etc/haproxy/coraza.cfg
    http-request deny deny_status 403 if { var(txn.coraza.action) -m str deny }
    default_backend backend_web

backend backend_web
    server web01 10.88.2XX.11:443 check ssl verify none

backend coraza-spoa
    mode tcp
    option spop-check
    server spoa1 127.0.0.1:9000 check
Check
  • haproxy -c -f /etc/haproxy/haproxy.cfg

SPOE-Konfiguration für Coraza

  • vim /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
    log               global

spoe-message coraza-req
    args app=str(revproxy) 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

Eigene Fehlerseite

  • mkdir -p /etc/haproxy/errors
  • vim /etc/haproxy/errors/403-waf.http
HTTP/1.1 403 Forbidden
Content-Type: text/html

<html><body><h1>Anfrage blockiert</h1><p>Diese Anfrage wurde von der Web Application Firewall abgelehnt.</p></body></html>
  • systemctl restart haproxy
  • systemctl enable --now haproxy

Test

Erste Anfrage: Status 200 von www.it2XX.int. Zweite Anfrage: 403-Fehlerseite, www.it2XX.int wird nicht erreicht.