Dotfiles/setup/modules/FreeipaAnsible/ansible/policies.d/dev_mon_clamscan.sh

110 lines
4.9 KiB
Bash

#!/usr/bin/env bash
# policy: dev_mon_clamscan — daily ClamAV + rkhunter + chkrootkit scan at 02:00,
# with results reported natively to CheckMK.
# Applied when the host is a member of the dev_mon_clamscan host-group.
#
# Results are handed to CheckMK via a local check (ansipa_clamscan) rather than
# uploaded to an SMB share: the CheckMK agent (installed by dev_mon_base) picks
# up the local check and surfaces the scan status as a monitored service. Add a
# host to BOTH dev_mon_clamscan (to run the scan + emit the check) and dev_mon_base
# (to install the agent that collects it) to see results in CheckMK.
SCAN_CRON="$CRON_DIR/ansipa-clamscan"
SCAN_SCRIPT="/usr/local/bin/ansipa-clamscan.sh"
SCAN_LOG="/var/log/ansipa-clamscan.log"
CMK_LOCAL_DIR="/usr/lib/check_mk_agent/local"
CMK_CHECK="$CMK_LOCAL_DIR/ansipa_clamscan"
if [[ "$WANT_CLAMSCAN" == true ]]; then
# (Re-)write the scan script so it stays current with this version of the enforcer.
cat > "$SCAN_SCRIPT" <<'SCAN'
#!/bin/bash
# ansipa-clamscan — daily ClamAV / rkhunter / chkrootkit run.
# Managed by ansipa-enforce-policies — do not edit manually.
# Results are read by the ansipa_clamscan CheckMK local check; no SMB upload.
LOG=/var/log/ansipa-clamscan.log
# `hostname` (inetutils) may be absent on minimal Arch; resolve without it.
HOSTNAME=$( { command -v hostname >/dev/null 2>&1 && hostname -f 2>/dev/null; } \
|| hostnamectl --static 2>/dev/null || cat /etc/hostname 2>/dev/null \
|| cat /proc/sys/kernel/hostname 2>/dev/null )
DATE=$(date +%Y-%m-%d)
{
echo "=== ansipa-clamscan: $DATE $HOSTNAME ==="
if command -v freshclam &>/dev/null; then
freshclam --quiet 2>/dev/null || true
fi
if command -v clamscan &>/dev/null; then
clamscan -r --infected --quiet /home /etc /tmp /var/tmp 2>/dev/null || true
fi
if command -v rkhunter &>/dev/null; then
rkhunter --update --quiet 2>/dev/null || true
rkhunter --check --skip-keypress --quiet 2>/dev/null || true
fi
if command -v chkrootkit &>/dev/null; then
chkrootkit 2>/dev/null || true
fi
echo "=== scan complete ==="
} >> "$LOG" 2>&1
SCAN
chmod 755 "$SCAN_SCRIPT"
# ── CheckMK local check: report scan results to CheckMK ───────────────────
# Emitted regardless of whether the CheckMK agent is present yet; once
# dev_mon_base installs the agent, it collects this check automatically.
mkdir -p "$CMK_LOCAL_DIR"
cat > "$CMK_CHECK" <<'CHECK'
#!/bin/bash
# ansipa_clamscan — CheckMK local check reporting the ansipa-clamscan result.
# Managed by ansipa-enforce-policies (dev_mon_clamscan) — do not edit manually.
LOG=/var/log/ansipa-clamscan.log
CLAMDB=/var/lib/clamav/main.cvd
[[ -f /var/lib/clamav/main.cld ]] && CLAMDB=/var/lib/clamav/main.cld
if [[ ! -f "$LOG" ]]; then
echo "1 Ansipa_ClamScan - No scan has run yet (scans run daily at 02:00)."
exit 0
fi
LAST_DATE=$(grep "^=== ansipa-clamscan:" "$LOG" 2>/dev/null | tail -1 \
| grep -oE "[0-9]{4}-[0-9]{2}-[0-9]{2}" || echo "")
INFECTED=$(grep -c "FOUND$" "$LOG" 2>/dev/null) || INFECTED=0
RKWARN=$(grep -c "Warning:" "$LOG" 2>/dev/null) || RKWARN=0
DB_DAYS=999
if [[ -f "$CLAMDB" ]]; then
DB_DAYS=$(( ( $(date +%s) - $(stat -c %Y "$CLAMDB" 2>/dev/null || echo 0) ) / 86400 ))
fi
PERF="infected=${INFECTED};1;1 rkhunter_warnings=${RKWARN} db_age_days=${DB_DAYS};7;30"
if [[ -z "$LAST_DATE" ]]; then
echo "1 Ansipa_ClamScan ${PERF} No completed scan found yet"
elif [[ "$INFECTED" -gt 0 ]]; then
echo "2 Ansipa_ClamScan ${PERF} INFECTED: ${INFECTED} threat(s) — last scan: ${LAST_DATE}"
elif [[ "$DB_DAYS" -gt 7 ]]; then
echo "1 Ansipa_ClamScan ${PERF} ClamAV DB stale (${DB_DAYS}d). Last scan: ${LAST_DATE}"
elif [[ "$RKWARN" -gt 0 ]]; then
echo "1 Ansipa_ClamScan ${PERF} Clean, but ${RKWARN} rkhunter warning(s) — last scan: ${LAST_DATE}"
else
echo "0 Ansipa_ClamScan ${PERF} Clean — last scan: ${LAST_DATE}, DB age: ${DB_DAYS}d"
fi
CHECK
chmod 755 "$CMK_CHECK"
if [[ ! -f "$SCAN_CRON" ]]; then
log "Enabling daily ClamAV scan (dev_mon_clamscan) with CheckMK reporting"
# /etc/cron.d may not exist yet if cron isn't installed — create it so the
# drop-in lands (cronie/anti-malware tooling comes via dev_mod_anti-malware).
mkdir -p "$CRON_DIR"
cat > "$SCAN_CRON" <<'CRON'
# ansipa-dev_mon_clamscan: managed by ansipa-enforce-policies — do not edit manually.
# Install scan tools by adding the host to the dev_mod_anti-malware group.
# Results appear in CheckMK (Ansipa_ClamScan) when the host is also in dev_mon_base.
0 2 * * * root /usr/local/bin/ansipa-clamscan.sh
CRON
chmod 644 "$SCAN_CRON"
fi
else
if [[ -f "$SCAN_CRON" || -f "$SCAN_SCRIPT" || -f "$CMK_CHECK" ]]; then
rm -f "$SCAN_CRON" "$SCAN_SCRIPT" "$CMK_CHECK" "$SCAN_LOG"
log "Removed dev_mon_clamscan policy (host left dev_mon_clamscan group)"
fi
fi