#!/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" ReadWritePaths /run/bongo assert_contains "$SERVICE" ReadWritePaths /var/lib/bongo 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"