Files
bongo/contrib/testing/systemd-runtime-check.sh
2026-07-27 22:03:40 +02:00

123 lines
4.1 KiB
Bash
Executable File

#!/bin/sh
set -eu
SERVICE=${BONGO_TEST_SERVICE:-bongo.service}
UPDATE_SERVICE=${BONGO_TEST_UPDATE_SERVICE:-bongo-spamassassin-update.service}
UPDATE_TIMER=${BONGO_TEST_UPDATE_TIMER:-bongo-spamassassin-update.timer}
show_value()
{
unit=$1
property=$2
systemctl show "$unit" -p "$property" --value
}
assert_equal()
{
unit=$1
property=$2
expected=$3
actual=$(show_value "$unit" "$property")
if [ "$actual" != "$expected" ]; then
echo "$unit $property=$actual, expected $expected" >&2
exit 1
fi
}
assert_contains()
{
unit=$1
property=$2
expected=$3
actual=$(show_value "$unit" "$property")
case " $actual " in
*" $expected "*) ;;
*)
echo "$unit $property does not contain $expected: $actual" >&2
exit 1
;;
esac
}
systemd-analyze verify \
/usr/lib/systemd/system/bongo.service \
/usr/lib/systemd/system/bongo-spamassassin-update.service \
/usr/lib/systemd/system/bongo-spamassassin-update.timer
echo "PASS installed systemd units verify"
assert_equal "$SERVICE" ActiveState active
assert_equal "$SERVICE" Result success
assert_equal "$SERVICE" NoNewPrivileges yes
assert_equal "$SERVICE" ProtectSystem strict
assert_equal "$SERVICE" PrivateDevices yes
assert_equal "$SERVICE" PrivateTmp yes
assert_equal "$SERVICE" ProtectControlGroups yes
assert_equal "$SERVICE" ProtectKernelLogs yes
assert_equal "$SERVICE" ProtectKernelModules yes
assert_equal "$SERVICE" ProtectKernelTunables yes
assert_equal "$SERVICE" RestrictSUIDSGID yes
assert_contains "$SERVICE" RequiresMountsFor /etc/bongo
assert_contains "$SERVICE" RequiresMountsFor /var/lib/bongo
assert_contains "$SERVICE" RequiresMountsFor /var/spool/bongo/maildrop
assert_contains "$SERVICE" ReadWritePaths /run/bongo
assert_contains "$SERVICE" ReadWritePaths /var/lib/bongo
assert_contains "$SERVICE" ReadWritePaths /var/spool/bongo/maildrop
assert_contains "$SERVICE" ReadWritePaths /etc/bongo/aliases.d
assert_contains "$SERVICE" RestrictAddressFamilies AF_INET
assert_contains "$SERVICE" RestrictAddressFamilies AF_INET6
assert_contains "$SERVICE" RestrictAddressFamilies AF_UNIX
echo "PASS main service ordering and sandbox properties"
assert_equal "$UPDATE_TIMER" ActiveState active
assert_equal "$UPDATE_TIMER" UnitFileState enabled
calendar=$(show_value "$UPDATE_TIMER" TimersCalendar)
case "$calendar" in
*OnCalendar=*) ;;
*)
echo "$UPDATE_TIMER has no calendar trigger: $calendar" >&2
exit 1
;;
esac
assert_equal "$UPDATE_SERVICE" Result success
assert_equal "$UPDATE_SERVICE" ExecMainStatus 0
echo "PASS enabled scanner-update timer and its last successful run"
manager=$(show_value "$SERVICE" MainPID)
worker=$(/usr/bin/pgrep -P "$manager" -x bongoworker 2>/dev/null || true)
if [ -z "$worker" ]; then
echo "bongoworker is not a child of manager $manager" >&2
exit 1
fi
worker_config=$(sudo -n -u bongo /usr/bin/bongo-admin __config-read worker)
for job in acme-renew scanner-health tlsrpt-delivery; do
if ! printf '%s\n' "$worker_config" |
grep -Eq "\"name\"[[:space:]]*:[[:space:]]*\"$job\""; then
echo "worker configuration does not contain $job" >&2
exit 1
fi
done
directory_state=$(sudo -n /usr/bin/stat -c '%a %U:%G' \
/var/lib/bongo/worker)
database_state=$(sudo -n /usr/bin/stat -c '%a %U:%G' \
/var/lib/bongo/worker/jobs.sqlite)
if [ "$directory_state" != "750 bongo:bongo" ] ||
[ "$database_state" != "600 bongo:bongo" ]; then
echo "unsafe worker scheduler state: dir=$directory_state db=$database_state" >&2
exit 1
fi
echo "PASS worker PID $worker and persistent scheduler state"
if [ "${BONGO_REQUIRE_WORKER_ACTIVITY:-}" = 1 ]; then
invocation=$(show_value "$SERVICE" InvocationID)
if ! journalctl "_SYSTEMD_INVOCATION_ID=$invocation" --no-pager -l |
grep -Eq 'Starting scheduled job|bongo-sa-update:'; then
echo "current service invocation has no scheduled worker activity" >&2
exit 1
fi
echo "PASS current service invocation contains scheduled worker activity"
fi
echo "PASS systemd ordering, hardening, scanner timer, and worker scheduling"