Aktionen

Proxmox Mail Gateway PMG Emails auf Wörter in Nachricht filtern Mailbody

Aus znilwiki

Changelog:

  • 02.06.2025 Skript Version 1.0 => erste Version
  • 03.06.2025 Skript Version 1.1 => mehr Details in den Logmeldungen / Syslog, Farbige Meldungen in der Konsole

Vorwort

In letzter Zeit werden meine Familie und ich von Spam-Mails über Erektionsproblemen überflutet. Ein Großteil filtert das PMG schon aus so das dieses schon mal in Quarantäne landen. Aber es sind so viele das immer noch ein großer Teil durchrutscht.
Die Mails sehen alle so aus:


Der Text variiert, der Aufbau ist immer gleich. Die Mails werden dabei immer von vertrauenswürdigen Quellen gesendet, vermutlich also gehackte Emailkonten.
Allen gemein ist das immer auf eine URL verwiesen wird die auf

apotheke.html

endet. Die HTML-Datei liegt dabei oft auch auf den Webspace von vertrauenswürdigen Webseiten (die vermutlich auch gehackt wurden).


Also eigentlich etwas wonach man prima filtern könnte.

Es stellte sich aber heraus das es dann doch nicht ganz so einfach mit PMG ist, denn es gibt keinen direkten Weg über die Weboberfläche.



Custom Check Skript erstellen

Die Grundlage der Lösung findet sich in der Hilfe:

https://pmg.proxmox.com/pmg-docs/pmg-admin-guide.html#pmgconfig_custom_check

Ich wollte es erst per SpamAssassin machen (mache ich vielleicht noch), die Lösung mit dem Skript gefiel mir jedoch im Moment besser.
Wir erstellen das folgende Skript:

nano /usr/local/bin/pmg-custom-check

mit folgendem Inhalt:

#!/bin/bash
# Siehe https://znil.net/index.php?title=Proxmox_Mail_Gateway_PMG_Emails_auf_W%C3%B6rter_in_Nachricht_filtern_Mailbody
#
# V1.1 vom 03.06.2025 von Bernhard Linz => Bernhard@znil.de
#


# Filter, weitere einfach mit Leerzeichen und in "..." hinzufügen, Es wird auf "String in String" getestet
# Nach SPAM
filterArraySPAM=("apotheke.html" "test1234567890")
# Spam Score der gesetzt werden soll wenn es einen SPAM Treffer gibt
spamScoreSPAM=4

# Nach Whitelisting
filterArrayWHITE=("Test Abrakadabra")
# Spam Score der gesetzt werden soll wenn es einen WHITE Treffer gibt
spamScoreWHITE=-10

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

# schreibt nach STDERR durch 1>&2, das landet dann nur im Logfile /var/log/mail.log
# und wird nicht als Rückgabe des Skriptes interpretiert
# echo "/usr/bin/pmg-custom-check called with $*" 1>&2
echo -e "\e[31m/usr/bin/pmg-custom-check called with $*\e[0m" 1>&2

# Fehler wenn nicht 2 Argumente
if [ "$#" -ne 2 ]; then
  echo "usage: $0 APIVERSION QUEUEFILENAME" 1>&2
  exit 1
fi

# Argument $1 ist die API-Version
apiver="$1"

# Argument $2 ist die Datei mit der Email
queue_file="$2"

# shift würde das Argument $2 zu $1 verschieben
#shift

if [ "$apiver" != "v1" ]; then
  echo "/usr/bin/pmg-custom-check wrong APIVERSION: $apiver" 1>&2
  exit 2
fi

#queue_file="$1"

# Das Skirpt muss auf STDOUT 2 Ausgaben machen:
# Die API-Version, hier also v1
echo "v1"

# Und eine(!) der folgenden 3 Ausgaben:
# 1: Es ist alles ok:
#echo "OK"

# 2: Die Mail enthält einen Virus
#echo "VIRUS: <virusdescription>"

# 3: Die Mail enthält SPAM, wir können den SPAM-Score beinflussen und z.B. um 2 erhöhen (der Startwert ist dann 2)
#echo SCORE: 2

# 4: Die Mail soll auf keinen Fall als SPAM erkannt werden, wir setzen den SCORE auf einen negativen Wert:<br>
#echo SCORE: -10

# Dateinhalte (=Mail) einlesen
#queue_filecontent=$(< $queue_file)
queue_filecontent=$(cat $queue_file)

# Variable die ggf. am Ende dafür sorgt das "OK" ausgegeben wird
bNoSPAM=true

# Test auf WHITE(-listing)
for strWHITE in ${filterArrayWHITE[@]}; do
    # echo $strSPAM
    if [[ "$queue_filecontent" =~ $strWHITE ]]; then
        bNoSPAM=false
        #echo "/usr/bin/pmg-custom-check SCORE: ${spamScoreWHITE}" 1>&2
        echo -e "\e[31m/usr/bin/pmg-custom-check SCORE: ${spamScoreWHITE}\e[0m" 1>&2
        echo "SCORE: ${spamScoreWHITE}"
        break
    fi
done


# Test auf SPAM:
for strSPAM in ${filterArraySPAM[@]}; do
    # echo $strSPAM
    if [[ "$queue_filecontent" =~ $strSPAM ]]; then
        bNoSPAM=false
        #echo "/usr/bin/pmg-custom-check SCORE: ${spamScoreSPAM}" 1>&2
        echo -e "\e[31m/usr/bin/pmg-custom-check SCORE: ${spamScoreSPAM}\e[0m" 1>&2
        echo "SCORE: ${spamScoreSPAM}"
        break
    fi
done

if $bNoSPAM; then
    #echo "/usr/bin/pmg-custom-check OK" 1>&2
    echo -e "\e[31m/usr/bin/pmg-custom-check OK\e[0m" 1>&2
    echo "OK"
fi

exit 0

Und das Skript ausführbar machen:

chmod +x /usr/local/bin/pmg-custom-check



Im Skript könnte Ihr zwei Dinge einstellen:

# Nach SPAM
filterArraySPAM=("apotheke.html" "test1234567890")
# Spam Score der gesetzt werden soll wenn es einen SPAM Treffer gibt
spamScoreSPAM=4

Da hinterlegt Ihr die Liste der Wörter, Sätze, Zeichenfolgen die als SPAM gekennzeichnet werden soll und entscheidet welche Punktzahl die Mail als Spam bekommt.
In diesem Fall hier die 4. Die Mail wird trotzdem weiter verarbeitet, also alles was im Bereich Mail Filter aktiviert ist, greift zusätzlich.
Ggf. kommen also weitere SPAM-Punkte hinzu und die Mail wird ganz ablehnt.

# Nach Whitelisting
filterArrayWHITE=("Test Abrakadabra")
# Spam Score der gesetzt werden soll wenn es einen WHITE Treffer gibt
spamScoreWHITE=-10

Das gleiche Prinzip, nur das die Mail dann mit -10 in die weitere Verarbeitung geht. Selbst wenn dann noch Spam Punkte gesammelt werden, wird die Mail also höchstwahrscheinlich zugestellt.


Skript testen Teil 1

Dazu bräuchten wir Dateien mit Mails.
Wenn Ihr eine in der SPAM-Ansicht RAW habt, könnt mit einem eindeutigen Text danach suchen, in diesem Fall ist das die SPAM-Mail mit apotheke.html:

grep -lr "minute.eicindustria.com.br" /var/spool

Beispielausgabe:

/var/spool/pmg/spam/5A/10013F683BC2482795A

Damit können wir unser Skript nun testen

/usr/local/bin/pmg-custom-check v1 /var/spool/pmg/spam/5A/10013F683BC2482795A

Beispielausgabe:

/usr/bin/pmg-custom-check called with v1 /var/spool/pmg/spam/26/1002A068303219D3E26
v1
/usr/bin/pmg-custom-check SCORE: 4

Die erste und dritte Zeile landet später nur in /var/log/mail.log und im syslog, die anderen beiden sind die notwendige Rückgabe für das PMG.
Gegenprobe mit einer anderen Email, mit

find /var/spool/pmg/spam/ -type f -printf "%T@ %p\n" | sort -nr | cut -d\  -f2-

könnt Ihr euch alle vorhandenen SPAM-Emails anzeigen lassen.

/usr/local/bin/pmg-custom-check v1 /var/spool/pmg/spam/26/1002A068303219D3E26

Beispielausgabe:





Skript scharf schalten

Wir aktivieren das Skript:

nano /etc/pmg/pmg.conf

und im ersten Abschnitt

section: admin

hängen wir die folgenden beiden Zeilen an:

        custom_check_path /usr/local/bin/pmg-custom-check
        custom_check 1

Leider weis ich nicht welchen der Dienste man nun neu starten müsste bzw. wie man das erneute Einlesen der Konfiguration anstößt.
Deshalb starte ich den PMG neu:

reboot




Testmail

Im Skript oben habe ich als Filter auch test1234567890 eingebaut,
also schicke ich mir mal eine Testmail von außerhalb mit der Zeichenfolge:


Und tatata! Der Spam Score ist 4! Ab 5 hätte er die Mail gleich verworfen!
Es funktioniert also!



Im Syslog

Im Mailgateway Syslog sehen wir die Aufrufe des Skriptes:


Die komischen Sonderzeichen kommen daher das ich den Text in der Konsole unbedingt in rot haben wollte.



ToDo

Folgendes möchte ich bei Gelegenheit noch in das Skript einbauen:

  • Echte RegEx-Abfrage statt nur String in String




Quellen




Kommentare

Loading comments...