-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add support for coraza-waf integration
- Loading branch information
Showing
16 changed files
with
353 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
# Coraza WAF Example | ||
|
||
You might want to combine the actual WAF-functionality with [basic Security-checks and TLS-Fingerprinting](https://github.com/ansibleguy/infra_haproxy/blob/latest/ExampleWAF.md)! | ||
|
||
## Config | ||
|
||
```yaml | ||
waf: # Role: ansibleguy.haproxy_waf_coraza | ||
apps: | ||
- name: 'default' | ||
- name: 'default_block' | ||
block: true | ||
|
||
# apis | ||
- name: 'app1' | ||
block: true | ||
|
||
- name: 'app2' | ||
|
||
haproxy: | ||
waf: | ||
coraza: | ||
enable: true | ||
default_app: 'default' | ||
|
||
frontends: | ||
fe_web: | ||
bind: ['[::]:80 v4v6'] | ||
|
||
routes: | ||
be_test1: | ||
domains: ['test1.ansibleguy.net'] | ||
|
||
be_test2: | ||
domains: ['test2.ansibleguy.net'] | ||
|
||
be_app1: | ||
domains: ['app1.ansibleguy.net'] | ||
|
||
be_app2: | ||
domains: ['app2.ansibleguy.net'] | ||
|
||
default_backend: 'be_fallback' | ||
|
||
backends: | ||
be_test1: | ||
servers: ... | ||
|
||
be_test2: | ||
servers: ... | ||
security: | ||
coraza_app: 'default_block' | ||
|
||
be_app1: | ||
servers: ... | ||
|
||
be_app2: | ||
servers: ... | ||
|
||
be_fallback: | ||
lines: 'http-request redirect code 302 location https://github.com/ansibleguy' | ||
``` | ||
---- | ||
## Result | ||
```bash | ||
root@test-ag-haproxy-waf:/# cat /etc/haproxy/haproxy.cfg | ||
> # Ansible managed: Do NOT edit this file manually! | ||
> # ansibleguy.infra_haproxy | ||
> | ||
> global | ||
> daemon | ||
> user haproxy | ||
> group haproxy | ||
> | ||
> tune.ssl.capture-buffer-size 96 | ||
> | ||
> log /dev/log local0 | ||
> log /dev/log local1 notice | ||
> chroot /var/lib/haproxy | ||
> stats socket /run/haproxy/admin.sock mode 660 level admin | ||
> stats timeout 30s | ||
> ca-base /etc/ssl/certs | ||
> crt-base /etc/ssl/private | ||
> ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 | ||
> ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 | ||
> ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets | ||
> | ||
> defaults | ||
> log global | ||
> mode http | ||
> option httplog | ||
> option dontlognull | ||
> timeout connect 5000 | ||
> timeout client 50000 | ||
> timeout server 50000 | ||
> errorfile 400 /etc/haproxy/errors/400.http | ||
> errorfile 403 /etc/haproxy/errors/403.http | ||
> errorfile 408 /etc/haproxy/errors/408.http | ||
> errorfile 500 /etc/haproxy/errors/500.http | ||
> errorfile 502 /etc/haproxy/errors/502.http | ||
> errorfile 503 /etc/haproxy/errors/503.http | ||
> errorfile 504 /etc/haproxy/errors/504.http | ||
|
||
root@test-ag-haproxy-waf:/# cat /etc/haproxy/waf-coraza.cfg | ||
> # Ansible managed | ||
> # ansibleguy.haproxy_waf_coraza | ||
> | ||
> backend coraza-waf-spoa | ||
> mode tcp | ||
> server coraza-waf 127.0.0.1:9000 check | ||
|
||
root@test-ag-haproxy-waf:/# cat waf-coraza-spoe.cfg | ||
> # Ansible managed | ||
> # ansibleguy.haproxy_waf_coraza | ||
> | ||
> [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-waf-spoa | ||
> log global | ||
> | ||
> spoe-message coraza-req | ||
> args app=var(txn.waf_app) 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-backend-http-request | ||
|
||
root@test-ag-haproxy-waf:/# cat /etc/haproxy/conf.d/frontend.cfg | ||
> # Ansible managed: Do NOT edit this file manually! | ||
> # ansibleguy.infra_haproxy | ||
> | ||
> frontend fe_web | ||
> mode http | ||
> bind [::]:80 v4v6 | ||
> | ||
> # Security headers | ||
> http-response add-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;" if !{ res.hdr(Strict-Transport-Security) -m found } | ||
> http-response add-header X-Frame-Options "SAMEORIGIN" if !{ res.hdr(X-Frame-Options) -m found } | ||
> http-response add-header X-Content-Type-Options "nosniff" if !{ res.hdr(X-Content-Type-Options) -m found } | ||
> http-response add-header X-Permitted-Cross-Domain-Policies "none" if !{ res.hdr(X-Permitted-Cross-Domain-Policies) -m found } | ||
> http-response add-header X-XSS-Protection "1; mode=block" if !{ res.hdr(X-XSS-Protection) -m found } | ||
> | ||
> http-request capture req.fhdr(User-Agent) len 200 | ||
> | ||
> # BACKEND be_test1 | ||
> acl be_test1_filter_domains req.hdr(host) -m str -i test1.ansibleguy.net | ||
> use_backend be_test1 if be_test1_filter_domains | ||
> | ||
> # BACKEND be_test2 | ||
> acl be_test2_filter_domains req.hdr(host) -m str -i test2.ansibleguy.net | ||
> use_backend be_test2 if be_test2_filter_domains | ||
> | ||
> http-request set-var(txn.waf_app) str(default_block) if be_test2_filter_domains | ||
> | ||
> # BACKEND be_app1 | ||
> acl be_app1_filter_domains req.hdr(host) -m str -i app1.ansibleguy.net | ||
> use_backend be_app1 if be_app1_filter_domains | ||
> | ||
> http-request set-var(txn.waf_app) str(be_app1) if be_app1_filter_domains | ||
> | ||
> # BACKEND be_app2 | ||
> acl be_app2_filter_domains req.hdr(host) -m str -i app2.ansibleguy.net | ||
> use_backend be_app2 if be_app2_filter_domains | ||
> | ||
> http-request set-var(txn.waf_app) str(be_app2) if be_app1_filter_domains | ||
> | ||
> # Coraza WAF | ||
> http-request set-var(txn.waf_app) str(default) if !{ var(txn.waf_app) -m found } | ||
> | ||
> filter spoe engine coraza config /etc/haproxy/waf-coraza-spoe.cfg | ||
> http-request capture var(txn.waf_app) len 50 | ||
> http-request capture var(txn.coraza.id) len 16 | ||
> http-request capture var(txn.coraza.fail) len 1 | ||
> http-request capture var(txn.coraza.action) len 8 | ||
> http-request deny status 403 default-errorfiles if { var(txn.coraza.action) -m str deny } | ||
> http-response deny status 403 default-errorfiles if { var(txn.coraza.action) -m str deny } | ||
> http-request silent-drop if { var(txn.coraza.action) -m str drop } | ||
> http-response silent-drop if { var(txn.coraza.action) -m str drop } | ||
|
||
root@test-ag-haproxy-waf:/# systemctl status haproxy.service | ||
> * haproxy.service - HAProxy Load Balancer | ||
> Loaded: loaded (/lib/systemd/system/haproxy.service; enabled; preset: enabled) | ||
> Drop-In: /etc/systemd/system/haproxy.service.d | ||
> `-override.conf | ||
> Active: active (running) since Sat 2024-05-04 16:24:54 UTC; 4min 11s ago | ||
> Docs: man:haproxy(1) | ||
> file:/usr/share/doc/haproxy/configuration.txt.gz | ||
> https://www.haproxy.com/documentation/haproxy-configuration-manual/latest/ | ||
> https://github.com/ansibleguy/infra_haproxy | ||
> Process: 4574 ExecStartPre=/usr/sbin/haproxy -c -f $CONFIG -f /etc/haproxy/conf.d/ -f /etc/haproxy/waf-coraza.cfg (code=exited, status=0/SUCCESS) | ||
> Process: 4635 ExecReload=/usr/sbin/haproxy -c -f $CONFIG -f /etc/haproxy/conf.d/ -f /etc/haproxy/waf-coraza.cfg (code=exited, status=0/SUCCESS) | ||
> Process: 4637 ExecReload=/bin/kill -USR2 $MAINPID (code=exited, status=0/SUCCESS) | ||
> Main PID: 4576 (haproxy) | ||
> Status: "Ready." | ||
> Tasks: 7 (limit: 1783) | ||
> Memory: 132.2M | ||
> CPU: 297ms | ||
> CGroup: /system.slice/haproxy.service | ||
> |-4576 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -p /run/haproxy.pid -S /run/haproxy-master.sock | ||
> `-4639 /usr/sbin/haproxy -sf 4578 -x sockpair@4 -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -p /run/haproxy.pid -S /run/haproxy-master.sock | ||
|
||
root@test-ag-haproxy-waf:/# systemctl status coraza-spoa.service | ||
> ● coraza-spoa.service - Coraza WAF SPOA Daemon | ||
> Loaded: loaded (/etc/systemd/system/coraza-spoa.service; enabled; preset: enabled) | ||
> Drop-In: /etc/systemd/system/coraza-spoa.service.d | ||
> └─override.conf | ||
> Active: active (running) since Fri 2024-12-27 19:45:29 CET; 1h 12min ago | ||
> Docs: https://www.coraza.io | ||
> https://github.com/corazawaf/coraza-spoa | ||
> https://github.com/corazawaf/coraza | ||
> https://coraza.io/docs/seclang/directives/ | ||
> https://github.com/ansibleguy/haproxy_waf_coraza | ||
> https://docs.o-x-l.com/waf/coraza.html | ||
> Main PID: 3878168 (coraza-spoa) | ||
> Tasks: 10 (limit: 4531) | ||
> Memory: 11.7M | ||
> CPU: 4.099s | ||
> CGroup: /system.slice/coraza-spoa.service | ||
> └─3878168 /usr/bin/coraza-spoa -config=/etc/coraza-spoa/spoa.yml | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
# external roles and collections to download | ||
# install: ansible-galaxy install -r requirements.yml | ||
|
||
roles: | ||
- src: 'ansibleguy.haproxy_waf_coraza' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.