release / release (push) Successful in 30s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
71 lines
2.9 KiB
Markdown
71 lines
2.9 KiB
Markdown
# 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.
|
|
* **`systemctl reload guard`** puts a changed guard.yaml to work
|
|
without losing what Guard has counted.
|
|
* **`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
|
|
* [development.md](docs/development.md): building, testing, releasing
|
|
* [CHANGELOG.md](CHANGELOG.md)
|
|
|
|
Housecarl's side: its [docs/bans.md](https://gitea.adbraun.lol/adam/housecarl/src/branch/main/docs/bans.md).
|
|
|
|
## Status
|
|
|
|
Guard 0.1.0 is in testing (0.1.0-rc.2). Go, `CGO_ENABLED=0`, Linux. MIT licence.
|