Documents the 2026-03-14 incident where MajorAir's public IP was banned by the postfix-sasl jail after repeated SASL auth failures, silently blocking all IMAP connections from Spark Desktop. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.7 KiB
Mail Client Stops Receiving: Fail2ban IMAP Self-Ban
🛑 Problem
A mail client stops receiving new email on one device while other devices (e.g., phone on cellular) continue to work normally. The mail server is healthy — Postfix is delivering to maildir and Dovecot is running — but the affected device receives no new messages and is never prompted for credentials.
🔍 Diagnosis
Step 1 — Confirm the mail server is delivering
ssh root@<mailserver> "tail -20 /var/log/maillog | grep 'status=sent'"
If you see status=sent (delivered to maildir), the server is working. The issue is on the client side.
Step 2 — Check if the client is connecting at all
ssh root@<mailserver> "grep '<client_ip>' /var/log/maillog | tail -10"
If there are zero results, the client is not reaching the server at all — not a credentials or sync issue.
Step 3 — Get the client's current public IP
Run this on the affected machine:
curl -s https://api.ipify.org
Step 4 — Check if that IP is banned by Fail2ban
ssh root@<mailserver> "fail2ban-client status postfix-sasl"
ssh root@<mailserver> "fail2ban-client status dovecot-invalid"
Look for the IP in the Banned IP list. If it's there, that's your problem.
Step 5 — Find when the ban was applied
ssh root@<mailserver> "grep '<client_ip>' /var/log/fail2ban.log | tail -20"
This shows the exact timestamps of auth failures and the ban event.
✅ Fix
Unban the IP from all relevant jails:
fail2ban-client set postfix-sasl unbanip <IP>
fail2ban-client set dovecot-invalid unbanip <IP>
Mail should resume immediately without restarting any services.
🔁 Why This Happens
| Symptom | Cause |
|---|---|
| One device stops getting mail, others don't | Each device has a different public IP. Only the banned IP is blocked. |
| No auth prompt in the mail client | Fail2ban issues a TCP REJECT — the client sees a connection error, not an auth failure, so it doesn't prompt for new credentials. It silently retries on a timer. |
| Multiple failed attempts before ban | The mail client retried with a previously valid session token or stale auth state, triggering the maxretry threshold. |
Ban on postfix-sasl blocks IMAP (port 993) |
The postfix-sasl jail monitors ports 25, 465, 587, 143, 993, 110, and 995 — not just SMTP. A failed SMTP auth attempt can ban access to IMAP as well. |
⚠️ Key Notes
- Fail2ban
postfix-saslcovers all mail ports — a single jail can lock out SMTP and IMAP simultaneously. - The affected device's IP is never logged in Dovecot once banned — the rejection happens at the iptables/Fail2ban layer before Dovecot sees the connection.
- Tailscale doesn't help if the mail client connects via the public interface — the ban applies to the public IP, not the Tailscale IP.
- Check when the ban happened:
grep '<IP>' /var/log/fail2ban.logshows exact timestamps.
🔎 Quick Diagnostic Commands
# Get your current public IP (run on affected machine)
curl -s https://api.ipify.org
# Check all Fail2ban jail statuses
fail2ban-client status
# Check a specific jail for a banned IP
fail2ban-client status postfix-sasl
fail2ban-client status dovecot-invalid
# Unban from a specific jail
fail2ban-client set postfix-sasl unbanip <IP>
fail2ban-client set dovecot-invalid unbanip <IP>
# Unban from all jails at once
for jail in $(fail2ban-client status | grep "Jail list" | sed 's/.*://;s/,/ /g'); do
fail2ban-client set $jail unbanip <IP> 2>/dev/null && echo "Unbanned from $jail"
done
# Find when a specific IP was banned
grep '<IP>' /var/log/fail2ban.log | tail -20