Skip to content

Commit

Permalink
Merge branch 'main' into sts_fix_debian_packge
Browse files Browse the repository at this point in the history
  • Loading branch information
jptosso authored May 13, 2023
2 parents a55e308 + d615d83 commit c3530fc
Show file tree
Hide file tree
Showing 27 changed files with 757 additions and 417 deletions.
85 changes: 71 additions & 14 deletions .github/workflows/container-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ on:
pull_request:
workflow_dispatch:


env:
HAPROXY_IMAGES: >
haproxy:2.2-alpine
haproxy:2.4-alpine
haproxy:2.5-alpine
haproxy:2.6-alpine
haproxy:2.7-alpine
jobs:
build:
runs-on: ubuntu-latest
Expand All @@ -21,20 +30,24 @@ jobs:
- name: Check out code
uses: actions/checkout@v3

- name: Run e2e tests against the example
shell: bash
run: >
for image in $HAPROXY_IMAGES; do
echo "Running e2e with Haproxy image $image"
HAPROXY_IMAGE=$image docker compose -f docker-compose.e2e.yaml up --abort-on-container-exit tests
done
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: |
ghcr.io/${{ github.repository }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}
- name: Inspect builder
run: |
echo "Name: ${{ steps.buildx.outputs.name }}"
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
echo "Status: ${{ steps.buildx.outputs.status }}"
echo "Flags: ${{ steps.buildx.outputs.flags }}"
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
- name: Login to GHCR
uses: docker/login-action@v2
Expand All @@ -43,12 +56,56 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
- name: Docker metadata - Main
id: meta-main
uses: docker/metadata-action@v4
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=raw,value=snapshot,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=ref,event=branch
type=ref,event=pr
- name: Image - Main
uses: docker/build-push-action@v3
with:
context: .
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64
file: Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ steps.meta-main.outputs.tags }}
labels: ${{ steps.meta-main.outputs.labels }}


- name: Docker metadata - CRS4
id: meta-crs4
uses: docker/metadata-action@v4
with:
images: ghcr.io/${{ github.repository }}
flavor: |
suffix=-crs4,onlatest=true
tags: |
type=raw,value=snapshot,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=ref,event=branch
type=ref,event=pr
- name: Image - CRS4
uses: docker/build-push-action@v3
with:
context: .
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64
file: Dockerfile
push: ${{ github.event_name != 'pull_request' }}
target: coreruleset
build-args: |
CORERULESET_VERSION=v4.0.0-rc1
tags: ${{ steps.meta-crs4.outputs.tags }}
labels: ${{ steps.meta-crs4.outputs.labels }}
33 changes: 7 additions & 26 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -1,35 +1,16 @@
name: "Code Linting"
name: Lint (pre-commit)

on:
pull_request:
branches:
- "*"
push:
branches:
- "*"

jobs:
pre-commit:
lint:
runs-on: ubuntu-latest
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: v1.17.x

- name: Install dependencies
run: |
cd /tmp && go install github.com/go-critic/go-critic/cmd/gocritic@latest
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.43.0
go install golang.org/x/lint/golint@latest
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
- uses: actions/checkout@v3
- uses: actions/setup-python@v2

- name: Fix up git URLs
run: echo -e '[url "https://github.com/"]\n insteadOf = "git://github.com/"' >> ~/.gitconfig

- uses: pre-commit/[email protected]
- name: Install Go
uses: actions/setup-go@v3
with:
extra_args: --all-files
go-version: v1.18.x
cache: true
- run: go run mage.go lint
15 changes: 0 additions & 15 deletions .pre-commit-config.yaml

This file was deleted.

2 changes: 2 additions & 0 deletions .pre-commit.hook
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
echo "Executing precommit checks"
go run mage.go check
119 changes: 72 additions & 47 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,56 +1,81 @@
FROM golang:1.19.1-alpine3.16 AS build
# Copyright 2023 The OWASP Coraza contributors
# SPDX-License-Identifier: Apache-2.0

# Specify Coreruleset version to download
ARG CORERULESET_VERSION=v4.0.0-rc1
ARG CORERULESET_MD5=9140236dc7e941c274e414385824c996

# Change working directory
WORKDIR /app

RUN \
apk add --no-cache \
# Install make to build coraza-spoa binary from makefile
make \
# Download and set up Coreruleset
&& wget -qO/tmp/coreruleset.tar.gz https://github.com/coreruleset/coreruleset/archive/${CORERULESET_VERSION}.tar.gz \
&& echo "$CORERULESET_MD5 /tmp/coreruleset.tar.gz" | md5sum -c \
&& mkdir -p /tmp/coraza-coreruleset \
&& mkdir -p /etc/coraza-spoa/rules \
&& tar xzf /tmp/coreruleset.tar.gz --strip-components=1 -C /tmp/coraza-coreruleset \
&& mv /tmp/coraza-coreruleset/crs-setup.conf.example /etc/coraza-spoa/crs-setup.conf \
&& mv /tmp/coraza-coreruleset/rules /etc/coraza-spoa \
&& mv /tmp/coraza-coreruleset/plugins /etc/coraza-spoa \
&& rm -rf /tmp/*

# Cache Go dependencies
COPY go.mod go.sum ./
FROM --platform=$BUILDPLATFORM golang:1.19-alpine3.17 AS builder

WORKDIR /build
COPY . /build

# Download dependencies for all platforms once
RUN go mod download

# Copy project files into build image
COPY . .
ARG TARGETOS
ARG TARGETARCH

RUN apk add --no-cache make ca-certificates \
&& update-ca-certificates

RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg \
OS=${TARGETOS} ARCH=${TARGETARCH} make

# ---
FROM alpine:3.17 AS main

ARG TARGETARCH

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"

RUN apk add --no-cache tini socat ca-certificates \
&& update-ca-certificates

# Build coraza-spoa binary
RUN make
# Add unprivileged user & group for the coraza-spoa
RUN addgroup --system coraza-spoa \
&& adduser --system --ingroup coraza-spoa --no-create-home --home /nonexistent --disabled-password coraza-spoa

RUN mkdir -p /etc/coraza-spoa /var/log/coraza-spoa \
&& chown coraza-spoa:coraza-spoa /var/log/coraza-spoa

COPY --from=builder /build/coraza-spoa_${TARGETARCH} /usr/bin/coraza-spoa
COPY --from=builder /build/config.yaml.default /etc/coraza-spoa/config.yaml
COPY --from=builder /build/docker/coraza-spoa/coraza.conf /etc/coraza-spoa/coraza.conf
COPY --from=builder /build/docker/coraza-spoa/docker-entrypoint.sh /docker-entrypoint.sh

EXPOSE 9000
USER coraza-spoa

HEALTHCHECK --interval=10s --timeout=2s --retries=2 CMD "/usr/bin/socat /dev/null TCP:0.0.0.0:9000"

ENTRYPOINT ["tini", "--", "/docker-entrypoint.sh"]

CMD ["/usr/bin/coraza-spoa", "--config", "/etc/coraza-spoa/config.yaml"]

# ---
FROM main AS coreruleset

ARG CORERULESET_VERSION=v4.0.0-rc1
ARG CORERULESET_SHA256SUM=a8f0d1cac941bf2158988b92a91519f093a8bce64a260e46fa352d608c7de3e6

RUN \
# Move coraza-spoa config file to config dir
mv /app/docker/coraza-spoa/coraza.conf /etc/coraza-spoa/coraza.conf \
# Rename coraza-spoa default config file
&& mv /app/config.yaml.default /app/config.yaml \
# Rename coraza-spoa binary
&& mv /app/coraza-spoa_amd64 /app/coraza-spoa \
# Make coraza-spoa binary executable
&& chmod +x /app/coraza-spoa
# Switch to root for crs installation
USER root

# Download the core rule set
RUN set -xe \
&& wget -O /tmp/crs.tgz https://github.com/coreruleset/coreruleset/archive/refs/tags/${CORERULESET_VERSION}.tar.gz

RUN echo "$CORERULESET_SHA256SUM /tmp/crs.tgz" | sha256sum -c

FROM alpine:3.16
# Make directory for coraza-spoa audit and error logs
RUN mkdir -p /var/log/coraza-spoa
# Copy coraza-spoa binary and default config file from build image
COPY --from=build /app/config.yaml /app/coraza-spoa /
# Copy Coreruleset files from build image
COPY --from=build /etc/coraza-spoa /etc/coraza-spoa
RUN set -xe \
&& mkdir crs \
&& tar --strip-components 1 -C crs -xf /tmp/crs.tgz \
&& mv crs/crs-setup.conf.example /etc/coraza-spoa/crs-setup.conf \
&& mv crs/rules /etc/coraza-spoa \
&& if [[ -d crs/plugins ]] ; then mv crs/plugins /etc/coraza-spoa ; fi \
&& rm -rf crs /tmp/crs.tgz

# Container run command
CMD ["/coraza-spoa", "-config", "/config.yaml"]
USER coraza-spoa
31 changes: 23 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
# Owasp Coraza Haproxy

[![Code Linting](https://github.com/corazawaf/coraza-spoa/actions/workflows/lint.yaml/badge.svg)](https://github.com/corazawaf/coraza-spoa/actions/workflows/lint.yaml)
[![CodeQL Scanning](https://github.com/corazawaf/coraza-spoa/actions/workflows/codeql.yaml/badge.svg)](https://github.com/corazawaf/coraza-spoa/actions/workflows/codeql.yaml)

## Overview

This is a third-party daemon that connects to SPOE. It sends the request and response sent by HAProxy to [OWASP Coraza](https://github.com/corazawaf/coraza) and returns the verdict.

## Compilation

### Build

The command `make` will compile the source code and produce the executable file `coraza-spoa`.

### Clean

When you need to re-compile the source code, you can use the command `make clean` to clean the executable file.

## Configuration file

The example configuration file is `config.yaml.default`, you can copy it and modify the related configuration information.

## Start the service

After you have compiled it, you can start the service by running the command `./coraza-spoa`.

```shell
$> ./coraza-spoa -h
Usage of ./coraza-spoa:
Expand All @@ -25,28 +33,34 @@ Usage of ./coraza-spoa:
```

## Configure a SPOE to use the service

Here is the configuration template to use for your SPOE with OWASP Coraza module, you can find it in the [doc/config/coraza.cfg](https://github.com/corazawaf/coraza-spoa/blob/main/doc/config/coraza.cfg):

```editorconfig
[coraza]
spoe-agent coraza-agent
messages coraza-req coraza-res
option var-prefix coraza
timeout hello 100ms
timeout idle 2m
timeout processing 10ms
messages coraza-req coraza-res
option var-prefix coraza
option set-on-error error
timeout hello 100ms
timeout idle 2m
timeout processing 500ms
use-backend coraza-spoa
log global
spoe-message coraza-req
args app=str(sample_app) id=unique-id src-ip=src method=method path=path query=query version=req.ver headers=req.hdrs bodyreq.body
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-res
args app=str(sample_app) id=unique-id version=res.ver status=status headers=res.hdrs body=res.body
event on-http-response
```

Instead of hard coded application name `str(sample_app)` you can use some HAProxy's variable. For example, frontend name `fe_name` or some custom variable.

The engine is in the scope "coraza". So to enable it, you must set the following line in a frontend/listener section:

``` editorconfig
frontend coraza.io
...
Expand All @@ -57,6 +71,7 @@ frontend coraza.io
```

Because, in SPOE configuration file, we declare to use the backend "coraza-spoa" to communicate with the service, so we need to define it in the HAProxy file. For example:

```editorconfig
backend coraza-spoa
mode tcp
Expand All @@ -68,13 +83,13 @@ backend coraza-spoa
```

The OWASP Coraza action is returned in a variable named "txn.coraza.fail". It contains the verdict of the request. If the variable is set to 1, the request will be denied.

```editorconfig
http-request deny if { var(txn.coraza.fail) -m int eq 1 }
http-response deny if { var(txn.coraza.fail) -m int eq 1 }
```
With this rule, all unsafe requests will be rejected. You can find the example HAProxy configuration file in the [doc/config/haproxy.cfg](https://github.com/corazawaf/coraza-spoa/blob/main/doc/config/haproxy.cfg).


With this rule, all unsafe requests will be rejected. You can find the example HAProxy configuration file in the [doc/config/haproxy.cfg](https://github.com/corazawaf/coraza-spoa/blob/main/doc/config/haproxy.cfg).

## Docker

Expand Down
Loading

0 comments on commit c3530fc

Please sign in to comment.