From c780c8ab2e75de280220af483b9afe365183ca4a Mon Sep 17 00:00:00 2001 From: cschantz Date: Wed, 31 Dec 2025 18:55:59 -0500 Subject: [PATCH] Improve email diagnostics output clarity and logic Key improvements: - Add Quick Summary section at top for instant status - Always show main metrics (sent/received/delivered) even if 0 - Fix contradictory "account not found" when successful logins exist - Better verdict logic for authentication-only scenarios - Clearer section headers ("Mailbox Access Activity" vs delivery) - Group problems together, only show if they exist - Improve status messages with context Output now shows: 1. Quick Summary - instant understanding of status 2. Email Delivery Activity - always show main counts 3. Problems section - only if issues detected 4. Mailbox Access Activity - clarify IMAP/POP3 vs email delivery 5. Account Status - use successful logins as proof account exists 6. Better verdicts for auth-only, no-activity scenarios --- modules/email/email-diagnostics.sh | 198 +++++++++++++++++++++-------- 1 file changed, 142 insertions(+), 56 deletions(-) diff --git a/modules/email/email-diagnostics.sh b/modules/email/email-diagnostics.sh index d87e591..b36bdb0 100755 --- a/modules/email/email-diagnostics.sh +++ b/modules/email/email-diagnostics.sh @@ -136,10 +136,7 @@ echo "" # Categorize activity ################################################################################ -print_header "📊 Activity Summary" -echo "" - -# Count different types (sanitize to remove newlines) +# Count different types first (sanitize to remove newlines) delivered=$(grep -ci "=> .*$search_pattern\|delivered.*$search_pattern" "$TEMP_MATCHES" 2>/dev/null || echo 0) delivered=$(echo "$delivered" | head -1 | tr -d '\n\r') sent=$(grep -ci "<=.*$search_pattern" "$TEMP_MATCHES" 2>/dev/null || echo 0) @@ -167,44 +164,100 @@ auth_failed=$(echo "$auth_failed" | head -1 | tr -d '\n\r') auth_success=$(grep -ci "Logged in\|Login:.*user=.*$search_pattern" "$TEMP_AUTH" 2>/dev/null || echo 0) auth_success=$(echo "$auth_success" | head -1 | tr -d '\n\r') -if [ "$delivered" -gt 0 ]; then - print_success "✅ Delivered: $delivered emails successfully delivered" +################################################################################ +# Quick Summary +################################################################################ + +print_header "⚡ Quick Summary" +echo "" + +# Determine quick status +total_problems=$((bounced + rejected + spam_rejected)) +total_email_activity=$((sent + received + delivered)) + +if [ "$total_email_activity" -gt 0 ] && [ "$total_problems" -eq 0 ]; then + print_success "✅ Email appears to be working (${total_email_activity} email events, no problems)" +elif [ "$total_email_activity" -gt 0 ] && [ "$total_problems" -gt 0 ]; then + print_warning "âš ī¸ Partial email issues (${total_email_activity} delivered, ${total_problems} failed)" +elif [ "$total_problems" -gt 0 ]; then + print_error "❌ Email delivery problems detected (${total_problems} failures)" +elif [ "$auth_success" -gt 0 ] && [ "$total_email_activity" -eq 0 ]; then + print_info "📱 Account active (${auth_success} logins) but no email traffic in last ${hours}h" +elif [ "$auth_failed" -gt 0 ]; then + print_warning "âš ī¸ Failed login attempts detected (${auth_failed} attempts) - possible attack" +else + print_info "â„šī¸ No activity detected in last ${hours} hours" +fi + +echo "" + +################################################################################ +# Detailed Activity Breakdown +################################################################################ + +print_header "📊 Email Delivery Activity (last $hours hours)" +echo "" + +# Always show main metrics for clarity +if [ "$received" -gt 0 ]; then + print_success "đŸ“Ĩ Received: $received emails (incoming TO this $check_label)" +else + echo "đŸ“Ĩ Received: 0 emails (no incoming mail)" fi if [ "$sent" -gt 0 ]; then - print_info "📤 Sent: $sent emails sent FROM this $check_label" + print_success "📤 Sent: $sent emails (outgoing FROM this $check_label)" +else + echo "📤 Sent: 0 emails (no outgoing mail)" fi +if [ "$delivered" -gt 0 ]; then + print_success "✅ Delivered: $delivered successful deliveries" +else + echo "✅ Delivered: 0 (no completed deliveries logged)" +fi + +echo "" + +# Only show problems if they exist +has_problems=0 + if [ "$bounced" -gt 0 ]; then print_error "❌ Bounced: $bounced emails bounced/failed" + has_problems=1 fi if [ "$deferred" -gt 0 ]; then print_warning "⏸ Deferred: $deferred emails temporarily delayed" + has_problems=1 fi if [ "$rejected" -gt 0 ]; then print_error "đŸšĢ Rejected: $rejected emails blocked/rejected" -fi - -if [ "$spf_fail" -gt 0 ]; then - print_warning "⚠ SPF Failures: $spf_fail authentication failures" -fi - -if [ "$dkim_fail" -gt 0 ]; then - print_warning "⚠ DKIM Failures: $dkim_fail signature failures" + has_problems=1 fi if [ "$spam_rejected" -gt 0 ]; then print_error "đŸšĢ Spam Rejected: $spam_rejected emails marked as spam" + has_problems=1 +fi + +if [ "$spf_fail" -gt 0 ]; then + print_warning "⚠ SPF Failures: $spf_fail authentication failures" + has_problems=1 +fi + +if [ "$dkim_fail" -gt 0 ]; then + print_warning "⚠ DKIM Failures: $dkim_fail signature failures" + has_problems=1 fi if [ "$greylist" -gt 0 ]; then - print_info "⏱ Greylisted: $greylist emails temporarily delayed (anti-spam measure)" + print_info "⏱ Greylisted: $greylist emails temporarily delayed (normal anti-spam)" fi -if [ "$received" -gt 0 ]; then - print_info "đŸ“Ĩ Received: $received emails received TO this $check_label" +if [ $has_problems -eq 0 ]; then + print_success "✓ No delivery problems detected" fi # Show email traffic patterns @@ -235,15 +288,17 @@ fi # Show authentication summary if [ -s "$TEMP_AUTH" ]; then echo "" - print_header "🔐 Authentication Activity (IMAP/POP3 Login Attempts)" + print_header "🔐 Mailbox Access Activity (IMAP/POP3 Logins)" + echo "" + print_info "This shows if customer can access their mailbox (not email delivery)" echo "" if [ "$auth_success" -gt 0 ]; then - print_success "✅ Successful Logins: $auth_success (password is correct)" + print_success "✅ Successful Logins: $auth_success (password is correct, mailbox accessible)" fi if [ "$auth_failed" -gt 0 ]; then - print_error "❌ Failed Logins: $auth_failed (WRONG PASSWORD or unauthorized access)" + print_error "❌ Failed Logins: $auth_failed (WRONG PASSWORD or brute-force attack)" # Extract IPs attempting failed logins failed_ips=$(grep -i "auth failed\|Login aborted" "$TEMP_AUTH" | grep -oE "rip=[0-9.]+|from [0-9.]+" | sed 's/rip=//; s/from //' | sort | uniq -c | sort -rn) @@ -273,51 +328,57 @@ if [ "$check_type" != "2" ]; then # Check if email account exists in various locations account_found=0 + maildir="" # Check cPanel mail directory if [ -d "/home/*/mail/$domain_part/$local_part" ]; then maildir=$(find /home/*/mail/$domain_part/$local_part -maxdepth 0 -type d 2>/dev/null | head -1) if [ -n "$maildir" ]; then - print_success "✅ Email account EXISTS on this server" account_found=1 - - # Get disk usage - if [ -d "$maildir" ]; then - disk_usage=$(du -sh "$maildir" 2>/dev/null | awk '{print $1}') - print_info "📊 Mailbox size: $disk_usage" - - # Count messages - msg_count=$(find "$maildir" -type f -name "*:2,*" 2>/dev/null | wc -l) - print_info "đŸ“Ŧ Messages stored: $msg_count" - fi - - # Check for quota file - quota_file=$(find /home/*/mail/$domain_part/$local_part -name "maildirsize" 2>/dev/null | head -1) - if [ -f "$quota_file" ]; then - quota_info=$(head -1 "$quota_file" 2>/dev/null) - print_info "💾 Quota: $quota_info" - fi fi fi # Check Plesk mail directory if [ $account_found -eq 0 ] && [ -d "/var/qmail/mailnames/$domain_part/$local_part" ]; then - print_success "✅ Email account EXISTS on this server (Plesk)" account_found=1 maildir="/var/qmail/mailnames/$domain_part/$local_part" - disk_usage=$(du -sh "$maildir" 2>/dev/null | awk '{print $1}') - print_info "📊 Mailbox size: $disk_usage" fi # Check generic /var/mail if [ $account_found -eq 0 ] && [ -f "/var/mail/$local_part" ]; then - print_success "✅ Email account EXISTS in /var/mail" account_found=1 - disk_usage=$(du -sh "/var/mail/$local_part" 2>/dev/null | awk '{print $1}') - print_info "📊 Mailbox size: $disk_usage" + maildir="/var/mail/$local_part" fi - if [ $account_found -eq 0 ]; then + # If successful logins exist, account must exist (even if we can't find the directory) + if [ $account_found -eq 0 ] && [ "$auth_success" -gt 0 ]; then + account_found=1 + print_success "✅ Email account EXISTS (confirmed by successful logins)" + print_warning " Note: Mailbox directory not found in standard locations" + elif [ $account_found -eq 1 ]; then + print_success "✅ Email account EXISTS on this server" + + # Show mailbox details if we found the directory + if [ -n "$maildir" ] && [ -d "$maildir" ]; then + disk_usage=$(du -sh "$maildir" 2>/dev/null | awk '{print $1}') + if [ -n "$disk_usage" ]; then + print_info "📊 Mailbox size: $disk_usage" + fi + + # Count messages + msg_count=$(find "$maildir" -type f -name "*:2,*" 2>/dev/null | wc -l) + if [ "$msg_count" -gt 0 ]; then + print_info "đŸ“Ŧ Messages stored: $msg_count" + fi + + # Check for quota file + quota_file=$(find "$maildir" -name "maildirsize" 2>/dev/null | head -1) + if [ -f "$quota_file" ]; then + quota_info=$(head -1 "$quota_file" 2>/dev/null) + print_info "💾 Quota: $quota_info" + fi + fi + else print_warning "⚠ Email account NOT FOUND on this server" echo "" echo "This could mean:" @@ -346,36 +407,61 @@ fi print_header "🔍 Diagnostic Result" echo "" -if [ "$delivered" -gt 0 ] && [ "$bounced" -eq 0 ] && [ "$rejected" -eq 0 ]; then +# Determine overall status +if [ "$delivered" -gt 0 ] && [ "$bounced" -eq 0 ] && [ "$rejected" -eq 0 ] && [ "$spam_rejected" -eq 0 ]; then print_success "✅ EMAIL IS WORKING PROPERLY" echo "" echo "Evidence: $delivered successful deliveries in the last $hours hours" - echo "No bounces or rejections detected" - echo "Proof shown below with timestamps" + echo "No bounces, rejections, or spam filtering detected" echo "" + elif [ "$delivered" -gt 0 ] && [ "$bounced" -gt 0 ]; then print_warning "⚠ EMAIL PARTIALLY WORKING" echo "" echo "Some emails delivered ($delivered) but some failed ($bounced)" echo "Check bounce reasons below for details" echo "" -elif [ "$bounced" -gt 0 ] || [ "$rejected" -gt 0 ]; then - print_error "❌ EMAIL HAS PROBLEMS" + +elif [ "$bounced" -gt 0 ] || [ "$rejected" -gt 0 ] || [ "$spam_rejected" -gt 0 ]; then + print_error "❌ EMAIL HAS DELIVERY PROBLEMS" echo "" - echo "Emails are being rejected or bouncing" + echo "Emails are being rejected, bouncing, or filtered as spam" echo "See details below for why" echo "" + elif [ "$deferred" -gt 0 ]; then print_warning "⏸ EMAIL DELAYED" echo "" echo "Emails are being deferred (temporary failures)" - echo "This usually resolves itself" + echo "This usually resolves itself within minutes" echo "" + +elif [ "$sent" -gt 0 ] || [ "$received" -gt 0 ]; then + print_info "đŸ“Ŧ EMAIL ACTIVITY DETECTED" + echo "" + echo "Email traffic logged but no delivery confirmations in last $hours hours" + echo "This may be normal depending on email volume" + echo "" + +elif [ "$auth_success" -gt 0 ] || [ "$auth_failed" -gt 0 ]; then + print_info "📱 MAILBOX ACCESS ONLY" + echo "" + echo "No email delivery activity, only mailbox access (IMAP/POP3) detected" + echo "This means the account exists and is being checked, but no emails sent/received" + echo "" + if [ "$auth_success" -gt 0 ]; then + echo "✓ Authentication is working (customer can access mailbox)" + fi + if [ "$auth_failed" -gt 0 ]; then + echo "⚠ Failed login attempts detected (see details below)" + fi + echo "" + else - print_info "đŸ“Ŧ EMAILS SENT, AWAITING CONFIRMATION" + print_warning "❌ NO EMAIL ACTIVITY FOUND" echo "" - echo "Emails were sent but no delivery confirmation yet" - echo "Check again in a few minutes" + echo "No email sending, receiving, or mailbox access in the last $hours hours" + echo "Account may be inactive or not used during this time period" echo "" fi