Fix ClamAV account setup and add install verification
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env bash
|
||||
set -u
|
||||
|
||||
PASS=0
|
||||
WARN=0
|
||||
FAIL=0
|
||||
|
||||
ok(){ printf "[PASS] %s\n" "$*"; PASS=$((PASS+1)); }
|
||||
warn(){ printf "[WARN] %s\n" "$*"; WARN=$((WARN+1)); }
|
||||
fail(){ printf "[FAIL] %s\n" "$*"; FAIL=$((FAIL+1)); }
|
||||
|
||||
if [[ ${EUID:-$(id -u)} -ne 0 ]]; then
|
||||
exec sudo bash "$0" "$@"
|
||||
fi
|
||||
|
||||
TEST_DISCORD=0
|
||||
[[ "${1:-}" == "--test-discord" ]] && TEST_DISCORD=1
|
||||
|
||||
printf "malware-watch verification | host=%s | time=%s\n\n" "$(hostname)" "$(date -Is)"
|
||||
|
||||
for f in \
|
||||
/etc/malware-watch/config \
|
||||
/usr/local/sbin/malware-watch.py \
|
||||
/usr/local/sbin/malware-quarantine.py \
|
||||
/usr/local/sbin/malware-feed-update.py \
|
||||
/usr/local/sbin/clamav-watch-scan.sh \
|
||||
/usr/local/sbin/block-malware-iocs; do
|
||||
if [[ -f "$f" ]]; then ok "file exists: $f"; else fail "missing file: $f"; fi
|
||||
done
|
||||
|
||||
if [[ -f /etc/malware-watch/config ]]; then
|
||||
mode=$(stat -c %a /etc/malware-watch/config 2>/dev/null || true)
|
||||
[[ "$mode" == "600" ]] && ok "config permissions are 600" || warn "config permissions are $mode (expected 600)"
|
||||
if grep -q '^DISCORD_WEBHOOK=' /etc/malware-watch/config && grep -q '^ABUSECH_AUTH_KEY=' /etc/malware-watch/config; then
|
||||
ok "Discord webhook and abuse.ch key entries exist"
|
||||
else
|
||||
fail "Discord webhook or abuse.ch key entry is missing"
|
||||
fi
|
||||
fi
|
||||
|
||||
for t in malware-watch.timer malware-feed-update.timer; do
|
||||
if systemctl is-enabled "$t" >/dev/null 2>&1 && systemctl is-active "$t" >/dev/null 2>&1; then
|
||||
ok "$t is enabled and active"
|
||||
else
|
||||
fail "$t is not enabled/active"
|
||||
fi
|
||||
done
|
||||
|
||||
if systemctl is-enabled block-malware-iocs.service >/dev/null 2>&1 && systemctl is-active block-malware-iocs.service >/dev/null 2>&1; then
|
||||
ok "block-malware-iocs.service is enabled and active"
|
||||
else
|
||||
fail "block-malware-iocs.service is not enabled/active"
|
||||
fi
|
||||
|
||||
TF=/var/lib/malware-watch/feeds/threatfox.json
|
||||
MB=/var/lib/malware-watch/feeds/malwarebazaar.json
|
||||
if [[ -s "$TF" ]]; then
|
||||
n=$(python3 - "$TF" <<'PY'
|
||||
import json,sys
|
||||
try:
|
||||
d=json.load(open(sys.argv[1])); print(len(d.get("iocs",{})))
|
||||
except Exception: print(-1)
|
||||
PY
|
||||
)
|
||||
[[ "$n" =~ ^[0-9]+$ ]] && (( n > 0 )) && ok "ThreatFox feed loaded: $n IOCs" || warn "ThreatFox feed exists but contains no parsed IOCs"
|
||||
else
|
||||
fail "ThreatFox feed missing/empty"
|
||||
fi
|
||||
|
||||
if [[ -s "$MB" ]]; then
|
||||
n=$(python3 - "$MB" <<'PY'
|
||||
import json,sys
|
||||
try:
|
||||
d=json.load(open(sys.argv[1])); print(len(d.get("hashes",{})))
|
||||
except Exception: print(-1)
|
||||
PY
|
||||
)
|
||||
[[ "$n" =~ ^[0-9]+$ ]] && (( n > 0 )) && ok "MalwareBazaar feed loaded: $n hashes" || warn "MalwareBazaar feed exists but contains no parsed hashes"
|
||||
else
|
||||
fail "MalwareBazaar feed missing/empty"
|
||||
fi
|
||||
|
||||
if [[ -x /usr/local/bin/clamscan ]]; then
|
||||
ok "ClamAV installed: $(/usr/local/bin/clamscan --version 2>/dev/null | head -n1)"
|
||||
if id -u clamav >/dev/null 2>&1; then ok "clamav service account exists"; else fail "clamav service account is missing"; fi
|
||||
if compgen -G '/var/lib/clamav/*.cvd' >/dev/null || compgen -G '/var/lib/clamav/*.cld' >/dev/null; then
|
||||
ok "ClamAV signature database exists"
|
||||
else
|
||||
warn "ClamAV signature DB is not ready yet; freshclam timer may still need to download it"
|
||||
fi
|
||||
for t in clamav-freshclam-local.timer clamav-risk-scan.timer clamav-deep-scan.timer; do
|
||||
if systemctl is-enabled "$t" >/dev/null 2>&1 && systemctl is-active "$t" >/dev/null 2>&1; then
|
||||
ok "$t is enabled and active"
|
||||
else
|
||||
fail "$t is not enabled/active"
|
||||
fi
|
||||
done
|
||||
else
|
||||
warn "ClamAV is not installed (INSTALL_CLAMAV may have been disabled)"
|
||||
fi
|
||||
|
||||
if [[ -x /usr/local/sbin/malware-watch.py ]]; then
|
||||
out=$(/usr/local/sbin/malware-watch.py 2>&1); rc=$?
|
||||
if (( rc == 0 )); then
|
||||
ok "malware-watch one-shot execution succeeded: $out"
|
||||
else
|
||||
fail "malware-watch one-shot execution failed (rc=$rc): $out"
|
||||
fi
|
||||
fi
|
||||
|
||||
if (( TEST_DISCORD )); then
|
||||
if [[ -r /etc/malware-watch/config ]]; then
|
||||
set -a
|
||||
. /etc/malware-watch/config
|
||||
set +a
|
||||
payload=$(python3 - <<'PY'
|
||||
import json,socket
|
||||
print(json.dumps({"content":f"malware-watch verify OK | server: {socket.gethostname()}"},ensure_ascii=False))
|
||||
PY
|
||||
)
|
||||
code=$(curl -sS -o /tmp/malware-watch-discord-verify.out -w '%{http_code}' \
|
||||
-A 'Mozilla/5.0 (compatible; malware-watch/verify)' \
|
||||
-H 'Content-Type: application/json' --data "$payload" "$DISCORD_WEBHOOK" || true)
|
||||
if [[ "$code" == "204" || "$code" == "200" ]]; then
|
||||
ok "Discord webhook test succeeded (HTTP $code)"
|
||||
else
|
||||
fail "Discord webhook test failed (HTTP ${code:-000})"
|
||||
fi
|
||||
rm -f /tmp/malware-watch-discord-verify.out
|
||||
else
|
||||
fail "cannot test Discord: config unavailable"
|
||||
fi
|
||||
fi
|
||||
|
||||
printf "\nSummary: PASS=%d WARN=%d FAIL=%d\n" "$PASS" "$WARN" "$FAIL"
|
||||
(( FAIL == 0 ))
|
||||
Reference in New Issue
Block a user