• SolvedUpstreamed
  • grommunio-spam-run.sh does neither learn spam nor clean junk-folder

Hello,

I was very happy to see that grommunio-antispam offers an easy way to learn spam with activating timer for grommunio-spam-run. I have enabled the timer and saw in the journal that the grommunio-spam-run.sh script was run. So I began to debug this script. I began to understand that I need to define mysql_port in /etc/gromox/mysql_adaptor.cfg otherwise the mysql command fails. Furthermore I found out that in line 21 of /usr/sbin/grommunio-spam-run.sh the Variable $MSGFILE is empty. Good news is that the while loop does work and $SPAMMSG has a numberic value and the loop runs 5 times (that is exactly the number of Junk Mails in Junk-Folder. But now I am clueless, cause I dont understand MSGFILE=$(echo ${SPAMMSG} | awk '{ print $2 }').
Pershaps someone can help with this?

thx emtie

Maybe this removes all possible "issues".

cp /usr/sbin/grommunio-spam-run.sh{,.bak}
cat << 'EOPATCH' > /usr/sbin/grommunio-spam-run.sh
#!/bin/bash

MYSQL_CFG="/etc/gromox/mysql_adaptor.cfg"

if [ ! -e "${MYSQL_CFG}" ] ; then
  echo "MySQL configuration not found. (${MYSQL_CFG})"
  exit 1
fi

MYSQL_PARAMS="--skip-column-names --skip-line-numbers"
MYSQL_USERNAME=$(sed -ne 's/mysql_username\s*=\s*\(.*\)\s*/-u\1/pI' ${MYSQL_CFG})
MYSQL_PASSWORD=$(sed -ne 's/mysql_password\s*=\s*\(.*\)\s*/-p\1/pI' ${MYSQL_CFG})
MYSQL_DBNAME=$(sed -ne 's/mysql_dbname\s*=\s*\(.*\)\s*/\1/pI' ${MYSQL_CFG})
MYSQL_HOST=$(sed -ne 's/mysql_host\s*=\s*\(.*\)\s*/-h\1/pI' ${MYSQL_CFG})
MYSQL_PORT=$(sed -ne 's/mysql_port\s*=\s*\(.*\)\s*/-P\1/pI' ${MYSQL_CFG})
# shellcheck disable=SC2016
MYSQL_QUERY='SELECT `username`, `maildir` from users where `id` <> 0 and `maildir` <> "";'
MYSQL_CMD=("mysql" ${MYSQL_PARAMS} "${MYSQL_USERNAME:=-uroot}" "${MYSQL_PASSWORD:=}" "${MYSQL_HOST:=-hlocalhost}" "${MYSQL_PORT}" "${MYSQL_DBNAME:=email}")
SQLITE_QUERY='select message_id,mid_string from messages where parent_fid=0x17;'
if ${MYSQL_CMD[@]}<<<"exit"&>/dev/null; then
  echo "${MYSQL_QUERY}" | ${MYSQL_CMD[@]} | while read -r USERNAME MAILDIR ; do
    echo "${SQLITE_QUERY}" | sqlite3 "${MAILDIR}/exmdb/exchange.sqlite3" -tabs -noheader | while read -r MESSAGEID MIDSTRING; do
      echo "Learning spam for user ${USERNAME}" | systemd-cat -t grommunio-spam-run
      MSGFILE="$MAILDIR/eml/$MIDSTRING"
      if [[ ! -f "$MSGFILE" ]]; then
        gromox-exm2eml -u "${USERNAME}" "${MESSAGEID}" 2>/dev/null | rspamc learn_spam "$MSGFILE" | systemd-cat -t grommunio-spam-run
      else
        rspamc learn_spam "$MSGFILE" | systemd-cat -t grommunio-spam-run
      	# ??? this will always result in 0 as systemd-cat is run as the last command.
      	EXITSTATUS=$?
      	if [ ${EXITSTATUS} -eq 0 ]; then
      	  /usr/sbin/gromox-mbop -u "${USERNAME}" delmsg -f 0x17 "${MESSAGEID}" | systemd-cat -t grommunio-spam-run
      	fi
      fi
    done
  done
else
  echo "MySQL-Connection couldn't be established, please check your configuration." |systemd-cat -t grommunio-spam-run -p err
fi
EOPATCH

    crpb
    Schränkst du da irgenwo auf den Junk-Mail Ordner ein? Ich habe es bei mir laufen lassen und habe gesehen, dass Emails aus "Gelöschte Objete" verarbeitet werden.
    Bin mir nicht sicher, ob er nicht über das komplette Postfach geht....

    crpb parent_fid=0x17

    0x17 is Hardcoded as the Junk-Folder.

    grommunio-2022121:~ # grommunio-admin exmdb cb@test.local folder list
    Top of Information Store (0x9)
    ├─Sent Items (0xa)
    ├─Deleted Items (0xb)
    ├─Outbox (0xc)
    ├─Inbox (0xd)
    ├─Drafts (0xe)
    ├─Calendar (0xf)
    ├─Journal (0x10)
    ├─Notes (0x11)
    ├─Tasks (0x12)
    ├─Contacts (0x13)
    ├─Junk Email (0x17)
    ├─Sync Issues (0x19)
    └─Conversation Action Settings (0x1d)

    The 0x17 is used in the sqlite3-query which looks for the Message-ID and the maybe missing MID-String(filename in maildir/eml/MIDSTRING)

    Did check again. My Trashbin wasn't touched..

    And now i changed it a bit again because the "gromox-mbop" only has to be called if we even have found a real file and not in both cases.

    ---------------------- enhancements/grommunio-spam-run.sh ----------------------
    index 72214e7..0cfd203 100755
    @@ -26,11 +26,11 @@ if ${MYSQL_CMD[@]}<<<"exit"&>/dev/null; then
             gromox-exm2eml -u "${USERNAME}" "${MESSAGEID}" 2>/dev/null | rspamc learn_spam "$MSGFILE" | systemd-cat -t grommunio-spam-run
           else
             rspamc learn_spam "$MSGFILE" | systemd-cat -t grommunio-spam-run
    -      fi
    -      # ??? this will always result in 0 as systemd-cat is run as the last command.
    -      EXITSTATUS=$?
    -      if [ ${EXITSTATUS} -eq 0 ]; then
    -        /usr/sbin/gromox-mbop -u "${USERNAME}" delmsg -f 0x17 "${MESSAGEID}" | systemd-cat -t grommunio-spam-run
    +      	# ??? this will always result in 0 as systemd-cat is run as the last command.
    +      	EXITSTATUS=$?
    +      	if [ ${EXITSTATUS} -eq 0 ]; then
    +      	  /usr/sbin/gromox-mbop -u "${USERNAME}" delmsg -f 0x17 "${MESSAGEID}" | systemd-cat -t grommunio-spam-run
    +      	fi
           fi
         done
       done

    Gelöscht hat er mit in "Gelöschte Elemente" zum Glück nichts, aber er lern die dort enthaltenen Emails als Spam.
    Ich hatte nach ein paar Minuten über 25.000 gerlente Spam Malis. So viel habe ich in sämtlichen Junk-Mail-Ordnern meines Mailsystems bei weitem nicht an Daten.

    Auf jeden Fall schon mal vielen Dank für die überarbeitete Fassung!

    Kann es sein, dass hier
    gromox-exm2eml -u "${USERNAME}" "${MESSAGEID}" 2>/dev/null | rspamc learn_spam "$MSGFILE" | systemd-cat -t grommunio-spam-run
    das $MSGFILE nach learn_spam raus muss, weil der Inhalt ja über die Pipe kommt?

    Ich habe bei mir den Effekt, dass für einen einzigen Aufruf seitenweise Logs im Journal generiert werden. Dabei liefert er mir solche Pfade /var/lib/gromox/user/0/5/eml//1673386028.18.cp3 die nicht gültig sind (doppelter Slash). Ich befürchte, dass rspam hier dann das ganze Verzeichnis "lernt", was natürlich Unsinn ist.

    Noch etwas anderes: Das Löschen der Email findet nur in einem Fall statt, nämlich wenn die Datei im Filesystem existiert. Wenn sie generiert wird, dann wird nicht gelöscht. Das sollte konsistent sein, oder?

    Die falsch gelenrten rspam Daten bekommt man wohl so bereinigt:

    redis-cli KEYS *BAYES* | xargs redis-cli DEL
    redis-cli KEYS RS* | xargs redis-cli DEL

    Zumindest habe ich das bei mir mal so abgesetzt.

    So, ich habe das Skript jetzt ein klein wenig überarbeitet:

    #!/bin/bash
    
    # add "-d" to delete junk emails after they have been learned
    if [ "$1" = "-d" ]
    then
       DO_DEL=1
    else
       DO_DEL=0
    fi
    
    MYSQL_CFG="/etc/gromox/mysql_adaptor.cfg"
    
    if [ ! -e "${MYSQL_CFG}" ] ; then
      echo "MySQL configuration not found. (${MYSQL_CFG})"
      exit 1
    fi
    
    MYSQL_PARAMS="--skip-column-names --skip-line-numbers"
    MYSQL_USERNAME=$(sed -ne 's/mysql_username\s*=\s*\(.*\)\s*/-u\1/pI' ${MYSQL_CFG})
    MYSQL_PASSWORD=$(sed -ne 's/mysql_password\s*=\s*\(.*\)\s*/-p\1/pI' ${MYSQL_CFG})
    MYSQL_DBNAME=$(sed -ne 's/mysql_dbname\s*=\s*\(.*\)\s*/\1/pI' ${MYSQL_CFG})
    MYSQL_HOST=$(sed -ne 's/mysql_host\s*=\s*\(.*\)\s*/-h\1/pI' ${MYSQL_CFG})
    MYSQL_PORT=$(sed -ne 's/mysql_port\s*=\s*\(.*\)\s*/-P\1/pI' ${MYSQL_CFG})
    # shellcheck disable=SC2016
    MYSQL_QUERY='SELECT `username`, `maildir` from users where `id` <> 0 and `maildir` <> "";'
    MYSQL_CMD=("mysql" ${MYSQL_PARAMS} "${MYSQL_USERNAME:=-uroot}" "${MYSQL_PASSWORD:=}" "${MYSQL_HOST:=-hlocalhost}" "${MYSQL_PORT}" "${MYSQL_DBNAME:=email}")
    SQLITE_QUERY='select message_id,mid_string from messages where parent_fid=0x17;'
    if ${MYSQL_CMD[@]}<<<"exit"&>/dev/null; then
      echo "${MYSQL_QUERY}" | ${MYSQL_CMD[@]} | while read -r USERNAME MAILDIR ; do
        echo "${SQLITE_QUERY}" | sqlite3 "${MAILDIR}/exmdb/exchange.sqlite3" -tabs -noheader | while read -r MESSAGEID MIDSTRING; do
          echo "Learning spam for user ${USERNAME}" | systemd-cat -t grommunio-spam-run
          MSGFILE="$MAILDIR/eml/$MIDSTRING"
          if [[ ! -f "$MSGFILE" ]]; then
            gromox-exm2eml -u "${USERNAME}" "${MESSAGEID}" 2>/dev/null | rspamc learn_spam | systemd-cat -t grommunio-spam-run
            EXITSTATUS=$?
          else
            rspamc learn_spam "$MSGFILE" | systemd-cat -t grommunio-spam-run
            # ??? this will always result in 0 as systemd-cat is run as the last command.
            EXITSTATUS=$?
          fi
          if [ ${EXITSTATUS} -eq 0 -a ${DO_DEL} -eq 1 ]; then
            /usr/sbin/gromox-mbop -u "${USERNAME}" delmsg -f 0x17 "${MESSAGEID}" | systemd-cat -t grommunio-spam-run
          fi
        done
      done
    else
      echo "MySQL-Connection couldn't be established, please check your configuration." |systemd-cat -t grommunio-spam-run -p err
    fi

    Änderungen

    • Übergabe des Emailtextes über Pipe gefixt (siehe oben)
    • Löschen erfolgt in beiden Fällen
    • Löschen an sich über Parameter "-d" steuerbar. Standardfall ist, dass nicht gelöscht wird. Ich habe mich versichert, dass rspamc bei mehrmaligen Lernversuchen für die selbe Email das erkennt und einfach ignoriert. D. h., die Gewichtung ändert sich nicht, egal wie oft man die selbe Spam-Email lernt. Das Verhalten finde ich persönlich als Standardfall besser, als die Emails zu löschen (Stichwort "false positives")

    Bitte übernimm davon gerne, was du für sinnvoll hältst.

      Ich danke Euch, jetzt läuft das ganze super. Ich habe die /usr/lib/systemd/system/grommunio-spam-run.service noch angepasst und -d Schalter eingearbeitet. systemctl daemon-reload gemacht und dann läufts. Jetzt habe ich nur noch die Herausforderung, dass im Grommunio Admin Webinterface 77 untersuchte Mails, davon 2 mit SPAM Klassifizierung und 2100 gelernte. Ich vermute, dass dies aus meinen Fehlversuchen kommt. Die beiden redis-cli Befehle von oben habe ich bereits ausgeführt. Habt Ihr da noch einmal eine Hilfestellung für mich?

      Vielen tausend Dank!

        weini crpb

        Tolle contributions, ist für euch das OK, wenn wir das in unsere QA schicken und ggf. als deliverable anpassen?

        • crpb replied to this.

          Für meinen Mini-Beitrag ist das natürlich ok, das gilt pauschal für alles, was ich hier im Forum teile.

          emtie Die beiden von mir angegebenen Redis Befehle löschen nur die tatsächlichen Bayes Daten aber nicht die Statistiken. Diese wirst du mit rspamc stat_reset los.

            weini Mega! Ganz herzlichen Dank für die super Unterstützung!

            © 2020-2024 grommunio GmbH. All rights reserved. | https://grommunio.com | Data Protection | Legal notice