Daily SPAM Digest?

Hi all,
I use the HestiaCP email server and have no problems at all with it.

But I’d like to know whether thereany way to actually get a daily digest of rejected emails (regarded as spam) or have them all marked as “SPAM*” instead of being plain rejected?
For now I have a cron that sends me the rejected.log file from EXIM but it there another way that present data a bit better? Like from/to/subject/reason_for_rejection

If it’s rejected, we don’t have any clue about a possible false postivie.

I do NOT have the “Reject Spam” option turned ON
Thanks for any help
Steve

Hi @sjordi,

If you didn’t activate that option, then the rejectlog doesn’t contain any rejected SPAM message (using SPAM message I mean a message filtered and scored by Spamassassin). What you are viewing in that log are tries to send messages from IPs blocked by the DNSBL (DNS Block Lists) used by Exim. By default it uses two:

$ cat /etc/exim4/dnsbl.conf
bl.spamcop.net
zen.spamhaus.org

You could remove them from the file but I can’t recommend it, those dnsbl block a lot of spammers.

I made below script, I don’t know whether it would be useful to you but I left it here just in case.

The script will find mail messages from last day (by default) and will check all of them flagged as Spam and will print something like this:

DATE                 ID                SCORE  FROM                                       TO                  SUBJECT              FILE
2024-09-25_12:15:13  1stBd8-00AwCC-aa  55     "Troy | example.com" <[email protected]>    [email protected]      =?UTF-8?Q?help=3F?=  /home/user1/mail/example.net/me/.Spam/cur/1727207727.M126422P2606992.myhost.example.net:2,
2024-09-25_16:22:27  1stBd8-00AwCC-bb  82     John <[email protected]>                    [email protected]  Fancy subject        /home/user1/mail/example.net/random/.Spam/cur/1727207737.M126411P2606993.myhost.example.net:2,
2024-09-25_20:38:44  1stBd8-00AwCC-cc  65     <[email protected]>                      [email protected]      Money money          /home/user1/mail/example.net/me/.Spam/cur/1727207747.M126411P2606994.myhost.example.net:2,

The only argument you can use is an integer to search for messages created on those days.

This will search for messages created on last day.

./script

This will search for messages created on last 7 days.

./script 7

Note: the output uses long lines so I recommend redirecting the output to a file and view the contents using a file viewer setting no wrap for lines.

The script (use at your own risk :wink: )

#!/usr/bin/env bash
days="${1-1}"
if [[ $EUID -ne 0 ]]; then
        echo "Error: Script must be executed as root user" >&2
        exit 1
fi

if [[ -t 1 ]]; then
        interactive=1
fi

msg="$(find /home/*/mail/ -type f -mtime -"$days" -regextype egrep -regex ".*/[0-9]{10}\..*"  -print0 | xargs --null -I {} grep -El 'X-Spam-Status: Yes$' '{}' 2>/dev/null)"
if [[ -z $msg ]]; then
        echo "I didn't find any Spam message"
        exit
fi
result=""
ifs="$IFS"
IFS=$'\n'
for i in $msg; do
        if [[ $interactive -eq 1 ]]; then
                printf 'Checking %s \033[0K\r' "$i"
        fi
        date="$(date -d @"$(basename "$i" | cut -d '.' -f1)" +'%Y-%m-%d_%H:%M:%S')"
        score="$(grep -E '^X-Spam-Score:' "$i" | head -n1 | cut -d ' ' -f2-)"
        from="$(grep -E '^From:.*@' "$i" 2>/dev/null | head -n1 | cut -d ' ' -f2-)"
        user="$(cut -d '/' -f6 <<<"$i")"
        domain="$(cut -d '/' -f5 <<<"$i")"
        to="$user@$domain"
        subject="$(grep -E '^Subject:.*' "$i" 2>/dev/null | head -n1 | cut -d ' ' -f2-)"
        id="$(grep -E '^\s*id\s.+' "$i" 2>/dev/null | head -n1 | cut -d ' ' -f2)"
        result+="$date§$id§$score§$from§$to§$subject§$i\n"
done
IFS="$ifs"
if [[ $interactive -eq 1 ]]; then
        printf "\033[0K\r"
fi
echo -e "$result" | column -t -s '§' -N DATE,ID,SCORE,FROM,TO,SUBJECT,FILE | sort -n

Edit: added -regextype egrep -regex ".*/[0-9]{10}\..*" to find command so only file messages are checked.

Edit 2: replaced find parameter -ctime by -mtime

2 Likes

Perfect, exactly what I needed.
Thanks x 1000 !

1 Like

My knowledge is limited. How could I add this to the script, to receive on local email.

#!/bin/bash
email="[email protected]"
subject="Script"
message="Mail Spam"
echo "$message" | mail -s "$subject" "$email"

Thank you for your patience!

1 Like

In the script, replace this:

echo -e "$result" | column -t -s '§' -N DATE,ID,SCORE,FROM,TO,SUBJECT,FILE | sort -n

by this:

email="[email protected]"
subject="Script"
echo -e "$result" | column -t -s '§' -N DATE,ID,SCORE,FROM,TO,SUBJECT,FILE | sort -n | mail -s "$subject" "$email"

Thank you! When I run the script I get this. The notification is in the email.

date: invalid date ‘@dovecot’domain.com/home/dovecot.index.cache

1 Like

Replace this:

msg="$(find /home/*/mail/ -type f -mtime -"$days" -print0 | xargs --null -I {} grep -El 'X-Spam-Status: Yes$' '{}' 2>/dev/null)"

by this:

msg="$(find /home/*/mail/ -type f -mtime -"$days" -regextype egrep -regex ".*/[0-9]{10}\..*"  -print0 | xargs --null -I {} grep -El 'X-Spam-Status: Yes$' '{}' 2>/dev/null)"

and try again.

No errors. Thank you.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.