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,67 @@
|
||||
# Guard
|
||||
|
||||
Guard watches logs and bans the addresses that misbehave in them, at the
|
||||
firewall. It reads log files and the systemd journal, counts each
|
||||
address's **bounty** (its matches within a while), and once that reaches
|
||||
a watch's limit bans the address in a ban list of
|
||||
[Housecarl](https://gitea.adbraun.lol/adam/housecarl), the firewall
|
||||
manager. The ban list says what a banned address is kept from: the
|
||||
firewall itself, some hosts behind it, or everything. Guard doesn't need
|
||||
to know anything about the firewall.
|
||||
|
||||
It is the fourth of a set with Jarl (BIND), Steward (DHCP) and Housecarl
|
||||
(nftables), and works like fail2ban, with one easy file instead of jails
|
||||
and filters spread over many:
|
||||
|
||||
```yaml
|
||||
housecarl:
|
||||
url: https://router.lan:8070
|
||||
token_file: /etc/guard/token
|
||||
list: web
|
||||
|
||||
watch:
|
||||
- name: ssh
|
||||
preset: sshd # OpenSSH, from the journal
|
||||
ban: {protocol: tcp, port: 22}
|
||||
- name: web-login
|
||||
file: /var/log/nginx/access.log
|
||||
match: ['^<IP> \S+ \S+ \[[^\]]+\] "POST /login[^"]*" 401 ']
|
||||
hits: 10
|
||||
ban: {time: 6h}
|
||||
```
|
||||
|
||||
* **One pattern placeholder, `<IP>`.** It matches IPv4 and IPv6
|
||||
(bracketed, IPv4-mapped); what only looks like an address is never
|
||||
taken for one.
|
||||
* **No date formats.** Guard follows logs as they are written, and
|
||||
counts each line at the time it reads it (the journal's entries have
|
||||
their own time).
|
||||
* **Files and the journal**, the journal by unit or syslog identifier
|
||||
(`sshd-session` on Debian 13).
|
||||
* **Presets** for OpenSSH, Postfix, Dovecot, nginx, BIND zone transfers,
|
||||
Jarl, Housecarl and Steward, and Housecarl's own log of dropped
|
||||
packets, for scans ([docs/presets.md](docs/presets.md)).
|
||||
* **Repeat offenders** get longer bans: each earlier ban doubles the
|
||||
time, up to a week.
|
||||
* **Never banned:** your own addresses, from Guard's `never_ban`, and
|
||||
from Housecarl, which never bans the inside networks, the firewall's
|
||||
own addresses or the machine asking.
|
||||
* **IPv6 by /64**, as the ban list says: one customer usually has a
|
||||
whole /64 and moves around in it.
|
||||
* **Housecarl away?** Bans wait and are sent once it answers.
|
||||
* **`guard test`** shows what a watch's patterns find in a log, and whom
|
||||
they would ban, before you trust it.
|
||||
|
||||
## Documentation
|
||||
|
||||
* [install.md](docs/install.md): installing, the ban list and token in Housecarl, first steps
|
||||
* [configuration.md](docs/configuration.md): `/etc/guard/guard.yaml`
|
||||
* [presets.md](docs/presets.md): the presets, and writing your own patterns
|
||||
* [cli.md](docs/cli.md): the `guard` command
|
||||
* [CHANGELOG.md](CHANGELOG.md)
|
||||
|
||||
Housecarl's side: its [docs/bans.md](https://gitea.adbraun.lol/adam/housecarl/src/branch/main/docs/bans.md).
|
||||
|
||||
## Status
|
||||
|
||||
0.1.0 in development. Go, `CGO_ENABLED=0`, Linux. MIT licence.
|
||||
Reference in new issue
Block a user