diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..22d9af7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +FROM caddy:2.7-builder AS builder + +COPY ./fail2ban.go /src/caddy-fail2ban/ +COPY ./go.sum /src/caddy-fail2ban/ +COPY ./go.mod /src/caddy-fail2ban/ +RUN xcaddy build \ + --with github.com/Javex/caddy-fail2ban=/src/caddy-fail2ban + +FROM caddy:2.7 + +COPY --from=builder /usr/bin/caddy /usr/bin/caddy + +RUN apk update && apk add fail2ban curl bash +RUN rm /etc/fail2ban/jail.d/alpine-ssh.conf +COPY ./fail2ban/caddy-banfile.conf /etc/fail2ban/action.d/caddy-banfile.conf +COPY ./test/caddy-test.local /etc/fail2ban/jail.d/caddy-test.local +COPY ./test/caddy-fail2ban-test.sh /usr/local/bin/ +RUN chmod u+x /usr/local/bin/caddy-fail2ban-test.sh + diff --git a/README.md b/README.md index 33099f8..e0462c5 100644 --- a/README.md +++ b/README.md @@ -36,4 +36,20 @@ Now in any of your jails if you want to block requests at the HTTP layer, you ca action = caddy-banfile[banfile_path="/etc/caddy/banned-ips"] ``` -The above path is the default so you can omit the `banfile_path` parameter if you like. \ No newline at end of file +The above path is the default so you can omit the `banfile_path` parameter if you like. + +## Running tests + +First run the go unit tests, then spin up a docker container to test the +integration with fail2ban + +``` +go build -v ./... +go test -v ./... + +sudo docker build . -t caddy-fail2ban +sudo docker run --rm --name caddy-fail2ban --detach -v $PWD/test/Caddyfile:/etc/caddy/Caddyfile caddy-fail2ban +sudo docker exec -it caddy-fail2ban /usr/local/bin/caddy-fail2ban-test.sh +sudo docker logs caddy-fail2ban +sudo docker stop caddy-fail2ban +``` diff --git a/test/Caddyfile b/test/Caddyfile new file mode 100644 index 0000000..8c167f1 --- /dev/null +++ b/test/Caddyfile @@ -0,0 +1,15 @@ +{ + log { + level DEBUG + } +} + +127.0.0.1:80 { + @banned { + fail2ban /srv/banned-ips + } + handle @banned { + abort + } + respond "ok" +} diff --git a/test/caddy-fail2ban-test.sh b/test/caddy-fail2ban-test.sh new file mode 100644 index 0000000..685b260 --- /dev/null +++ b/test/caddy-fail2ban-test.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +set -euo pipefail + +fail2ban-server +sleep 1 + +output=$(curl http://127.0.0.1) +if [ "$output" != "ok" ]; then + echo "Expected 'ok' output, got '${output}'" + exit 1 +fi + +fail2ban-client set caddy_test banip 127.0.0.1 + +set +e +curl http://127.0.0.1 +curl_exit_code=$? +set -e +if [ $curl_exit_code -eq 0 ]; then + echo "Expected curl to exit with non-zero exit code, but it was successful"; + exit 1 +fi + +echo "Success!" +exit 0 diff --git a/test/caddy-test.local b/test/caddy-test.local new file mode 100644 index 0000000..bc68c0e --- /dev/null +++ b/test/caddy-test.local @@ -0,0 +1,10 @@ +[caddy_test] +backend = auto +enabled = true +port = 80,443 +protocol = tcp +filter = bitwarden +maxretry = 3 +bantime = 86400 +findtime = 43200 +action = caddy-banfile[banfile_path="/srv/banned-ips"]