#!/bin/bash
# spamdetector 0.3
# borys@bohater.net 4 akron.net.pl
# Za pomoca ngrep - zlicza ilosc wystapien textu "mail from" i jesli przekracza podany pulap
# na jedno ip - sprawdza ilosc unikalnych serwerow SMTP i jesli ilosc
# unikalnych serwerow jest wieksza od > SMTP_UNIQUE_LIMIT - uznaje za SPAMera i loguje / informuje

#Katalog z logami czyli plikami z naglowkami "mail from" w kwestii dowodowej
LOGDIR="/var/log/spamdetector"
#Ilosc pakietow do zebrania w ciagu $SEKUND sekund
ILEPAKIETOW=20
#Jesli na jedno IP jest wiecej zlapanych "mail from" niz $ILESPAM to informujemy
ILESPAM=5
#Ilosc sekund czekania sleepem do zabicia ngrepa
SLEEP=120
#Ilosc sekund czekania sleepem do zabicia ngrepa sygnalem -9 po sprawdzeniu, ze zwykly kill zawiodl
SLEEP9=20
#Ilosc unikalnych serwerow smtp wyzej, ktorej wnioskujemy, ze to SPAMer
SMTP_UNIQUE_LIMIT=3
#bpf filter for tcpdump
FILTER='port 25'
#Plik z wylapanymi IP i iloscia wystapien "mail from"
LOGFILE=/var/log/spam.log
#Mail gdzie poslac info o SPAMerze
MAILADMIN="youradmin@mail.com"
#Jesli DEBUG=1 - podczas uruchomienia wyswietli wykryte adresy IP
DEBUG=0
#Najlepiej nie dotykac
PLIKTMP=/tmp/spamdetector
PLIKTMP2=/tmp/spamdetector_2

###########################################################

#Jesli nie ma katalogu do logowania - zakladamy go
if [ ! -d "$LOGDIR" ] ; then
  mkdir -p "$LOGDIR"
fi

#Czyszczenie plikow tymczasowych
rm -f "$PLIKTMP" "$PLIKTMP2"

#Forkujemy ngrepem
ngrep -q -i -n $ILEPAKIETOW -d any 'mail from' $FILTER > "$PLIKTMP" &

sleep $SLEEP

if [ -f "$PLIKTMP" ] ; then

  cat "$PLIKTMP" | grep "\->"| awk '{print $2}'| cut -d : -f 1 > "$PLIKTMP2"

  DATA=`date +%Y_%m_%d-%H%M`

  for ip in `cat "$PLIKTMP2" |sort |uniq` ; do
    if [ "$DEBUG" -eq 1 ] ; then
      echo -n "DEBUG: /$DATA/ -> Ip: $ip | Ile_Wiadomosci:  "
      grep $ip -wc "$PLIKTMP2"
    fi

    ILENAIP=`grep $ip -wc "$PLIKTMP2"`

#Jesli ilosc wystapien danego IP jest wieksza niz $ILESPAM - uznajemy IP za podejrzanego SPAMera
    if [ "$ILENAIP" -gt $ILESPAM ] ; then
      echo "SPAMER: /$DATA/ -> Ip: $ip | Ile_Wiadomosci: $ILENAIP " >> $LOGFILE
      DATA=`date +%Y_%m_%d-%H%M`

#Zliczamy ilosc unikalnych smtp serwerow i jesli przekracza $SMTP_UNIQUE_LIMIT to SPAMER
echo "STARTCZEKUNIQ"
      SMTP_UNIQUE=`cat $PLIKTMP|grep -w $ip|awk -F "->" '{print $2}'|sort|uniq|wc -l`

      if [ "$SMTP_UNIQUE" -gt "$SMTP_UNIQUE_LIMIT" ] ; then

#SPAMER!!!

        echo -e "SPAMER: /$DATA/ -> Ip: $ip | Ile_Wiadomosci: $ILENAIP \nLOGI_DOWODOWE: $LOGDIR/$DATA " |mail -s "SPAM_DETECTOR from `hostname`" $MAILADMIN 
      fi

    else
      echo -n "NORMAL: /$DATA/ -> Ip: $ip | Ile_Wiadomosci:  " >> $LOGFILE
      grep $ip -wc "$PLIKTMP2" >> $LOGFILE
    fi

  done

fi

#Jesli ngrep sam sie nie zamknal killujemy lekko
if [ ! -z "`ps --no-headers $!`" ] ; then
  kill $! 2>/dev/null 1>/dev/null
fi

sleep $SLEEP9

#Jesli ngrep wciaz sam sie nie zamknal killujemy mocno
if [ ! -z "`ps --no-headers $!`" ] ; then
  kill -9 $! 2>/dev/null 1>/dev/null
fi

DATA=`date +%Y_%m_%d-%H%M`

#Jesli plik istnieje i jest wiekszy > 0 - logujemy
if [ -s "$PLIKTMP" ] ; then
  mv -f "$PLIKTMP" "$LOGDIR/$DATA"
fi


#Czyszczenie plikow tymczasowych
rm -f "$PLIKTMP" "$PLIKTMP2"

