Files and the journal, patterns with one <IP>, bounties within a window, bans in a Housecarl ban list with repeat offenders' bans growing; presets for sshd, jarl, housecarl, steward, bind-xfr, postfix-sasl, dovecot, nginx-auth and housecarl-drops; guard run/check/test/status/bans/ban/unban; a Debian package with a sandboxed unit; an end-to-end test with Housecarl. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2.4 KiB
2.4 KiB
Working on Guard
Notes for coding agents (and people) changing this repository.
Guard watches logs and bans misbehaving addresses in Housecarl's ban
lists (../housecarl, its docs/bans.md). It is the fourth of a set with
Jarl (../jarl), Steward (../steward) and Housecarl, and copies their
ways: Go, CGO_ENABLED=0, one YAML file, the same release process. It
has no web UI and no database: bans are shown by Housecarl.
Layout
cmd/guard: the one binary (cobra):runis the daemon, the rest are tools.internal/config: guard.yaml, withpresets.yamlandexample.yamlembedded. A watch's preset is resolved here (Watch.resolve).internal/match: patterns with<IP>;Group(IPv6 by prefix).internal/source: files (polled tail -F), the journal (journalctl subprocess,GUARD_JOURNALCTLfor tests), Housecarl's log.internal/bounty: per-watch counts within a window.internal/daemon: lines → matches → bounties → bans, the retry queue, the status socket,never_ban.internal/housecarl: the API client (ban lists, bans, the log).internal/state: the JSON state file.
Ground rules
- Never trust a client's text for the address. Preset patterns put
<IP>where the program writes the address, after anything a client chose, anchored at the line's end where the format allows. Every preset has sample lines intestdata/presets/NAME.txt(the address to find, or-), including an attempt to plant an address;TestPresetsruns them. - No timestamp parsing. Lines count when read (the journal's and Housecarl's carry their own time).
- Never ban on spoofable evidence by default: UDP sources can be
faked (
housecarl-dropsis TCP unless told otherwise; no preset for BIND's UDP refusals). - Every user-visible change updates
CHANGELOG.mdunder## [Unreleased], and the matchingdocs/page. make testrunsgo vet, agofmt -lcheck and the tests.
Testing
make test
make e2e # with ../housecarl's lab: needs Docker (DOCKER_HOST=unix:///var/run/docker.sock here)
Git and releases
As in Housecarl: commit only when asked, never push; branches
dev-X.Y.Z; a release is a commit "Release X" setting VERSION, with
the annotated tag vX ("Guard X").
Shell hygiene
Never kill processes by pattern (pkill -f): the pattern matches the
shell running it. Find the PID and kill that.