Guard: watch logs, ban misbehaving addresses in Housecarl
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>
This commit is contained in:
commit
d06bf8d531
47 files changed
+4614
No files matched your search
@@ -0,0 +1,59 @@
|
||||
# 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): `run` is the daemon, the rest are
|
||||
tools.
|
||||
* `internal/config`: guard.yaml, with `presets.yaml` and `example.yaml`
|
||||
embedded. 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_JOURNALCTL` for 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 in `testdata/presets/NAME.txt` (the address
|
||||
to find, or `-`), including an attempt to plant an address;
|
||||
`TestPresets` runs 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-drops` is TCP unless told otherwise; no preset for
|
||||
BIND's UDP refusals).
|
||||
* **Every user-visible change updates `CHANGELOG.md`** under
|
||||
`## [Unreleased]`, and the matching `docs/` page.
|
||||
* `make test` runs `go vet`, a `gofmt -l` check and the tests.
|
||||
|
||||
## Testing
|
||||
|
||||
```sh
|
||||
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.
|
||||
Reference in new issue
Block a user