ipabusedb-docker-reporter: rename from ipabusedb-docker-ssh, add Dockerfile with runit service

Build on git.eeqj.de/sneak/baseimage:2026-11-05 with the docker CLI
copied from docker:cli. A runit service sleeps INTERVAL seconds
(default 1200), then runs the reporter with --since INTERVAL --submit;
DOCKER_CONTAINER_NAME and IPABUSEDB_API_KEY come from the container
environment. Add .dockerignore, make image, and README section; fix the
binary name in .gitignore.
This commit is contained in:
sneak committed 2026-11-06 20:18:26 -08:00
1 parent b8c36689ae
commit 1aa7d84401
16 files changed
+135 -11

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
.env
.git
*.csv
/ipabusedb-docker-reporter
deploy.sh
example_parser_script.py
File renamed without changes.
+3
View File
@@ -0,0 +1,3 @@
/ipabusedb-docker-reporter
/reports.csv
/.env
+39
View File
@@ -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 /
@@ -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
@@ -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
+14
View File
@@ -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"
+5
View File
@@ -0,0 +1,5 @@
module sneak.berlin/go/hacks/ipabusedb-docker-reporter
go 1.26.5
require github.com/joho/godotenv v1.5.1
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -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
-3
View File
@@ -1,3 +0,0 @@
/ipabusedb-docker-ssh
/reports.csv
/.env
-5
View File
@@ -1,5 +0,0 @@
module sneak.berlin/go/hacks/ipabusedb-docker-ssh
go 1.26.5
require github.com/joho/godotenv v1.5.1