abrown38andClaude Opus 5.5 b87cc6fb62 CLI: shorter, plainer output
Tables name a journal source by its first two units or identifiers;
guard test shows 20 matching lines and addresses (--all for all), no
/32; Housecarl connection errors without Go's request URL, said once by
guard check; status tells "not running" from "no permission"; bans says
when there are none; "1 ban lifted".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 12:53:37 +01:00
2026-10-23 12:53:37 +01:00
2026-10-23 12:53:37 +01:00
2026-10-23 12:53:37 +01:00
2026-10-23 12:53:37 +01:00
2026-10-23 12:47:17 +01:00
2026-10-23 12:47:17 +01:00

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, 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:

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).
  • 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

Housecarl's side: its docs/bans.md.

Status

Guard 0.1.0 is in testing (0.1.0-rc.1+git5-73ab640). Go, CGO_ENABLED=0, Linux. MIT licence.

S
Description
No description provided
Readme MIT
180 KiB
0 Stars 1 Watchers 0 Forks
Languages
Go 82.5%
Shell 14.3%
Makefile 3.2%