Fix bounce and spam detection to exclude auth failures

Improved accuracy:
- Bounces now only count actual SMTP delivery failures (550-554 codes)
- Excludes SMTP/IMAP/FTP authentication failures from bounce count
- Spam rejected now only counts actually rejected emails
- Excludes emails delivered to spam folder (those are successful deliveries)
- Updated display sections to match new filtering logic

This fixes the misleading "334 bounced" count that was actually
showing authentication failures, not email delivery problems.
This commit is contained in:
cschantz
2025-12-31 19:13:01 -05:00
parent d2e5d3f940
commit 0d372eab79
+12 -8
View File
@@ -159,17 +159,19 @@ delivered=$(grep -ci "=> .*$search_pattern\|delivered.*$search_pattern" "$TEMP_M
delivered=$(echo "$delivered" | head -1 | tr -d '\n\r') delivered=$(echo "$delivered" | head -1 | tr -d '\n\r')
sent=$(grep -ci "<=.*$search_pattern" "$TEMP_MATCHES" 2>/dev/null || echo 0) sent=$(grep -ci "<=.*$search_pattern" "$TEMP_MATCHES" 2>/dev/null || echo 0)
sent=$(echo "$sent" | head -1 | tr -d '\n\r') sent=$(echo "$sent" | head -1 | tr -d '\n\r')
bounced=$(grep -ci "bounce.*$search_pattern\|failed.*$search_pattern\|550.*$search_pattern" "$TEMP_MATCHES" 2>/dev/null || echo 0) # Only count actual email bounces, not auth failures
bounced=$(grep -i "$search_pattern" "$TEMP_MATCHES" | grep -v "authenticator failed\|Authentication failed" | grep -ci "550\|551\|552\|553\|554\|bounced\|Mail delivery failed" 2>/dev/null || echo 0)
bounced=$(echo "$bounced" | head -1 | tr -d '\n\r') bounced=$(echo "$bounced" | head -1 | tr -d '\n\r')
deferred=$(grep -ci "deferred.*$search_pattern\|retry.*$search_pattern\|temporarily rejected" "$TEMP_MATCHES" 2>/dev/null || echo 0) deferred=$(grep -ci "deferred.*$search_pattern\|retry.*$search_pattern\|temporarily rejected" "$TEMP_MATCHES" 2>/dev/null || echo 0)
deferred=$(echo "$deferred" | head -1 | tr -d '\n\r') deferred=$(echo "$deferred" | head -1 | tr -d '\n\r')
rejected=$(grep -ci "rejected.*$search_pattern\|denied.*$search_pattern\|blocked.*$search_pattern" "$TEMP_MATCHES" 2>/dev/null || echo 0) rejected=$(grep -i "$search_pattern" "$TEMP_MATCHES" | grep -v "authenticator failed\|Authentication failed" | grep -ci "rejected RCPT\|rejected.*relay.*denied\|rejected.*spam" 2>/dev/null || echo 0)
rejected=$(echo "$rejected" | head -1 | tr -d '\n\r') rejected=$(echo "$rejected" | head -1 | tr -d '\n\r')
spf_fail=$(grep -ci "SPF.*fail.*$search_pattern" "$TEMP_MATCHES" 2>/dev/null || echo 0) spf_fail=$(grep -ci "SPF.*fail.*$search_pattern" "$TEMP_MATCHES" 2>/dev/null || echo 0)
spf_fail=$(echo "$spf_fail" | head -1 | tr -d '\n\r') spf_fail=$(echo "$spf_fail" | head -1 | tr -d '\n\r')
dkim_fail=$(grep -ci "DKIM.*fail.*$search_pattern" "$TEMP_MATCHES" 2>/dev/null || echo 0) dkim_fail=$(grep -ci "DKIM.*fail.*$search_pattern" "$TEMP_MATCHES" 2>/dev/null || echo 0)
dkim_fail=$(echo "$dkim_fail" | head -1 | tr -d '\n\r') dkim_fail=$(echo "$dkim_fail" | head -1 | tr -d '\n\r')
spam_rejected=$(grep -ci "spam.*$search_pattern\|SpamAssassin.*rejected.*$search_pattern" "$TEMP_MATCHES" 2>/dev/null || echo 0) # Only count actually rejected spam, not spam delivered to spam folder
spam_rejected=$(grep -i "$search_pattern" "$TEMP_MATCHES" | grep -i "spam" | grep -ci "rejected\|blocked\|denied" 2>/dev/null || echo 0)
spam_rejected=$(echo "$spam_rejected" | head -1 | tr -d '\n\r') spam_rejected=$(echo "$spam_rejected" | head -1 | tr -d '\n\r')
greylist=$(grep -ci "greylist.*$search_pattern\|greylisted.*$search_pattern" "$TEMP_MATCHES" 2>/dev/null || echo 0) greylist=$(grep -ci "greylist.*$search_pattern\|greylisted.*$search_pattern" "$TEMP_MATCHES" 2>/dev/null || echo 0)
greylist=$(echo "$greylist" | head -1 | tr -d '\n\r') greylist=$(echo "$greylist" | head -1 | tr -d '\n\r')
@@ -507,9 +509,9 @@ fi
if [ "$bounced" -gt 0 ]; then if [ "$bounced" -gt 0 ]; then
print_header "RECENT BOUNCES/FAILURES (last 5 from past $hours hours)" print_header "RECENT BOUNCES/FAILURES (last 5 from past $hours hours)"
echo "" echo ""
print_warning "PROOF - These emails failed recently:" print_warning "PROOF - These emails failed delivery:"
echo "" echo ""
grep -i "bounce.*$search_pattern\|failed.*$search_pattern\|550.*$search_pattern" "$TEMP_MATCHES" | tail -5 | while read line; do grep -i "$search_pattern" "$TEMP_MATCHES" | grep -v "authenticator failed\|Authentication failed" | grep -i "550\|551\|552\|553\|554\|bounced\|Mail delivery failed" | tail -5 | while read line; do
timestamp=$(echo "$line" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}|[A-Z][a-z]{2} [0-9]+ [0-9]{2}:[0-9]{2}:[0-9]{2}' | head -1) timestamp=$(echo "$line" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}|[A-Z][a-z]{2} [0-9]+ [0-9]{2}:[0-9]{2}:[0-9]{2}' | head -1)
if [ -n "$timestamp" ]; then if [ -n "$timestamp" ]; then
echo -e " ${RED}[$timestamp]${NC} $line" echo -e " ${RED}[$timestamp]${NC} $line"
@@ -522,14 +524,14 @@ if [ "$bounced" -gt 0 ]; then
# Extract bounce reasons # Extract bounce reasons
print_header "COMMON BOUNCE REASONS" print_header "COMMON BOUNCE REASONS"
echo "" echo ""
grep -i "bounce\|550\|fail" "$TEMP_MATCHES" | grep -oE "550 .*|User unknown|Mailbox.*full|Relay.*denied|blocked" | sort | uniq -c | sort -rn | head -5 grep -i "$search_pattern" "$TEMP_MATCHES" | grep -v "authenticator failed\|Authentication failed" | grep -i "550\|551\|bounced" | grep -oE "550 [^:]*|551 [^:]*|User unknown|Mailbox.*full|Relay.*denied|No such user" | sort | uniq -c | sort -rn | head -5
echo "" echo ""
fi fi
if [ "$rejected" -gt 0 ]; then if [ "$rejected" -gt 0 ]; then
print_header "RECENT REJECTIONS (last 5)" print_header "RECENT REJECTIONS (last 5)"
echo "" echo ""
grep -i "rejected.*$search_pattern\|denied.*$search_pattern\|blocked.*$search_pattern" "$TEMP_MATCHES" | tail -5 | while read line; do grep -i "$search_pattern" "$TEMP_MATCHES" | grep -v "authenticator failed\|Authentication failed" | grep -i "rejected RCPT\|rejected.*relay.*denied\|rejected.*spam" | tail -5 | while read line; do
echo " $line" echo " $line"
done done
echo "" echo ""
@@ -538,7 +540,9 @@ fi
if [ "$spam_rejected" -gt 0 ]; then if [ "$spam_rejected" -gt 0 ]; then
print_header "RECENT SPAM REJECTIONS (last 5)" print_header "RECENT SPAM REJECTIONS (last 5)"
echo "" echo ""
grep -i "spam.*$search_pattern\|SpamAssassin.*rejected" "$TEMP_MATCHES" | tail -5 | while read line; do print_info "Emails rejected as spam (not delivered):"
echo ""
grep -i "$search_pattern" "$TEMP_MATCHES" | grep -i "spam" | grep -i "rejected\|blocked\|denied" | tail -5 | while read line; do
timestamp=$(echo "$line" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}|[A-Z][a-z]{2} [0-9]+ [0-9]{2}:[0-9]{2}:[0-9]{2}' | head -1) timestamp=$(echo "$line" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}|[A-Z][a-z]{2} [0-9]+ [0-9]{2}:[0-9]{2}:[0-9]{2}' | head -1)
if [ -n "$timestamp" ]; then if [ -n "$timestamp" ]; then
echo -e " ${RED}[$timestamp]${NC} $line" echo -e " ${RED}[$timestamp]${NC} $line"