From ea27077d7808ca11a12c8e58afe827286d1d9212 Mon Sep 17 00:00:00 2001 From: Rath Pascal Date: Sun, 5 Jan 2025 19:42:10 +0100 Subject: [PATCH 01/14] test: add support for ftw-tests --- .github/workflows/test.yaml | 14 +- example/docker-compose.yaml | 2 +- ftw/Dockerfile.coraza_spoa | 26 +++ ftw/Dockerfile.ftw | 20 +++ ftw/coraza-spoa.yaml | 48 ++++++ ftw/docker-compose.yml | 53 ++++++ ftw/ftw.yml | 320 ++++++++++++++++++++++++++++++++++++ ftw/haproxy/coraza.cfg | 26 +++ ftw/haproxy/haproxy.cfg | 45 +++++ ftw/tests.sh | 41 +++++ magefile.go | 17 ++ 11 files changed, 610 insertions(+), 2 deletions(-) create mode 100644 ftw/Dockerfile.coraza_spoa create mode 100644 ftw/Dockerfile.ftw create mode 100644 ftw/coraza-spoa.yaml create mode 100644 ftw/docker-compose.yml create mode 100644 ftw/ftw.yml create mode 100644 ftw/haproxy/coraza.cfg create mode 100644 ftw/haproxy/haproxy.cfg create mode 100755 ftw/tests.sh diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 53cb7cd..6d768be 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -24,4 +24,16 @@ jobs: haproxy -vv - name: Test - run: go run mage.go test \ No newline at end of file + run: go run mage.go test + + - name: Run regression tests (ftw) + run: go run mage.go ftw + + - uses: actions/upload-artifact@v4 + if: success() || failure() + with: + name: ftw-haproxy-spoa-logs + path: | + build/ftw.log + build/ftw-spoa.log + build/ftw-haproxy.log diff --git a/example/docker-compose.yaml b/example/docker-compose.yaml index d6740be..3b5090d 100644 --- a/example/docker-compose.yaml +++ b/example/docker-compose.yaml @@ -19,7 +19,7 @@ services: haproxy: restart: unless-stopped image: haproxy:2.9-alpine - ports: [ "8080:80", "8443:443", "8082:8082"] + ports: [ "8080:80", "8443:443", "8082:8082" ] depends_on: - httpbin links: diff --git a/ftw/Dockerfile.coraza_spoa b/ftw/Dockerfile.coraza_spoa new file mode 100644 index 0000000..8cc310d --- /dev/null +++ b/ftw/Dockerfile.coraza_spoa @@ -0,0 +1,26 @@ +# Copyright 2023 The OWASP Coraza contributors +# SPDX-License-Identifier: Apache-2.0 + +FROM golang:1.22 AS build + +WORKDIR /go/src/app +COPY . . + +RUN go mod download +RUN go vet -v ./... + +RUN CGO_ENABLED=0 go build -o /go/bin/coraza-spoa + +FROM gcr.io/distroless/static-debian11 + +LABEL org.opencontainers.image.authors="The OWASP Coraza contributors" \ + org.opencontainers.image.description="OWASP Coraza WAF (Haproxy SPOA)" \ + org.opencontainers.image.documentation="https://coraza.io/connectors/coraza-spoa/" \ + org.opencontainers.image.licenses="Apache-2.0" \ + org.opencontainers.image.source="https://github.com/corazawaf/coraza-spoa" \ + org.opencontainers.image.title="coraza-spoa" + +COPY --from=build /go/bin/coraza-spoa / +COPY ./ftw/coraza-spoa.yaml /config.yaml + +CMD ["/coraza-spoa", "--config", "/config.yaml"] \ No newline at end of file diff --git a/ftw/Dockerfile.ftw b/ftw/Dockerfile.ftw new file mode 100644 index 0000000..55251cb --- /dev/null +++ b/ftw/Dockerfile.ftw @@ -0,0 +1,20 @@ +# Copyright 2025 The OWASP Coraza contributors +# SPDX-License-Identifier: Apache-2.0 + +FROM ghcr.io/coreruleset/go-ftw:1.1.2 + +RUN apk update && apk add curl jq + +WORKDIR /workspace + +RUN mkdir coreruleset && \ + export CRS_VERSION="$(curl https://api.github.com/repos/corazawaf/coraza-coreruleset/releases/latest 2>/dev/null | jq -r '.name')" && \ + curl -L -o coreruleset/crs.tar.gz "https://github.com/coreruleset/coreruleset/archive/refs/tags/${CRS_VERSION}.tar.gz" 2>/dev/null && \ + cd coreruleset && \ + tar -xzf crs.tar.gz --strip-components 1 + +COPY ftw.yml /workspace/ftw.yml +COPY tests.sh /workspace/tests.sh + +ENTRYPOINT ["sh"] +CMD ["-c", "/workspace/tests.sh"] \ No newline at end of file diff --git a/ftw/coraza-spoa.yaml b/ftw/coraza-spoa.yaml new file mode 100644 index 0000000..7b717a1 --- /dev/null +++ b/ftw/coraza-spoa.yaml @@ -0,0 +1,48 @@ +--- + +bind: 0.0.0.0:9000 +log_level: info +log_file: /var/log/coraza-spoa/ftw-spoa.log +log_format: console + +applications: + - name: ftw + directives: | + Include @coraza.conf-recommended + # FTW config + SecDefaultAction "phase:3,log,auditlog,pass" + SecDefaultAction "phase:4,log,auditlog,pass" + SecDefaultAction "phase:5,log,auditlog,pass" + SecDebugLogLevel 3 + + SecAction "id:900005,\ + phase:1,\ + nolog,\ + pass,\ + ctl:ruleEngine=DetectionOnly,\ + ctl:ruleRemoveById=910000,\ + setvar:tx.blocking_paranoia_level=4,\ + setvar:tx.crs_validate_utf8_encoding=1,\ + setvar:tx.arg_name_length=100,\ + setvar:tx.arg_length=400,\ + setvar:tx.total_arg_length=64000,\ + setvar:tx.max_num_args=255,\ + setvar:tx.max_file_size=64100,\ + setvar:tx.combined_file_sizes=65535" + + SecRule REQUEST_HEADERS:X-CRS-Test "@rx ^.*$" "id:999999,\ + phase:1,\ + pass,\ + t:none,\ + log,\ + msg:'X-CRS-Test %{MATCHED_VAR}',\ + ctl:ruleRemoveById=1-999999" + + Include @crs-setup.conf.example + Include @owasp_crs/*.conf + + response_check: false + transaction_ttl_ms: 60000 + log_level: error # Printing only logs at error level to reduce what ftw has to parse + log_file: /var/log/coraza-spoa/ftw.log + log_format: console diff --git a/ftw/docker-compose.yml b/ftw/docker-compose.yml new file mode 100644 index 0000000..d93f57b --- /dev/null +++ b/ftw/docker-compose.yml @@ -0,0 +1,53 @@ +--- + +services: + coraza-spoa: + build: + context: .. + dockerfile: ./ftw/Dockerfile.coraza_spoa + network: host + volumes: + - ../build:/var/log/coraza-spoa:rw + ports: + - 9000:9000 + + haproxy-log: + image: alpine:3.21 + command: + - /bin/sh + - -c + - touch /var/log/haproxy/ftw-haproxy.log && chmod 777 /var/log/haproxy/ftw-haproxy.log + volumes: + - ../build:/var/log/haproxy:rw + + haproxy: + depends_on: + - haproxy-log + image: haproxy:3.1-alpine + links: + - coraza-spoa:coraza-spoa + volumes: + - type: bind + source: ./haproxy/ + target: /usr/local/etc/haproxy + - ../build:/var/log/haproxy:rw + command: + - /bin/sh + - -c + - haproxy -f /usr/local/etc/haproxy/haproxy.cfg > /var/log/haproxy/ftw-haproxy.log + ports: + - 8080:8080 + + ftw: + depends_on: + - coraza-spoa + - haproxy + build: + context: . + dockerfile: Dockerfile.ftw + network: host + environment: + - FTW_CLOUDMODE + - FTW_INCLUDE + volumes: + - ../build:/build diff --git a/ftw/ftw.yml b/ftw/ftw.yml new file mode 100644 index 0000000..0e541fe --- /dev/null +++ b/ftw/ftw.yml @@ -0,0 +1,320 @@ +--- + +logfile: '/build/ftw.log' +maxmarkerretries: 10 +testoverride: + input: + dest_addr: 'haproxy' + port: 8080 + ignore: + # Imported from https://github.com/corazawaf/coraza/blob/main/testing/coreruleset/.ftw.yml + 920100-4: 'Invalid uri, Coraza not reached - 404 page not found' + 920100-5: 'Invalid uri, Coraza not reached - 404 page not found' + 930110-7: 'CRS issue: https://github.com/coreruleset/coreruleset/issues/3736' + 932200-13: 'Failing only in multiphase evalution' + 932300-10: 'Failing only in multiphase evalution' + 933120-2: 'Failing only in multiphase evalution' + 920280-3: '' + 920430-3: '' + 920430-5: '' + 920430-9: '' + 920610-2: 'fragments, Coraza might just happly accept them. Run and check it.' + 920620-1: 'Rule checks if multiple Content-Type headers are kepts. Go/http might keep them and trigger the rule. Run and check it.' + + # TODO investigate failing tests: + 920100-10: '' + 920100-14: '' + 920100-16: '' + 920120-40: '' + 920120-41: '' + 920121-6: '' + 920121-7: '' + 920180-1: '' + 920180-3: '' + 920190-2: '' + 920190-3: '' + 920200-1: '' + 920200-2: '' + 920200-4: '' + 920200-5: '' + 920200-6: '' + 920200-8: '' + 920201-1: '' + 920201-2: '' + 920202-1: '' + 920202-2: '' + 920210-2: '' + 920210-3: '' + 920210-4: '' + 920210-6: '' + 920210-7: '' + 920220-1: '' + 920220-2: '' + 920220-5: '' + 920220-6: '' + 920221-1: '' + 920230-1: '' + 920240-1: '' + 920240-5: '' + 920240-6: '' + 920250-1: '' + 920250-2: '' + 920250-3: '' + 920250-4: '' + 920260-1: '' + 920260-3: '' + 920270-4: '' + 920274-1: '' + 920280-1: '' + 920290-1: '' + 920290-4: 'investigate, test related to empty host header' + 920300-1: '' + 920310-1: '' + 920310-4: '' + 920311-1: '' + 920320-1: '' + 920330-1: '' + 920340-1: '' + 920340-2: '' + 920350-1: '' + 920350-3: '' + 920350-4: '' + 920350-5: '' + 920350-6: '' + 920390-1: '' + 920400-1: '' + 920410-1: '' + 920420-15: '' + 920420-16: '' + 920420-17: '' + 920440-7: '' + 920470-19: '' + 920520-8: '' + 920520-9: '' + 921240-2: '' + 922100-3: '' + 922130-1: '' + 922130-2: '' + 922130-4: '' + 922130-7: '' + 932130-17: '' + 932131-2: '' + 932160-11: '' + 932160-12: '' + 932160-13: '' + 932175-10: '' + 932175-11: '' + 932175-12: '' + 932175-13: '' + 932175-14: '' + 932175-15: '' + 932190-5: '' + 932190-6: '' + 932205-7: '' + 932230-50: '' + 932230-51: '' + 932230-52: '' + 932230-53: '' + 932230-56: '' + 932230-57: '' + 932230-58: '' + 932235-11: '' + 932235-13: '' + 932235-14: '' + 932235-15: '' + 932235-16: '' + 932235-19: '' + 932235-20: '' + 932235-21: '' + 932235-22: '' + 932235-23: '' + 932235-24: '' + 932235-25: '' + 932235-26: '' + 932235-27: '' + 932235-28: '' + 932235-29: '' + 932235-30: '' + 932235-32: '' + 932235-33: '' + 932235-34: '' + 932235-35: '' + 932235-36: '' + 932235-37: '' + 932235-38: '' + 932236-44: '' + 932236-45: '' + 932236-46: '' + 932236-47: '' + 932236-48: '' + 932236-49: '' + 932236-62: '' + 932236-63: '' + 932236-65: '' + 932236-66: '' + 932236-67: '' + 932236-68: '' + 932236-69: '' + 932236-70: '' + 932236-71: '' + 932236-72: '' + 932236-74: '' + 932236-75: '' + 932236-76: '' + 932236-77: '' + 932236-78: '' + 932236-79: '' + 932236-80: '' + 932237-1: '' + 932237-6: '' + 932237-15: '' + 932237-16: '' + 932237-19: '' + 932237-20: '' + 932237-22: '' + 932237-23: '' + 932237-24: '' + 932237-25: '' + 932237-26: '' + 932237-28: '' + 932237-29: '' + 932237-30: '' + 932237-31: '' + 932237-32: '' + 932237-33: '' + 932237-34: '' + 932238-3: '' + 932238-4: '' + 932238-5: '' + 932238-6: '' + 932238-9: '' + 932238-10: '' + 932239-20: '' + 932239-21: '' + 932239-22: '' + 932239-23: '' + 932239-24: '' + 932239-25: '' + 932239-38: '' + 932239-39: '' + 932239-40: '' + 932239-41: '' + 932239-42: '' + 932239-43: '' + 932239-44: '' + 932239-45: '' + 932239-47: '' + 932239-48: '' + 932239-49: '' + 932239-50: '' + 932239-51: '' + 932239-52: '' + 932239-53: '' + 932240-16: '' + 932240-18: '' + 932260-24: '' + 932260-25: '' + 932260-27: '' + 932260-28: '' + 932260-29: '' + 932260-30: '' + 932260-31: '' + 932260-32: '' + 932260-33: '' + 932260-34: '' + 932260-35: '' + 932260-36: '' + 932260-37: '' + 932260-38: '' + 932260-39: '' + 932260-40: '' + 932260-41: '' + 932260-42: '' + 932260-43: '' + 932260-44: '' + 932260-45: '' + 932270-1: '' + 932270-2: '' + 932270-3: '' + 932270-4: '' + 932270-5: '' + 932270-9: '' + 932270-10: '' + 932270-11: '' + 932270-12: '' + 932270-13: '' + 932380-9: '' + 933100-5: '' + 933100-6: '' + 933100-7: '' + 933100-8: '' + 933151-6: '' + 933160-9: '' + 933160-10: '' + 933160-12: '' + 933160-14: '' + 933160-15: '' + 933160-16: '' + 933160-29: '' + 934120-23: '' + 934120-24: '' + 934120-25: '' + 934120-26: '' + 934120-39: '' + 941120-4: 'investigate, Test added via https://github.com/coreruleset/coreruleset/pull/3822' + 941120-7: '' + 941160-16: '' + 941160-17: '' + 941390-8: '' + 941390-9: '' + 942160-14: '' + 942190-42: '' + 942190-44: '' + 942420-1: '' + 942421-1: '' + 942430-1: '' + 942431-1: '' + 942432-1: '' + 942440-19: '' + 942440-20: '' + 942460-1: '' + 942500-3: '' + 942500-4: '' + 942560-1: '' + 951110-1: '' + 951120-1: '' + 951130-1: '' + 951140-1: '' + 951150-1: '' + 951160-1: '' + 951170-1: '' + 951180-1: '' + 951190-1: '' + 951200-1: '' + 951210-1: '' + 951220-1: '' + 951220-2: '' + 951230-1: '' + 951230-2: '' + 951240-1: '' + 951240-2: '' + 951250-1: '' + 951260-1: '' + 953101-1: '' + 953101-2: '' + 953101-3: '' + 953101-4: '' + 953101-5: '' + 953120-1: '' + 953120-3: '' + 953120-5: '' + 953120-7: '' + 954100-1: '' + 954120-1: '' + 954120-2: '' + 955100-1: '' + 955100-2: '' + 955100-3: '' + 955260-1: '' + 959100-1: '' + 959100-3: '' diff --git a/ftw/haproxy/coraza.cfg b/ftw/haproxy/coraza.cfg new file mode 100644 index 0000000..bc1fc13 --- /dev/null +++ b/ftw/haproxy/coraza.cfg @@ -0,0 +1,26 @@ +# https://github.com/haproxy/haproxy/blob/master/doc/SPOE.txt +# /usr/local/etc/haproxy/coraza.cfg +[coraza] +spoe-agent coraza-agent + messages coraza-req coraza-res + groups coraza-req coraza-res + 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(ftw) 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 + +spoe-message coraza-res + args app=str(ftw) id=var(txn.coraza.id) version=res.ver status=status headers=res.hdrs body=res.body + event on-http-response + +spoe-group coraza-req + messages coraza-req + +spoe-group coraza-res + messages coraza-res diff --git a/ftw/haproxy/haproxy.cfg b/ftw/haproxy/haproxy.cfg new file mode 100644 index 0000000..5edf2cb --- /dev/null +++ b/ftw/haproxy/haproxy.cfg @@ -0,0 +1,45 @@ +# https://docs.haproxy.org/ +global + log stdout format raw local0 + +defaults + log global + option httplog + timeout client 1m + timeout server 1m + timeout connect 10s + +frontend default + mode http + bind *:8080 + log-format "%ci:%cp\ [%t]\ %ft\ %b/%s\ %Th/%Ti/%TR/%Tq/%Tw/%Tc/%Tr/%Tt\ %ST\ %B\ %CC\ %CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ %{+Q}r\ %[var(txn.coraza.id)]\ spoa-error:\ %[var(txn.coraza.error)]\ waf-hit:\ %[var(txn.coraza.fail)] waf-action:\ %[var(txn.coraza.action)]" + + filter spoe engine coraza config /usr/local/etc/haproxy/coraza.cfg + http-request send-spoe-group coraza coraza-req + + # Currently haproxy cannot use variables to set the code or deny_status, so this needs to be manually configured here + http-request redirect code 302 location %[var(txn.coraza.data)] if { var(txn.coraza.action) -m str redirect } + http-response redirect code 302 location %[var(txn.coraza.data)] if { var(txn.coraza.action) -m str redirect } + + http-request deny deny_status 403 hdr waf-block "request" if { var(txn.coraza.action) -m str deny } + http-response deny deny_status 403 hdr waf-block "response" 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 } + + # Deny in case of an error, when processing with the Coraza SPOA + http-request deny deny_status 500 if { var(txn.coraza.error) -m int gt 0 } + http-response deny deny_status 500 if { var(txn.coraza.error) -m int gt 0 } + + use_backend test + +resolvers host_dns + parse-resolv-conf + +backend test + mode http + http-request return status 200 + +backend coraza-spoa + mode tcp + server coraza_spoa coraza-spoa:9000 diff --git a/ftw/tests.sh b/ftw/tests.sh new file mode 100755 index 0000000..ae82b50 --- /dev/null +++ b/ftw/tests.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# Copyright 2025 The OWASP Coraza contributors +# SPDX-License-Identifier: Apache-2.0 + +cd /workspace + +# Revisited from https://github.com/corazawaf/coraza-proxy-wasm/blob/main/ftw/tests.sh + +step=1 +total_steps=1 +max_retries=15 # Seconds for the server reachability timeout +host=${1:-haproxy} +health_url="http://${host}:8080" +log_file='/build/ftw-haproxy.log' + +# Testing if the server is up +echo "[$step/$total_steps] Testing application reachability" +status_code="000" +while [[ "$status_code" -eq "000" ]]; do + status_code=$(curl --write-out "%{http_code}" --silent --output /dev/null "$health_url") + sleep 1 + echo -ne "[Wait] Waiting for response from $health_url. Timeout: ${max_retries}s \r" + let "max_retries--" + if [[ "$max_retries" -eq 0 ]]; then + echo "[Fail] Timeout waiting for response from $health_url, make sure the server is running." + echo "HAProxy Logs:" && cat "$log_file" + exit 1 + fi +done +if [[ "${status_code}" -ne "200" ]]; then + echo "[Fail] Unexpected response with code ${status_code} from ${health_url}, expected 200." + echo "HAProxy Logs:" && cat "$log_file" + exit 1 +fi +echo -e "\n[Ok] Got status code $status_code, expected 200. Ready to start." + +FTW_CLOUDMODE=${FTW_CLOUDMODE:-false} + +FTW_INCLUDE=$([ "${FTW_INCLUDE}" == "" ] && echo "" || echo "-i ${FTW_INCLUDE}") + +/ftw run -d coreruleset/tests/regression/tests --config ftw.yml --read-timeout=10s --max-marker-retries=50 --cloud=$FTW_CLOUDMODE $FTW_INCLUDE || exit 1 diff --git a/magefile.go b/magefile.go index f8ecfb5..e978d24 100644 --- a/magefile.go +++ b/magefile.go @@ -157,3 +157,20 @@ func Precommit() error { func Check() { mg.SerialDeps(Lint, Test) } + +// Ftw runs CRS regressions tests. Requires docker. +func Ftw() error { + if err := sh.RunV("docker", "compose", "--file", "ftw/docker-compose.yml", "build", "--pull"); err != nil { + return err + } + defer func() { + _ = sh.RunV("docker", "compose", "--file", "ftw/docker-compose.yml", "down", "-v") + }() + env := map[string]string{ + "FTW_CLOUDMODE": os.Getenv("FTW_CLOUDMODE"), + "FTW_INCLUDE": os.Getenv("FTW_INCLUDE"), + } + + task := "ftw" + return sh.RunWithV(env, "docker", "compose", "--file", "ftw/docker-compose.yml", "run", "--rm", task) +} From a613129177dccd34445fd67cd7924d7ec8146bde Mon Sep 17 00:00:00 2001 From: Rath Pascal Date: Sun, 5 Jan 2025 19:48:57 +0100 Subject: [PATCH 02/14] test: bump debian version --- ftw/Dockerfile.coraza_spoa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftw/Dockerfile.coraza_spoa b/ftw/Dockerfile.coraza_spoa index 8cc310d..d543634 100644 --- a/ftw/Dockerfile.coraza_spoa +++ b/ftw/Dockerfile.coraza_spoa @@ -11,7 +11,7 @@ RUN go vet -v ./... RUN CGO_ENABLED=0 go build -o /go/bin/coraza-spoa -FROM gcr.io/distroless/static-debian11 +FROM gcr.io/distroless/static-debian12 LABEL org.opencontainers.image.authors="The OWASP Coraza contributors" \ org.opencontainers.image.description="OWASP Coraza WAF (Haproxy SPOA)" \ From 21c2777835cd36f7b319890211f6e7bad585d941 Mon Sep 17 00:00:00 2001 From: Rath Pascal Date: Sun, 5 Jan 2025 20:11:46 +0100 Subject: [PATCH 03/14] test: set coreruleset to specific version --- ftw/Dockerfile.ftw | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ftw/Dockerfile.ftw b/ftw/Dockerfile.ftw index 55251cb..ec1e154 100644 --- a/ftw/Dockerfile.ftw +++ b/ftw/Dockerfile.ftw @@ -7,11 +7,17 @@ RUN apk update && apk add curl jq WORKDIR /workspace -RUN mkdir coreruleset && \ - export CRS_VERSION="$(curl https://api.github.com/repos/corazawaf/coraza-coreruleset/releases/latest 2>/dev/null | jq -r '.name')" && \ - curl -L -o coreruleset/crs.tar.gz "https://github.com/coreruleset/coreruleset/archive/refs/tags/${CRS_VERSION}.tar.gz" 2>/dev/null && \ - cd coreruleset && \ - tar -xzf crs.tar.gz --strip-components 1 +ENV CRS_VERSION=4.5.0 + +ADD https://github.com/coreruleset/coreruleset/archive/refs/tags/v${CRS_VERSION}.tar.gz /workspace/coreruleset/ +RUN cd coreruleset && tar -xf v${CRS_VERSION}.tar.gz --strip-components 1 + +# to dynamically pull latest CRS version: +# RUN mkdir coreruleset && \ +# export CRS_VERSION="$(curl https://api.github.com/repos/corazawaf/coraza-coreruleset/releases/latest 2>/dev/null | jq -r '.name')" && \ +# curl -L -o coreruleset/crs.tar.gz "https://github.com/coreruleset/coreruleset/archive/refs/tags/${CRS_VERSION}.tar.gz" 2>/dev/null && \ +# cd coreruleset && \ +# tar -xzf crs.tar.gz --strip-components 1 COPY ftw.yml /workspace/ftw.yml COPY tests.sh /workspace/tests.sh From a9584881b4cb1aecc6ed0ec8dc35c50065a217a3 Mon Sep 17 00:00:00 2001 From: Rath Pascal Date: Mon, 6 Jan 2025 11:07:09 +0100 Subject: [PATCH 04/14] test: move ftw-tests to separate workflow --- .github/workflows/ftw.yaml | 30 ++++++++++++++++++++++++++++++ .github/workflows/test.yaml | 12 ------------ 2 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/ftw.yaml diff --git a/.github/workflows/ftw.yaml b/.github/workflows/ftw.yaml new file mode 100644 index 0000000..fb5c536 --- /dev/null +++ b/.github/workflows/ftw.yaml @@ -0,0 +1,30 @@ +--- + +name: FTW Test + +on: + pull_request: + push: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: 'go.mod' + + - name: Run regression tests (ftw) + run: go run mage.go ftw + + - uses: actions/upload-artifact@v4 + if: success() || failure() + with: + name: ftw-haproxy-spoa-logs + path: | + build/ftw.log + build/ftw-spoa.log + build/ftw-haproxy.log diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 6d768be..1b1bde1 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -25,15 +25,3 @@ jobs: - name: Test run: go run mage.go test - - - name: Run regression tests (ftw) - run: go run mage.go ftw - - - uses: actions/upload-artifact@v4 - if: success() || failure() - with: - name: ftw-haproxy-spoa-logs - path: | - build/ftw.log - build/ftw-spoa.log - build/ftw-haproxy.log From af1c84621eb5194c05d6e9124da5f0a3849cd51e Mon Sep 17 00:00:00 2001 From: Rath Pascal Date: Mon, 6 Jan 2025 11:07:42 +0100 Subject: [PATCH 05/14] test: simplify ftw log-paths --- ftw/coraza-spoa.yaml | 4 ++-- ftw/docker-compose.yml | 29 ++++++++++++++++------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/ftw/coraza-spoa.yaml b/ftw/coraza-spoa.yaml index 7b717a1..16b98ac 100644 --- a/ftw/coraza-spoa.yaml +++ b/ftw/coraza-spoa.yaml @@ -2,7 +2,7 @@ bind: 0.0.0.0:9000 log_level: info -log_file: /var/log/coraza-spoa/ftw-spoa.log +log_file: /build/ftw-spoa.log log_format: console applications: @@ -44,5 +44,5 @@ applications: response_check: false transaction_ttl_ms: 60000 log_level: error # Printing only logs at error level to reduce what ftw has to parse - log_file: /var/log/coraza-spoa/ftw.log + log_file: /build/ftw.log log_format: console diff --git a/ftw/docker-compose.yml b/ftw/docker-compose.yml index d93f57b..1bf093b 100644 --- a/ftw/docker-compose.yml +++ b/ftw/docker-compose.yml @@ -1,28 +1,31 @@ --- services: + # clean existing logs, enable haproxy to write logs, allow devs to manage logs without sudo + prepare-logs: + image: alpine:3.21 + command: + - /bin/sh + - -c + - rm -f /build/ftw* && touch /build/ftw.log /build/ftw-haproxy.log /build/ftw-haproxy.log && chmod 666 /build/ftw* + volumes: + - ../build:/build:rw + coraza-spoa: + depends_on: + - prepare-logs build: context: .. dockerfile: ./ftw/Dockerfile.coraza_spoa network: host volumes: - - ../build:/var/log/coraza-spoa:rw + - ../build:/build:rw ports: - 9000:9000 - haproxy-log: - image: alpine:3.21 - command: - - /bin/sh - - -c - - touch /var/log/haproxy/ftw-haproxy.log && chmod 777 /var/log/haproxy/ftw-haproxy.log - volumes: - - ../build:/var/log/haproxy:rw - haproxy: depends_on: - - haproxy-log + - prepare-logs image: haproxy:3.1-alpine links: - coraza-spoa:coraza-spoa @@ -30,11 +33,11 @@ services: - type: bind source: ./haproxy/ target: /usr/local/etc/haproxy - - ../build:/var/log/haproxy:rw + - ../build:/build:rw command: - /bin/sh - -c - - haproxy -f /usr/local/etc/haproxy/haproxy.cfg > /var/log/haproxy/ftw-haproxy.log + - haproxy -f /usr/local/etc/haproxy/haproxy.cfg > /build/ftw-haproxy.log ports: - 8080:8080 From 7fe946fab79e69cb098cb6e932215c64109da424 Mon Sep 17 00:00:00 2001 From: Rath Pascal Date: Mon, 6 Jan 2025 11:08:22 +0100 Subject: [PATCH 06/14] test: inline unnecessary var --- magefile.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/magefile.go b/magefile.go index e978d24..6b12bb3 100644 --- a/magefile.go +++ b/magefile.go @@ -171,6 +171,5 @@ func Ftw() error { "FTW_INCLUDE": os.Getenv("FTW_INCLUDE"), } - task := "ftw" - return sh.RunWithV(env, "docker", "compose", "--file", "ftw/docker-compose.yml", "run", "--rm", task) + return sh.RunWithV(env, "docker", "compose", "--file", "ftw/docker-compose.yml", "run", "--rm", "ftw") } From 5647c79eb164c64a52e5766245a4fd345891eeb6 Mon Sep 17 00:00:00 2001 From: Rath Pascal Date: Mon, 6 Jan 2025 11:09:19 +0100 Subject: [PATCH 07/14] test: remove dynamic CRS-version for ftw-tests --- ftw/Dockerfile.ftw | 7 ------- 1 file changed, 7 deletions(-) diff --git a/ftw/Dockerfile.ftw b/ftw/Dockerfile.ftw index ec1e154..dbe2298 100644 --- a/ftw/Dockerfile.ftw +++ b/ftw/Dockerfile.ftw @@ -12,13 +12,6 @@ ENV CRS_VERSION=4.5.0 ADD https://github.com/coreruleset/coreruleset/archive/refs/tags/v${CRS_VERSION}.tar.gz /workspace/coreruleset/ RUN cd coreruleset && tar -xf v${CRS_VERSION}.tar.gz --strip-components 1 -# to dynamically pull latest CRS version: -# RUN mkdir coreruleset && \ -# export CRS_VERSION="$(curl https://api.github.com/repos/corazawaf/coraza-coreruleset/releases/latest 2>/dev/null | jq -r '.name')" && \ -# curl -L -o coreruleset/crs.tar.gz "https://github.com/coreruleset/coreruleset/archive/refs/tags/${CRS_VERSION}.tar.gz" 2>/dev/null && \ -# cd coreruleset && \ -# tar -xzf crs.tar.gz --strip-components 1 - COPY ftw.yml /workspace/ftw.yml COPY tests.sh /workspace/tests.sh From d514610391ee0f152a3dbf51c9c58be2b05935e9 Mon Sep 17 00:00:00 2001 From: Rath Pascal Date: Mon, 6 Jan 2025 12:13:28 +0100 Subject: [PATCH 08/14] test: disable build-cache for ftw-test --- magefile.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/magefile.go b/magefile.go index 6b12bb3..e7bdfcc 100644 --- a/magefile.go +++ b/magefile.go @@ -160,7 +160,7 @@ func Check() { // Ftw runs CRS regressions tests. Requires docker. func Ftw() error { - if err := sh.RunV("docker", "compose", "--file", "ftw/docker-compose.yml", "build", "--pull"); err != nil { + if err := sh.RunV("docker", "compose", "--file", "ftw/docker-compose.yml", "build", "--pull", "--no-cache"); err != nil { return err } defer func() { From f7ca8a66d591b695e9c378d1df9641ad3be8710d Mon Sep 17 00:00:00 2001 From: Rath Pascal Date: Mon, 6 Jan 2025 12:14:06 +0100 Subject: [PATCH 09/14] test: add ftw-albedo test-backend --- ftw/Dockerfile.ftw | 5 ++++- ftw/docker-compose.yml | 8 ++++++++ ftw/ftw.yml | 36 +++++------------------------------- ftw/haproxy/haproxy.cfg | 1 + 4 files changed, 18 insertions(+), 32 deletions(-) diff --git a/ftw/Dockerfile.ftw b/ftw/Dockerfile.ftw index dbe2298..9acb973 100644 --- a/ftw/Dockerfile.ftw +++ b/ftw/Dockerfile.ftw @@ -3,10 +3,13 @@ FROM ghcr.io/coreruleset/go-ftw:1.1.2 -RUN apk update && apk add curl jq +RUN apk update && apk add curl WORKDIR /workspace +# TODOs: +# - update when new CRS version is tagged: https://github.com/coreruleset/coreruleset/archive/refs/tags/v4.5.0.tar.gz +# - keep it aligned with the github.com/corazawaf/coraza-coreruleset/v4 dependency version used ENV CRS_VERSION=4.5.0 ADD https://github.com/coreruleset/coreruleset/archive/refs/tags/v${CRS_VERSION}.tar.gz /workspace/coreruleset/ diff --git a/ftw/docker-compose.yml b/ftw/docker-compose.yml index 1bf093b..4f31e15 100644 --- a/ftw/docker-compose.yml +++ b/ftw/docker-compose.yml @@ -1,6 +1,12 @@ --- services: + backend: + image: ghcr.io/coreruleset/albedo:0.0.16 + command: ['--port', '8081'] + ports: + - 8081:8081 + # clean existing logs, enable haproxy to write logs, allow devs to manage logs without sudo prepare-logs: image: alpine:3.21 @@ -22,10 +28,12 @@ services: - ../build:/build:rw ports: - 9000:9000 + restart: unless-stopped haproxy: depends_on: - prepare-logs + - backend image: haproxy:3.1-alpine links: - coraza-spoa:coraza-spoa diff --git a/ftw/ftw.yml b/ftw/ftw.yml index 0e541fe..2ed8d62 100644 --- a/ftw/ftw.yml +++ b/ftw/ftw.yml @@ -11,24 +11,20 @@ testoverride: 920100-4: 'Invalid uri, Coraza not reached - 404 page not found' 920100-5: 'Invalid uri, Coraza not reached - 404 page not found' 930110-7: 'CRS issue: https://github.com/coreruleset/coreruleset/issues/3736' - 932200-13: 'Failing only in multiphase evalution' - 932300-10: 'Failing only in multiphase evalution' - 933120-2: 'Failing only in multiphase evalution' + 932200-13: 'Failing only in multiphase evaluation' + 932300-10: 'Failing only in multiphase evaluation' + 933120-2: 'Failing only in multiphase evaluation' 920280-3: '' 920430-3: '' 920430-5: '' 920430-9: '' - 920610-2: 'fragments, Coraza might just happly accept them. Run and check it.' + 920610-2: 'fragments, Coraza might just happily accept them. Run and check it.' 920620-1: 'Rule checks if multiple Content-Type headers are kepts. Go/http might keep them and trigger the rule. Run and check it.' # TODO investigate failing tests: 920100-10: '' 920100-14: '' 920100-16: '' - 920120-40: '' - 920120-41: '' - 920121-6: '' - 920121-7: '' 920180-1: '' 920180-3: '' 920190-2: '' @@ -67,7 +63,7 @@ testoverride: 920274-1: '' 920280-1: '' 920290-1: '' - 920290-4: 'investigate, test related to empty host header' + 920290-4: '' 920300-1: '' 920310-1: '' 920310-4: '' @@ -82,21 +78,14 @@ testoverride: 920350-5: '' 920350-6: '' 920390-1: '' - 920400-1: '' 920410-1: '' 920420-15: '' 920420-16: '' 920420-17: '' - 920440-7: '' - 920470-19: '' 920520-8: '' 920520-9: '' 921240-2: '' 922100-3: '' - 922130-1: '' - 922130-2: '' - 922130-4: '' - 922130-7: '' 932130-17: '' 932131-2: '' 932160-11: '' @@ -141,7 +130,6 @@ testoverride: 932235-35: '' 932235-36: '' 932235-37: '' - 932235-38: '' 932236-44: '' 932236-45: '' 932236-46: '' @@ -233,16 +221,6 @@ testoverride: 932260-43: '' 932260-44: '' 932260-45: '' - 932270-1: '' - 932270-2: '' - 932270-3: '' - 932270-4: '' - 932270-5: '' - 932270-9: '' - 932270-10: '' - 932270-11: '' - 932270-12: '' - 932270-13: '' 932380-9: '' 933100-5: '' 933100-6: '' @@ -261,13 +239,9 @@ testoverride: 934120-25: '' 934120-26: '' 934120-39: '' - 941120-4: 'investigate, Test added via https://github.com/coreruleset/coreruleset/pull/3822' - 941120-7: '' 941160-16: '' - 941160-17: '' 941390-8: '' 941390-9: '' - 942160-14: '' 942190-42: '' 942190-44: '' 942420-1: '' diff --git a/ftw/haproxy/haproxy.cfg b/ftw/haproxy/haproxy.cfg index 5edf2cb..879a974 100644 --- a/ftw/haproxy/haproxy.cfg +++ b/ftw/haproxy/haproxy.cfg @@ -39,6 +39,7 @@ resolvers host_dns backend test mode http http-request return status 200 + # server test backend:8081 backend coraza-spoa mode tcp From b80bda5a5da942e78a07591c1f35ab7457c3d82f Mon Sep 17 00:00:00 2001 From: Rath Pascal Date: Mon, 6 Jan 2025 12:20:10 +0100 Subject: [PATCH 10/14] test: add ftw-albedo test-backend --- ftw/docker-compose.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/ftw/docker-compose.yml b/ftw/docker-compose.yml index 4f31e15..7399ca5 100644 --- a/ftw/docker-compose.yml +++ b/ftw/docker-compose.yml @@ -28,7 +28,6 @@ services: - ../build:/build:rw ports: - 9000:9000 - restart: unless-stopped haproxy: depends_on: From 177554569d781ac82e00ef3a7146fc1cc2923519 Mon Sep 17 00:00:00 2001 From: Rath Pascal Date: Mon, 6 Jan 2025 13:00:20 +0100 Subject: [PATCH 11/14] test: enable ftw-albedo test-backend --- ftw/coraza-spoa.yaml | 4 + ftw/docker-compose.yml | 2 +- ftw/ftw.yml | 270 ---------------------------------------- ftw/haproxy/coraza.cfg | 2 +- ftw/haproxy/haproxy.cfg | 3 +- 5 files changed, 7 insertions(+), 274 deletions(-) diff --git a/ftw/coraza-spoa.yaml b/ftw/coraza-spoa.yaml index 16b98ac..19aae22 100644 --- a/ftw/coraza-spoa.yaml +++ b/ftw/coraza-spoa.yaml @@ -9,6 +9,10 @@ applications: - name: ftw directives: | Include @coraza.conf-recommended + # log details on failures + SecAuditLog /build/ftw-audit.log + SecAuditLogRelevantStatus "^(?:5)" + # FTW config SecDefaultAction "phase:3,log,auditlog,pass" SecDefaultAction "phase:4,log,auditlog,pass" diff --git a/ftw/docker-compose.yml b/ftw/docker-compose.yml index 7399ca5..e338bc9 100644 --- a/ftw/docker-compose.yml +++ b/ftw/docker-compose.yml @@ -13,7 +13,7 @@ services: command: - /bin/sh - -c - - rm -f /build/ftw* && touch /build/ftw.log /build/ftw-haproxy.log /build/ftw-haproxy.log && chmod 666 /build/ftw* + - rm -f /build/ftw* && touch /build/ftw.log /build/ftw-haproxy.log /build/ftw-haproxy.log /build/ftw-audit.log && chmod 666 /build/ftw* volumes: - ../build:/build:rw diff --git a/ftw/ftw.yml b/ftw/ftw.yml index 2ed8d62..a7f7282 100644 --- a/ftw/ftw.yml +++ b/ftw/ftw.yml @@ -22,273 +22,3 @@ testoverride: 920620-1: 'Rule checks if multiple Content-Type headers are kepts. Go/http might keep them and trigger the rule. Run and check it.' # TODO investigate failing tests: - 920100-10: '' - 920100-14: '' - 920100-16: '' - 920180-1: '' - 920180-3: '' - 920190-2: '' - 920190-3: '' - 920200-1: '' - 920200-2: '' - 920200-4: '' - 920200-5: '' - 920200-6: '' - 920200-8: '' - 920201-1: '' - 920201-2: '' - 920202-1: '' - 920202-2: '' - 920210-2: '' - 920210-3: '' - 920210-4: '' - 920210-6: '' - 920210-7: '' - 920220-1: '' - 920220-2: '' - 920220-5: '' - 920220-6: '' - 920221-1: '' - 920230-1: '' - 920240-1: '' - 920240-5: '' - 920240-6: '' - 920250-1: '' - 920250-2: '' - 920250-3: '' - 920250-4: '' - 920260-1: '' - 920260-3: '' - 920270-4: '' - 920274-1: '' - 920280-1: '' - 920290-1: '' - 920290-4: '' - 920300-1: '' - 920310-1: '' - 920310-4: '' - 920311-1: '' - 920320-1: '' - 920330-1: '' - 920340-1: '' - 920340-2: '' - 920350-1: '' - 920350-3: '' - 920350-4: '' - 920350-5: '' - 920350-6: '' - 920390-1: '' - 920410-1: '' - 920420-15: '' - 920420-16: '' - 920420-17: '' - 920520-8: '' - 920520-9: '' - 921240-2: '' - 922100-3: '' - 932130-17: '' - 932131-2: '' - 932160-11: '' - 932160-12: '' - 932160-13: '' - 932175-10: '' - 932175-11: '' - 932175-12: '' - 932175-13: '' - 932175-14: '' - 932175-15: '' - 932190-5: '' - 932190-6: '' - 932205-7: '' - 932230-50: '' - 932230-51: '' - 932230-52: '' - 932230-53: '' - 932230-56: '' - 932230-57: '' - 932230-58: '' - 932235-11: '' - 932235-13: '' - 932235-14: '' - 932235-15: '' - 932235-16: '' - 932235-19: '' - 932235-20: '' - 932235-21: '' - 932235-22: '' - 932235-23: '' - 932235-24: '' - 932235-25: '' - 932235-26: '' - 932235-27: '' - 932235-28: '' - 932235-29: '' - 932235-30: '' - 932235-32: '' - 932235-33: '' - 932235-34: '' - 932235-35: '' - 932235-36: '' - 932235-37: '' - 932236-44: '' - 932236-45: '' - 932236-46: '' - 932236-47: '' - 932236-48: '' - 932236-49: '' - 932236-62: '' - 932236-63: '' - 932236-65: '' - 932236-66: '' - 932236-67: '' - 932236-68: '' - 932236-69: '' - 932236-70: '' - 932236-71: '' - 932236-72: '' - 932236-74: '' - 932236-75: '' - 932236-76: '' - 932236-77: '' - 932236-78: '' - 932236-79: '' - 932236-80: '' - 932237-1: '' - 932237-6: '' - 932237-15: '' - 932237-16: '' - 932237-19: '' - 932237-20: '' - 932237-22: '' - 932237-23: '' - 932237-24: '' - 932237-25: '' - 932237-26: '' - 932237-28: '' - 932237-29: '' - 932237-30: '' - 932237-31: '' - 932237-32: '' - 932237-33: '' - 932237-34: '' - 932238-3: '' - 932238-4: '' - 932238-5: '' - 932238-6: '' - 932238-9: '' - 932238-10: '' - 932239-20: '' - 932239-21: '' - 932239-22: '' - 932239-23: '' - 932239-24: '' - 932239-25: '' - 932239-38: '' - 932239-39: '' - 932239-40: '' - 932239-41: '' - 932239-42: '' - 932239-43: '' - 932239-44: '' - 932239-45: '' - 932239-47: '' - 932239-48: '' - 932239-49: '' - 932239-50: '' - 932239-51: '' - 932239-52: '' - 932239-53: '' - 932240-16: '' - 932240-18: '' - 932260-24: '' - 932260-25: '' - 932260-27: '' - 932260-28: '' - 932260-29: '' - 932260-30: '' - 932260-31: '' - 932260-32: '' - 932260-33: '' - 932260-34: '' - 932260-35: '' - 932260-36: '' - 932260-37: '' - 932260-38: '' - 932260-39: '' - 932260-40: '' - 932260-41: '' - 932260-42: '' - 932260-43: '' - 932260-44: '' - 932260-45: '' - 932380-9: '' - 933100-5: '' - 933100-6: '' - 933100-7: '' - 933100-8: '' - 933151-6: '' - 933160-9: '' - 933160-10: '' - 933160-12: '' - 933160-14: '' - 933160-15: '' - 933160-16: '' - 933160-29: '' - 934120-23: '' - 934120-24: '' - 934120-25: '' - 934120-26: '' - 934120-39: '' - 941160-16: '' - 941390-8: '' - 941390-9: '' - 942190-42: '' - 942190-44: '' - 942420-1: '' - 942421-1: '' - 942430-1: '' - 942431-1: '' - 942432-1: '' - 942440-19: '' - 942440-20: '' - 942460-1: '' - 942500-3: '' - 942500-4: '' - 942560-1: '' - 951110-1: '' - 951120-1: '' - 951130-1: '' - 951140-1: '' - 951150-1: '' - 951160-1: '' - 951170-1: '' - 951180-1: '' - 951190-1: '' - 951200-1: '' - 951210-1: '' - 951220-1: '' - 951220-2: '' - 951230-1: '' - 951230-2: '' - 951240-1: '' - 951240-2: '' - 951250-1: '' - 951260-1: '' - 953101-1: '' - 953101-2: '' - 953101-3: '' - 953101-4: '' - 953101-5: '' - 953120-1: '' - 953120-3: '' - 953120-5: '' - 953120-7: '' - 954100-1: '' - 954120-1: '' - 954120-2: '' - 955100-1: '' - 955100-2: '' - 955100-3: '' - 955260-1: '' - 959100-1: '' - 959100-3: '' diff --git a/ftw/haproxy/coraza.cfg b/ftw/haproxy/coraza.cfg index bc1fc13..9ad0a67 100644 --- a/ftw/haproxy/coraza.cfg +++ b/ftw/haproxy/coraza.cfg @@ -17,7 +17,7 @@ spoe-message coraza-req spoe-message coraza-res args app=str(ftw) id=var(txn.coraza.id) version=res.ver status=status headers=res.hdrs body=res.body - event on-http-response + # event on-http-response spoe-group coraza-req messages coraza-req diff --git a/ftw/haproxy/haproxy.cfg b/ftw/haproxy/haproxy.cfg index 879a974..063da77 100644 --- a/ftw/haproxy/haproxy.cfg +++ b/ftw/haproxy/haproxy.cfg @@ -38,8 +38,7 @@ resolvers host_dns backend test mode http - http-request return status 200 - # server test backend:8081 + server test backend:8081 backend coraza-spoa mode tcp From dfdf34c6c4ed85b668e2e0ac26af6eee854f20c4 Mon Sep 17 00:00:00 2001 From: Rath Pascal Date: Mon, 6 Jan 2025 13:56:08 +0100 Subject: [PATCH 12/14] test: add ftw multi-version support --- .github/workflows/ftw.yaml | 6 ++++++ ftw/docker-compose.yml | 2 +- magefile.go | 13 +++++++------ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ftw.yaml b/.github/workflows/ftw.yaml index fb5c536..1aef8dc 100644 --- a/.github/workflows/ftw.yaml +++ b/.github/workflows/ftw.yaml @@ -8,6 +8,10 @@ on: jobs: test: + strategy: + matrix: + haproxy-version: [3.1] # 3.0, 2.8 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -19,6 +23,8 @@ jobs: - name: Run regression tests (ftw) run: go run mage.go ftw + env: + FTW_HAPROXY_VERSION: "${{ matrix.haproxy-version }}" - uses: actions/upload-artifact@v4 if: success() || failure() diff --git a/ftw/docker-compose.yml b/ftw/docker-compose.yml index e338bc9..2573c01 100644 --- a/ftw/docker-compose.yml +++ b/ftw/docker-compose.yml @@ -33,7 +33,7 @@ services: depends_on: - prepare-logs - backend - image: haproxy:3.1-alpine + image: "haproxy:${FTW_HAPROXY_VERSION-3.1}-alpine" links: - coraza-spoa:coraza-spoa volumes: diff --git a/magefile.go b/magefile.go index e7bdfcc..d113db4 100644 --- a/magefile.go +++ b/magefile.go @@ -160,16 +160,17 @@ func Check() { // Ftw runs CRS regressions tests. Requires docker. func Ftw() error { - if err := sh.RunV("docker", "compose", "--file", "ftw/docker-compose.yml", "build", "--pull", "--no-cache"); err != nil { + env := map[string]string{ + "FTW_CLOUDMODE": os.Getenv("FTW_CLOUDMODE"), + "FTW_INCLUDE": os.Getenv("FTW_INCLUDE"), + "FTW_HAPROXY_VERSION": os.Getenv("FTW_HAPROXY_VERSION"), + } + if err := sh.RunWithV(env, "docker", "compose", "--file", "ftw/docker-compose.yml", "build", "--pull", "--no-cache"); err != nil { return err } defer func() { - _ = sh.RunV("docker", "compose", "--file", "ftw/docker-compose.yml", "down", "-v") + _ = sh.RunWithV(env, "docker", "compose", "--file", "ftw/docker-compose.yml", "down", "-v") }() - env := map[string]string{ - "FTW_CLOUDMODE": os.Getenv("FTW_CLOUDMODE"), - "FTW_INCLUDE": os.Getenv("FTW_INCLUDE"), - } return sh.RunWithV(env, "docker", "compose", "--file", "ftw/docker-compose.yml", "run", "--rm", "ftw") } From b8cd1f583bad9830cfb94964db89cb0fe340bb99 Mon Sep 17 00:00:00 2001 From: Rath Pascal Date: Wed, 8 Jan 2025 16:28:17 +0100 Subject: [PATCH 13/14] test: enabled ftw response-checks with HAProxy version 3.0 --- .github/workflows/ftw.yaml | 2 +- ftw/coraza-spoa.yaml | 2 +- ftw/docker-compose.yml | 2 +- ftw/ftw.yml | 234 +++++++++++++++++++++++++++++++++++++ ftw/haproxy/coraza.cfg | 2 +- ftw/haproxy/haproxy.cfg | 2 +- 6 files changed, 239 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ftw.yaml b/.github/workflows/ftw.yaml index 1aef8dc..7b98b22 100644 --- a/.github/workflows/ftw.yaml +++ b/.github/workflows/ftw.yaml @@ -10,7 +10,7 @@ jobs: test: strategy: matrix: - haproxy-version: [3.1] # 3.0, 2.8 + haproxy-version: [3.0] # 3.1, 3.0, 2.8 runs-on: ubuntu-latest steps: diff --git a/ftw/coraza-spoa.yaml b/ftw/coraza-spoa.yaml index 19aae22..f90bf52 100644 --- a/ftw/coraza-spoa.yaml +++ b/ftw/coraza-spoa.yaml @@ -45,7 +45,7 @@ applications: Include @crs-setup.conf.example Include @owasp_crs/*.conf - response_check: false + response_check: true transaction_ttl_ms: 60000 log_level: error # Printing only logs at error level to reduce what ftw has to parse log_file: /build/ftw.log diff --git a/ftw/docker-compose.yml b/ftw/docker-compose.yml index 2573c01..f747bf0 100644 --- a/ftw/docker-compose.yml +++ b/ftw/docker-compose.yml @@ -33,7 +33,7 @@ services: depends_on: - prepare-logs - backend - image: "haproxy:${FTW_HAPROXY_VERSION-3.1}-alpine" + image: "haproxy:${FTW_HAPROXY_VERSION-3.0}-alpine" links: - coraza-spoa:coraza-spoa volumes: diff --git a/ftw/ftw.yml b/ftw/ftw.yml index a7f7282..3ae4a93 100644 --- a/ftw/ftw.yml +++ b/ftw/ftw.yml @@ -22,3 +22,237 @@ testoverride: 920620-1: 'Rule checks if multiple Content-Type headers are kepts. Go/http might keep them and trigger the rule. Run and check it.' # TODO investigate failing tests: + 920100-10: '' + 920100-14: '' + 920100-16: '' + 920180-1: '' + 920180-3: '' + 920190-2: '' + 920190-3: '' + 920200-1: '' + 920200-2: '' + 920200-4: '' + 920200-5: '' + 920200-6: '' + 920200-8: '' + 920201-1: '' + 920201-2: '' + 920202-1: '' + 920202-2: '' + 920210-2: '' + 920210-3: '' + 920210-4: '' + 920210-6: '' + 920210-7: '' + 920220-1: '' + 920220-2: '' + 920220-5: '' + 920220-6: '' + 920221-1: '' + 920230-1: '' + 920240-1: '' + 920240-5: '' + 920240-6: '' + 920250-1: '' + 920250-2: '' + 920250-3: '' + 920250-4: '' + 920260-1: '' + 920260-3: '' + 920270-4: '' + 920274-1: '' + 920280-1: '' + 920290-1: '' + 920290-4: '' + 920300-1: '' + 920310-1: '' + 920310-4: '' + 920311-1: '' + 920320-1: '' + 920330-1: '' + 920340-1: '' + 920340-2: '' + 920350-1: '' + 920350-3: '' + 920350-4: '' + 920350-5: '' + 920350-6: '' + 920390-1: '' + 920410-1: '' + 920420-15: '' + 920420-16: '' + 920420-17: '' + 920520-8: '' + 920520-9: '' + 921240-2: '' + 922100-3: '' + 932130-17: '' + 932131-2: '' + 932160-11: '' + 932160-12: '' + 932160-13: '' + 932175-10: '' + 932175-11: '' + 932175-12: '' + 932175-13: '' + 932175-14: '' + 932175-15: '' + 932190-5: '' + 932190-6: '' + 932205-7: '' + 932230-50: '' + 932230-51: '' + 932230-52: '' + 932230-53: '' + 932230-56: '' + 932230-57: '' + 932230-58: '' + 932235-11: '' + 932235-13: '' + 932235-14: '' + 932235-15: '' + 932235-16: '' + 932235-19: '' + 932235-20: '' + 932235-21: '' + 932235-22: '' + 932235-23: '' + 932235-24: '' + 932235-25: '' + 932235-26: '' + 932235-27: '' + 932235-28: '' + 932235-29: '' + 932235-30: '' + 932235-32: '' + 932235-33: '' + 932235-34: '' + 932235-35: '' + 932235-36: '' + 932235-37: '' + 932236-44: '' + 932236-45: '' + 932236-46: '' + 932236-47: '' + 932236-48: '' + 932236-49: '' + 932236-62: '' + 932236-63: '' + 932236-65: '' + 932236-66: '' + 932236-67: '' + 932236-68: '' + 932236-69: '' + 932236-70: '' + 932236-71: '' + 932236-72: '' + 932236-74: '' + 932236-75: '' + 932236-76: '' + 932236-77: '' + 932236-78: '' + 932236-79: '' + 932236-80: '' + 932237-1: '' + 932237-6: '' + 932237-15: '' + 932237-16: '' + 932237-19: '' + 932237-20: '' + 932237-22: '' + 932237-23: '' + 932237-24: '' + 932237-25: '' + 932237-26: '' + 932237-28: '' + 932237-29: '' + 932237-30: '' + 932237-31: '' + 932237-32: '' + 932237-33: '' + 932237-34: '' + 932238-3: '' + 932238-4: '' + 932238-5: '' + 932238-6: '' + 932238-9: '' + 932238-10: '' + 932239-20: '' + 932239-21: '' + 932239-22: '' + 932239-23: '' + 932239-24: '' + 932239-25: '' + 932239-38: '' + 932239-39: '' + 932239-40: '' + 932239-41: '' + 932239-42: '' + 932239-43: '' + 932239-44: '' + 932239-45: '' + 932239-47: '' + 932239-48: '' + 932239-49: '' + 932239-50: '' + 932239-51: '' + 932239-52: '' + 932239-53: '' + 932240-16: '' + 932240-18: '' + 932260-24: '' + 932260-25: '' + 932260-27: '' + 932260-28: '' + 932260-29: '' + 932260-30: '' + 932260-31: '' + 932260-32: '' + 932260-33: '' + 932260-34: '' + 932260-35: '' + 932260-36: '' + 932260-37: '' + 932260-38: '' + 932260-39: '' + 932260-40: '' + 932260-41: '' + 932260-42: '' + 932260-43: '' + 932260-44: '' + 932260-45: '' + 932380-9: '' + 933100-5: '' + 933100-6: '' + 933100-7: '' + 933100-8: '' + 933151-6: '' + 933160-9: '' + 933160-10: '' + 933160-12: '' + 933160-14: '' + 933160-15: '' + 933160-16: '' + 933160-29: '' + 934120-23: '' + 934120-24: '' + 934120-25: '' + 934120-26: '' + 934120-39: '' + 941160-16: '' + 941390-8: '' + 941390-9: '' + 942190-42: '' + 942190-44: '' + 942420-1: '' + 942421-1: '' + 942430-1: '' + 942431-1: '' + 942432-1: '' + 942440-19: '' + 942440-20: '' + 942460-1: '' + 942500-3: '' + 942500-4: '' + 942560-1: '' + 953101-5: '' diff --git a/ftw/haproxy/coraza.cfg b/ftw/haproxy/coraza.cfg index 9ad0a67..bc1fc13 100644 --- a/ftw/haproxy/coraza.cfg +++ b/ftw/haproxy/coraza.cfg @@ -17,7 +17,7 @@ spoe-message coraza-req spoe-message coraza-res args app=str(ftw) id=var(txn.coraza.id) version=res.ver status=status headers=res.hdrs body=res.body - # event on-http-response + event on-http-response spoe-group coraza-req messages coraza-req diff --git a/ftw/haproxy/haproxy.cfg b/ftw/haproxy/haproxy.cfg index 063da77..572d2a9 100644 --- a/ftw/haproxy/haproxy.cfg +++ b/ftw/haproxy/haproxy.cfg @@ -12,7 +12,7 @@ defaults frontend default mode http bind *:8080 - log-format "%ci:%cp\ [%t]\ %ft\ %b/%s\ %Th/%Ti/%TR/%Tq/%Tw/%Tc/%Tr/%Tt\ %ST\ %B\ %CC\ %CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ %{+Q}r\ %[var(txn.coraza.id)]\ spoa-error:\ %[var(txn.coraza.error)]\ waf-hit:\ %[var(txn.coraza.fail)] waf-action:\ %[var(txn.coraza.action)]" + log-format "%ci:%cp\ [%t]\ %ft\ %b/%s\ %Th/%Ti/%TR/%Tq/%Tw/%Tc/%Tr/%Tt\ %ST\ %B\ %CC\ %CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ %{+Q}r\ %[var(txn.coraza.id)]\ spoa-error:\ %[var(txn.coraza.error)]\ waf-hit:\ %[var(txn.coraza.fail)] waf-action:\ %[var(txn.coraza.action)] waf-data:\ %[var(txn.coraza.data)]" filter spoe engine coraza config /usr/local/etc/haproxy/coraza.cfg http-request send-spoe-group coraza coraza-req From f7b722e2706066a6208ad01f86a59c014748b52d Mon Sep 17 00:00:00 2001 From: Rath Pascal Date: Wed, 8 Jan 2025 16:54:37 +0100 Subject: [PATCH 14/14] test: enable ftw-tests for haproxy-2.8 --- .github/workflows/ftw.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ftw.yaml b/.github/workflows/ftw.yaml index 7b98b22..083f35b 100644 --- a/.github/workflows/ftw.yaml +++ b/.github/workflows/ftw.yaml @@ -10,7 +10,7 @@ jobs: test: strategy: matrix: - haproxy-version: [3.0] # 3.1, 3.0, 2.8 + haproxy-version: [3.0, 2.8] # 3.1 runs-on: ubuntu-latest steps: