First post is a handy mail script I have put together.
I’m using this to see how much mail I’m sending, which is necessary because I have a few WordPress sites on this machine and they seem to be pretty easy to hack. Using this script gives me an indication of outgoing mail volume.
Firstly I changed my mail.log to rotate daily instead of monthly so that when I’m investigating it I don’t need to worry about the date. The file will only have the info from yesterday.
So I removed “/var/log/mail.log” from the weekly rotation of /etc/logrotate.d/rsyslog and put it at the end of the file like this;
/etc/logrotate.d/rsyslog
/var/log/syslog
/var/log/mail.info
/var/log/mail.warn
/var/log/mail.err
/var/log/daemon.log
/var/log/kern.log
/var/log/auth.log
/var/log/user.log
/var/log/lpr.log
/var/log/cron.log
/var/log/debug
/var/log/messages
{
rotate 4
weekly
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
/var/log/mail.log {
rotate 28
daily
missingok
notifempty
compress
delaycompress
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
Next I created a new file “/usr/local/bin/ultimate_mail_audit.sh“. You can see I’m looking at “mail.log.1”. Since it gets rotated daily this is the log for yesterday.
/usr/local/bin/ultimate_mail_audit.sh
!/bin/bash
#=== CONFIGURATION ===
ADMIN_EMAIL="user@something.com,user2@something.com"
FROM_ADDRESS="info@localhost.com"
FROM_HEADER="From: Daily Outgoing Email Audit <$FROM_ADDRESS>"
MAIL_LOG="/var/log/mail.log.1"
TMP_REPORT="/tmp/mail_audit_$(date +%F_%H-%M-%S).txt"
TMP_QUEUE_MAP="/tmp/queueid_to_user.$$"
TMP_MAIL_SUMMARY="/tmp/mail_summary.$$"
touch "$TMP_REPORT" "$TMP_QUEUE_MAP" "$TMP_MAIL_SUMMARY"
#--- HEADER ---
{
echo "Legitimate Outgoing Mail Summary:"
echo "____________________________"
} >> "$TMP_REPORT"
#--- Step 1: Map queue IDs to authenticated SASL usernames ---
grep "sasl_username=" "$MAIL_LOG" | while read -r line; do
queue_id=$(echo "$line" | grep -oE '[A-F0-9]{10,}')
user=$(echo "$line" | grep -oP 'sasl_username=\K\S+')
[[ -n "$queue_id" && -n "$user" ]] && echo "$queue_id:$user"
done >> "$TMP_QUEUE_MAP"
#--- Step 2: Map queue IDs to local pickup user IDs ---
grep 'postfix/pickup' "$MAIL_LOG" | grep -oP '([A-F0-9]{10,}): uid=\K\d+' | while read -r uid; do
queue_id=$(grep "uid=${uid}" "$MAIL_LOG" | grep -oE '[A-F0-9]{10,}')
user=$(getent passwd "$uid" | cut -d: -f1)
[[ -n "$queue_id" && -n "$user" ]] && echo "$queue_id:$user"
done >> "$TMP_QUEUE_MAP"
#--- Step 3: Extract legit outgoing emails ---
grep 'status=' "$MAIL_LOG" | grep 'postfix/' | grep -v 'relay=local' | while read -r line; do
queue_id=$(echo "$line" | awk '{print $6}' | sed 's/://')
to=$(echo "$line" | grep -oP 'to=<\K[^>]+')
from=$(grep "$queue_id" "$MAIL_LOG" | grep 'from=<' | head -n1 | grep -oP 'from=<\K[^>]+')
user=$(grep "^${queue_id}:" "$TMP_QUEUE_MAP" | cut -d: -f2)
if [[ -n "$user" && -n "$from" && -n "$to" ]]; then
echo "$from -> $to"
fi
done | sort | uniq -c | sort -nr >> "$TMP_MAIL_SUMMARY"
#--- Step 4: Output to report ---
cat "$TMP_MAIL_SUMMARY" >> "$TMP_REPORT"
#--- Step 5: Email and cleanup ---
mail -a "$FROM_HEADER" -r "$FROM_ADDRESS" -s "Daily Email Audit - $(hostname)" "$ADMIN_EMAIL" < "$TMP_REPORT"
rm -f "$TMP_QUEUE_MAP" "$TMP_MAIL_SUMMARY" "$TMP_REPORT"
Now we need a cronjob to run this script. So run “crontab -e” and put this in there
30 7 * * * /usr/local/bin/ultimate_mail_audit.sh
I’m running this on;
SYSTEM INFORMATION | |
---|---|
OS type and version | Ubuntu Linux 22.04.5 |
Usermin version | 2.302 |
Virtualmin version | 7.30.8 |
Theme version | 24.02 |
Apache version | 2.4.52 |
Package updates | All installed packages are up to date |
Leave a Reply