diff --git a/ipabusedb-docker-reporter/.dockerignore b/ipabusedb-docker-reporter/.dockerignore new file mode 100644 index 0000000..df18395 --- /dev/null +++ b/ipabusedb-docker-reporter/.dockerignore @@ -0,0 +1,6 @@ +.env +.git +*.csv +/ipabusedb-docker-reporter +deploy.sh +example_parser_script.py diff --git a/ipabusedb-docker-ssh/.env.example b/ipabusedb-docker-reporter/.env.example similarity index 100% rename from ipabusedb-docker-ssh/.env.example rename to ipabusedb-docker-reporter/.env.example diff --git a/ipabusedb-docker-reporter/.gitignore b/ipabusedb-docker-reporter/.gitignore new file mode 100644 index 0000000..85e9a26 --- /dev/null +++ b/ipabusedb-docker-reporter/.gitignore @@ -0,0 +1,3 @@ +/ipabusedb-docker-reporter +/reports.csv +/.env diff --git a/ipabusedb-docker-reporter/Dockerfile b/ipabusedb-docker-reporter/Dockerfile new file mode 100644 index 0000000..55e46d7 --- /dev/null +++ b/ipabusedb-docker-reporter/Dockerfile @@ -0,0 +1,39 @@ +# syntax=docker/dockerfile:1 +# +# Runs ipabusedb-docker-reporter as a runit service under the baseimage's +# runsvinit: sleep INTERVAL seconds, report the last INTERVAL seconds of +# sshd brute-force attempts to AbuseIPDB, repeat. +# +# Run with the host's docker socket bind-mounted and the config in the +# container environment: +# +# docker run -d --restart unless-stopped \ +# -v /var/run/docker.sock:/var/run/docker.sock \ +# -e DOCKER_CONTAINER_NAME=sshd \ +# -e IPABUSEDB_API_KEY=... \ +# -e INTERVAL=1200 \ +# ipabusedb-docker-reporter + +FROM git.eeqj.de/sneak/baseimage:2026-11-05 + +# The reporter shells out to "docker logs", so it needs the docker CLI. +# The static binary from the official CLI image avoids pulling the whole +# docker.io package (and daemon) in via apt. +COPY --from=docker:cli /usr/local/bin/docker /usr/local/bin/docker + +WORKDIR /src +COPY go.mod go.sum ./ +RUN --mount=type=cache,target=/root/go/pkg/mod go mod download +COPY *.go ./ +RUN --mount=type=cache,target=/root/go/pkg/mod \ + --mount=type=cache,target=/root/.cache/go-build \ + CGO_ENABLED=0 go build -o /usr/local/bin/ipabusedb-docker-reporter . + +COPY sv/ipabusedb-docker-reporter/run /etc/sv/ipabusedb-docker-reporter/run +RUN chmod +x /etc/sv/ipabusedb-docker-reporter/run \ + && ln -s /etc/sv/ipabusedb-docker-reporter /etc/service/ipabusedb-docker-reporter + +# Seconds to sleep between runs; also the --since window of each run. +ENV INTERVAL=1200 + +WORKDIR / diff --git a/ipabusedb-docker-ssh/Makefile b/ipabusedb-docker-reporter/Makefile similarity index 62% rename from ipabusedb-docker-ssh/Makefile rename to ipabusedb-docker-reporter/Makefile index b299a59..ce97888 100644 --- a/ipabusedb-docker-ssh/Makefile +++ b/ipabusedb-docker-reporter/Makefile @@ -1,10 +1,13 @@ -BIN := ipabusedb-docker-ssh +BIN := ipabusedb-docker-reporter -.PHONY: build test lint fmt fmt-check check clean +.PHONY: build test lint fmt fmt-check check clean image build: go build -o $(BIN) . +image: + docker build -t $(BIN) . + test: go test ./... @@ -20,4 +23,4 @@ lint: fmt-check check: lint test build clean: - rm -f $(BIN) + rm -f $(BIN) *.csv diff --git a/ipabusedb-docker-ssh/README.md b/ipabusedb-docker-reporter/README.md similarity index 71% rename from ipabusedb-docker-ssh/README.md rename to ipabusedb-docker-reporter/README.md index c7e47b9..470cacf 100644 --- a/ipabusedb-docker-ssh/README.md +++ b/ipabusedb-docker-reporter/README.md @@ -62,6 +62,35 @@ Submitting manually with curl instead of `--submit`: $ ./ipabusedb-docker-ssh --since 24h > reports.csv && curl https://api.abuseipdb.com/api/v2/bulk-report -F csv=@reports.csv -H "Key: $IPABUSEDB_API_KEY" ``` +## Running as a container + +The `Dockerfile` builds on `git.eeqj.de/sneak/baseimage` and installs the +program as a runit service (`sv/ipabusedb-docker-reporter/run`) that +sleeps `INTERVAL` seconds, then runs the reporter with +`--since ${INTERVAL}s --submit`, and repeats. The docker CLI is copied in +from the `docker:cli` image so the program can read logs through the +host's docker socket. + +| Variable | Purpose | +| ----------------------- | -------------------------------------------------- | +| `DOCKER_CONTAINER_NAME` | container whose logs are read (required) | +| `IPABUSEDB_API_KEY` | AbuseIPDB API key (required) | +| `INTERVAL` | seconds between runs, and the report window (1200) | + +``` +$ make image +$ docker run -d --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -e DOCKER_CONTAINER_NAME=sshd \ + -e IPABUSEDB_API_KEY=... \ + -e INTERVAL=1200 \ + ipabusedb-docker-reporter +``` + +Each run's CSV and the AbuseIPDB response go to the container log. If a +required variable is missing the service logs an error, sleeps a minute +and exits so runit can retry. + `make check` runs vet, the tests and the build. `loglines_example.txt` holds sample `docker logs -t` output used by the tests; `example_parser_script.py` is the reference script from AbuseIPDB that diff --git a/ipabusedb-docker-reporter/deploy.sh b/ipabusedb-docker-reporter/deploy.sh new file mode 100755 index 0000000..87940ff --- /dev/null +++ b/ipabusedb-docker-reporter/deploy.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +BIN="ipabusedb-docker-reporter" + +DH="root@fsn1app1" + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +cd "$DIR" + +rsync -avP --delete ./ "$DH":/tmp/reporterdeploy/ + +#ssh $DH "cd /tmp/reporterdeploy && go get -v && go build -o ./${BIN} . && ls -tla" +ssh $DH "cd /tmp/reporterdeploy && go get -v && go build . && ls -tla && mv ./${BIN} /usr/local/sbin" diff --git a/ipabusedb-docker-ssh/example_parser_script.py b/ipabusedb-docker-reporter/example_parser_script.py similarity index 100% rename from ipabusedb-docker-ssh/example_parser_script.py rename to ipabusedb-docker-reporter/example_parser_script.py diff --git a/ipabusedb-docker-reporter/go.mod b/ipabusedb-docker-reporter/go.mod new file mode 100644 index 0000000..64bde10 --- /dev/null +++ b/ipabusedb-docker-reporter/go.mod @@ -0,0 +1,5 @@ +module sneak.berlin/go/hacks/ipabusedb-docker-reporter + +go 1.26.5 + +require github.com/joho/godotenv v1.5.1 diff --git a/ipabusedb-docker-ssh/go.sum b/ipabusedb-docker-reporter/go.sum similarity index 100% rename from ipabusedb-docker-ssh/go.sum rename to ipabusedb-docker-reporter/go.sum diff --git a/ipabusedb-docker-ssh/loglines_example.txt b/ipabusedb-docker-reporter/loglines_example.txt similarity index 100% rename from ipabusedb-docker-ssh/loglines_example.txt rename to ipabusedb-docker-reporter/loglines_example.txt diff --git a/ipabusedb-docker-ssh/main.go b/ipabusedb-docker-reporter/main.go similarity index 100% rename from ipabusedb-docker-ssh/main.go rename to ipabusedb-docker-reporter/main.go diff --git a/ipabusedb-docker-ssh/main_test.go b/ipabusedb-docker-reporter/main_test.go similarity index 100% rename from ipabusedb-docker-ssh/main_test.go rename to ipabusedb-docker-reporter/main_test.go diff --git a/ipabusedb-docker-reporter/sv/ipabusedb-docker-reporter/run b/ipabusedb-docker-reporter/sv/ipabusedb-docker-reporter/run new file mode 100644 index 0000000..6371a5e --- /dev/null +++ b/ipabusedb-docker-reporter/sv/ipabusedb-docker-reporter/run @@ -0,0 +1,33 @@ +#!/bin/sh +# runit service: sleep INTERVAL seconds (default 1200), then report the +# last INTERVAL seconds of sshd brute-force attempts from the logs of +# DOCKER_CONTAINER_NAME to AbuseIPDB. runit restarts this script when it +# exits, so one invocation is one iteration of the loop. +# +# Configuration comes from the container environment: +# DOCKER_CONTAINER_NAME container whose logs are read (required) +# IPABUSEDB_API_KEY AbuseIPDB API key (required) +# INTERVAL seconds between runs (default 1200) +exec 2>&1 + +: "${INTERVAL:=1200}" + +for var in DOCKER_CONTAINER_NAME IPABUSEDB_API_KEY; do + eval "val=\${$var:-}" + if [ -z "$val" ]; then + echo "ipabusedb-docker-reporter: $var is not set in the environment" >&2 + # runit would otherwise retry every second and flood the log. + sleep 60 + exit 1 + fi +done + +# Sleep in the background so that SIGTERM from "sv stop" (which runsvinit +# sends on "docker stop") interrupts the wait instead of orphaning sleep. +trap 'kill "$sleeper" 2>/dev/null; exit 0' TERM INT +sleep "$INTERVAL" & +sleeper=$! +wait "$sleeper" +trap - TERM INT + +exec /usr/local/bin/ipabusedb-docker-reporter --since "${INTERVAL}s" --submit diff --git a/ipabusedb-docker-ssh/.gitignore b/ipabusedb-docker-ssh/.gitignore deleted file mode 100644 index e159425..0000000 --- a/ipabusedb-docker-ssh/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/ipabusedb-docker-ssh -/reports.csv -/.env diff --git a/ipabusedb-docker-ssh/go.mod b/ipabusedb-docker-ssh/go.mod deleted file mode 100644 index 114638a..0000000 --- a/ipabusedb-docker-ssh/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module sneak.berlin/go/hacks/ipabusedb-docker-ssh - -go 1.26.5 - -require github.com/joho/godotenv v1.5.1