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:
abrown38andClaude Opus 5.5 committed 2026-10-22 16:29:37 +01:00
commit d06bf8d531
47 files changed
+4614

No files matched your search

+18
View File
@@ -0,0 +1,18 @@
Package: guard
Version: @VERSION@
Architecture: @ARCH@
Maintainer: @MAINTAINER@
Installed-Size: @SIZE@
Depends: systemd
Section: net
Priority: optional
Description: bans addresses that misbehave in the logs, at the firewall
Guard watches log files and the systemd journal for failed logins,
scans and other misdeeds, counts each address's matches, and bans an
address that reaches a watch's limit in a ban list of Housecarl, the
firewall manager: the firewall then keeps it from this machine (or from
what the list says). One YAML file configures it; presets cover OpenSSH,
Postfix, Dovecot, nginx, BIND, Jarl, Housecarl and Steward.
.
guard isn't started on a first install: see
/usr/share/doc/guard/docs/install.md.
+26
View File
@@ -0,0 +1,26 @@
#!/bin/sh
# Guard: runs after the package's files are in place.
set -e
if [ "$1" = configure ]; then
systemd-sysusers guard.conf
install -d -m 0750 -o root -g guard /etc/guard
# An example configuration on the first install; an existing one is
# never touched.
if [ ! -e /etc/guard/guard.yaml ]; then
/usr/bin/guard config --example > /etc/guard/guard.yaml.dpkg-new
chown root:guard /etc/guard/guard.yaml.dpkg-new
chmod 0640 /etc/guard/guard.yaml.dpkg-new
mv /etc/guard/guard.yaml.dpkg-new /etc/guard/guard.yaml
fi
if [ -d /run/systemd/system ]; then
systemctl daemon-reload || true
# An upgrade restarts a running guard; a first install starts
# nothing (it needs Housecarl's ban list and token first).
if [ -n "$2" ] && systemctl is-active --quiet guard.service; then
systemctl restart guard.service || true
fi
fi
fi
exit 0
+17
View File
@@ -0,0 +1,17 @@
#!/bin/sh
# Guard: runs after the package's files are removed.
set -e
case "$1" in
remove|purge)
if [ -d /run/systemd/system ]; then
systemctl daemon-reload || true
fi
;;
esac
# The bans Guard made stay in Housecarl until they end.
if [ "$1" = purge ]; then
echo "guard: kept /etc/guard and /var/lib/guard; remove them by hand if unused."
fi
exit 0
+10
View File
@@ -0,0 +1,10 @@
#!/bin/sh
# Guard: runs before the package's files are removed (also on upgrades).
set -e
if [ "$1" = remove ] && [ -d /run/systemd/system ]; then
systemctl stop guard.service 2>/dev/null || true
systemctl disable guard.service 2>/dev/null || true
fi
exit 0
+55
View File
@@ -0,0 +1,55 @@
# Guard: watches logs and bans misbehaving addresses at the firewall
# (Housecarl's ban lists). Installed as /etc/systemd/system/guard.service
# (see docs/install.md).
[Unit]
Description=Guard: bans addresses that misbehave in the logs, at the firewall
Documentation=file:///usr/local/share/doc/guard/README.md
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/guard --config /etc/guard/guard.yaml run
Restart=on-failure
RestartSec=5s
User=guard
Group=guard
# Reading logs: /var/log's files (adm) and the journal (systemd-journal).
# On the firewall, add housecarl to use Housecarl's local socket.
SupplementaryGroups=adm systemd-journal
UMask=0027
# /var/lib/guard: the state (repeat offenders, bans waiting for
# Housecarl). /run/guard: the socket guard status asks.
StateDirectory=guard
StateDirectoryMode=0750
ConfigurationDirectory=guard
ConfigurationDirectoryMode=0750
RuntimeDirectory=guard
RuntimeDirectoryMode=0750
# Sandboxing: Guard only reads logs and talks to Housecarl.
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
PrivateDevices=yes
NoNewPrivileges=yes
CapabilityBoundingSet=
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectControlGroups=yes
ProtectClock=yes
ProtectHostname=yes
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
LockPersonality=yes
MemoryDenyWriteExecute=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
SystemCallArchitectures=native
SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
[Install]
WantedBy=multi-user.target
+3
View File
@@ -0,0 +1,3 @@
# Guard's system user (systemd-sysusers): it reads logs and talks to
# Housecarl, nothing more.
u guard - "Guard log watcher" /var/lib/guard /usr/sbin/nologin