110 lines
4.9 KiB
Bash
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
|