File: //lib64/nagios/plugins/check_exim_spam.sh
#!/bin/bash
# -----------------------------------------------------------------------------------------------
# Script name: check_exim_spam.sh
# Description: This script extracts Exim mail logs from the past hour and analyzes user activity.
# It identifies users who have sent more than the specified threshold of emails
# during that time period and perform action (suspend/stop/open ticket)
# Author: Tsvetan Gerov <tsvetan@worldhost.group>
# Version: 0.2
# Copyright (C) 2025 Hosting.Com
# All rights reserved.
# Dependencies: curl dig awk
# Changelog:
# Fri Jul 4 08:46:43 EEST 2025 - v0.2
# - Added --threshold argument to set the threshold for spam detection
# - Improved error handling for invalid threshold input
# - Converted to nagios check
# Thu Mar 20 10:46:09 EET 2025 - v0.1
# - Initial version / research
# ----------------------------------------------------------------------------------------------
# Global variables
HOSTNAME=$(hostname -f)
HOSTNAME_IP=$(dig +short $HOSTNAME)
EXTIP=$(curl -s ipv4.icanhazip.com)
EXTIP_PTR=$(dig +short -x $EXTIP | sed 's/\.$//')
OSRELEASE=$(cat /etc/redhat-release | tr -dc '0-9.'|cut -d \. -f1)
# Initialize flags and error message
CRITICAL=false
WARNING=false
ERROR_MESSAGE=""
check_deps(){
DEPS="curl dig awk"
for DEP in $DEPS; do
if [ ! -f "/usr/bin/${DEP}" ]; then
echo "[UNKNOWN] Please install $DEP"
exit 3
fi
done
}
check_spam() {
EXIM_LOG="/var/log/exim_mainlog"
TMPFILE=$(mktemp)
DATA=$(mktemp)
THRESHOLD="50"
# Parse arguments (from parent script, not from function)
while [[ $# -gt 0 ]]; do
case $1 in
--threshold)
if [[ -n $2 && $2 =~ ^[0-9]+$ ]]; then
THRESHOLD="$2"
shift
else
echo "[ERROR] --threshold requires a numeric argument" >&2
exit 1
fi
;;
*)
# Unknown option
;;
esac
shift
done
# Check if exim log exists
if [ ! -f "$EXIM_LOG" ]; then
WARNING=true
ERROR_MESSAGE+="Exim log $EXIM_LOG not found, skipping spam check. "
return
fi
# Declare array
declare -A data_array
# Get exim for the past hour
grep "$(date --date="-1 hours" '+%Y-%m-%d %H:')" $EXIM_LOG >> $TMPFILE
# Generate data
grep -E '\scwd=\/home[^[:space:]]*\s' $TMPFILE | awk '{print$3}' | cut -f 2 -d = | sort | uniq -c | sort -n | sed 's/^ *//' >> $DATA
grep -E '\sA=dovecot_(login|plain):([^\s]+)\s' $TMPFILE | grep -o 'A=[^ ]*' | cut -f 2 -d : | sort | uniq -c | sort -n | sed 's/^ *//' >> $DATA
SMTP_LIST=$(cat $DATA)
while IFS=' ' read -r value path; do
data_array["$path"]="$value"
done <<< "$SMTP_LIST"
for path in "${!data_array[@]}"; do
if [ "${data_array[$path]}" -gt "$THRESHOLD" ]; then
# TODO: Action (stop/block/suspend/ticket)
CRITICAL=true
ERROR_MESSAGE+="$path Value: ${data_array[$path]}, "
fi
done
}
# Perform dep checks
check_deps
# Pass all script arguments to check_spam
check_spam "$@"
# Return final state
if [ "$CRITICAL" = true ]; then
echo "[CRITICAL] Possible spam: ${ERROR_MESSAGE%, }"
exit 2
elif [ "$WARNING" = true ]; then
echo "[WARNING] ${ERROR_MESSAGE%, }"
exit 1
else
echo "[OK] All services are running correctly."
exit 0
fi