2026.10 / access recovery 074
Docker Mailserver Fail2Ban blocked my IP: unban it safely
IMAP, SMTP submission, or both suddenly time out from one network, even though Docker Mailserver is healthy and other clients still connect. If that network recently produced repeated bad logins, Fail2Ban may have blocked its public source address.
Do not begin by disabling Fail2Ban. First prove that a ban—not DNS, a closed port, TLS, or the mail service—is stopping this client. Then stop the device that is repeating the bad credential, remove only the confirmed source address, and verify that the relevant jail still catches deliberate failures.
An unban restores access; it does not fix the event that triggered the ban. Stop the failing client before removing the block or the address can be banned again immediately.
Fast recovery path
- Confirm the failure affects one public source network rather than every client.
- Identify that source address privately and match it to Docker Mailserver’s ban list.
- Use logs and jail status to identify the triggering service.
- Stop or correct every client behind that address.
- Unban only that exact address with the DMS setup command.
- Retest IMAP or SMTP once and confirm Fail2Ban remains enabled.
1. Distinguish a ban from a general outage
A Fail2Ban block is usually source-specific. Run the same narrow connection test from two genuinely different networks, such as the affected broadband connection and a mobile connection:
# IMAPS: implicit TLS
openssl s_client -connect mail.example.com:993 \
-servername mail.example.com -brief
# SMTP submission: STARTTLS
openssl s_client -starttls smtp \
-connect mail.example.com:587 \
-servername mail.example.com -brief
Replace the example hostname with your public mail hostname. If both sources fail, inspect public DNS, host reachability, published ports, firewall policy, and service health instead. The SMTP timeout guide covers that wider path.
If a second network connects while the first times out, a source-specific firewall or ban becomes likely. It is still not proof: the first network may have broken IPv6, captive filtering, or a local firewall. Keep the comparison and check the server-side ban state next.
2. Confirm Fail2Ban is enabled and running
Docker Mailserver’s documented container integration requires both ENABLE_FAIL2BAN=1 and the NET_ADMIN capability. Check the effective environment and service status without printing the entire environment:
docker compose exec mailserver \
sh -c 'test "$ENABLE_FAIL2BAN" = 1 && echo enabled || echo disabled'
docker compose exec mailserver supervisorctl status fail2ban
If it is disabled, Fail2Ban did not create this block. Check the host firewall, a separate security container, a provider firewall, and any upstream proxy. If it is enabled but not running, inspect current startup logs before restarting anything:
docker compose logs --since 20m mailserver
Keep logs private. They can contain real addresses, account names, message identifiers, internal hostnames, and authentication activity.
3. List bans through Docker Mailserver
DMS exposes a supported setup helper for viewing bans:
docker compose exec mailserver setup fail2ban
docker compose exec mailserver setup fail2ban status
The first command shows banned addresses; the status view provides more detail. Match the affected network’s current public source address exactly. Do not assume it is the address shown by a laptop’s Wi-Fi settings: home routers and mobile networks normally present a translated public address, and IPv4 and IPv6 can take different paths.
Treat the address as private operational data. Record it in the incident note, not a public issue or screenshot. If it is absent from every jail, stop following the unban path and investigate the actual network boundary.
4. Identify the jail and triggering failures
Inspect the detailed status for the named jail reported by Fail2Ban:
docker compose exec mailserver \
fail2ban-client status '<jail-name-from-status>'
Then correlate a short log window with the affected account, protocol, and source. Typical causes include:
| Evidence | Likely cause | Fix before unban |
|---|---|---|
| Repeated SASL failures on 587 or 465 | Stale SMTP password or wrong mailbox identity | Correct or stop the sending client |
| Repeated Dovecot auth failures | Mail app polling with an old IMAP password | Update every configured device |
| Failures immediately after a password rotation | One forgotten phone, desktop, scanner, or application | Find all consumers of the old credential |
| Many account names from one unfamiliar source | Credential attack rather than your client | Leave it banned and review account security |
| Many real users appear as one proxy address | Source-address visibility is lost | Repair the network design before tuning bans |
The official DMS defaults currently document six failed attempts over the previous week and a one-week ban. Check the documentation for your pinned image and any persistent fail2ban-jail.cf override rather than assuming those values never change.
5. Stop the retry loop first
Disable automatic mail checking on the affected devices or stop the application that uses the mailbox. A single public address may represent many clients behind NAT, so fixing the laptop you are holding may not be enough. Check phones, desktop mail apps, monitoring systems, contact forms, scanners, and scheduled jobs that use the same account.
If the credential was intentionally rotated, update it through each client’s protected credential store. Do not put a mailbox password in a Compose command, shell history, process argument, chat, screenshot, or log. If failures are unfamiliar or continue while your devices are stopped, treat the event as hostile: leave the ban in place, preserve evidence, and rotate any credential that may be exposed.
6. Unban only the confirmed address
Once the bad retries have stopped and the address is proven to belong to the affected client network, use Docker Mailserver’s documented helper:
docker compose exec mailserver \
setup fail2ban unban '<exact-client-ip>'
Replace the placeholder locally; never paste a real client address into a public guide. Repeat the ban listing and confirm only the intended entry disappeared:
docker compose exec mailserver setup fail2ban status
Do not flush every jail, disable ENABLE_FAIL2BAN, remove NET_ADMIN from a running protection design, or restart the whole mail stack merely to clear one known ban. Broad changes can release hostile sources and obscure whether your targeted recovery worked.
7. Verify access without creating another ban
- Connect once from the formerly blocked network to the intended port.
- Confirm the TLS certificate matches the mail hostname.
- Attempt one login with the corrected full mailbox identity and credential.
- For SMTP, send one harmless message to a mailbox you control and follow its queue ID to
status=sent. - For IMAP, confirm the mailbox opens and a known folder can be listed.
- Review the matching server log and make sure authentication failures are not continuing in the background.
- Recheck Fail2Ban status and confirm the jail is active and the source remains unbanned.
If SMTP still rejects the credential but the connection no longer times out, the ban is fixed and authentication is now the separate fault. Follow the SASL authentication guide. For mailbox access failures, use the IMAP and Dovecot guide.
8. Make tuning persistent only when evidence supports it
DMS loads persistent Fail2Ban overrides from the mail configuration volume. Its documentation maps docker-data/dms/config/fail2ban-jail.cf to /etc/fail2ban/jail.d/user-jail.local. Use that source if measured normal behaviour proves a jail needs adjustment.
Before changing maxretry, findtime, bantime, or ignoreip, answer three questions:
- Were the failures generated by legitimate users, or by a broken client that should be fixed?
- Does the server see each real client address, or only a shared proxy address?
- Can a narrow, stable trusted source be justified without creating a broad bypass?
Never allowlist a whole consumer ISP range, mobile carrier range, or arbitrary public subnet to hide a credential problem. Dynamic addresses also make a one-address allowlist brittle. If a proxy masks origins, repair trusted source-address handling or place rate controls at the boundary that can see the real client; do not exempt the proxy casually.
After a persistent configuration change, validate it and apply it through the maintained service path. The DMS FAQ documents restarting the Fail2Ban sub-service after its configuration changes:
docker compose exec mailserver fail2ban-client -t
docker compose exec mailserver supervisorctl restart fail2ban
docker compose exec mailserver setup fail2ban status
For a clean DMS configuration recreation, preserve mail and state volumes and use the project’s pinned image. Never use docker compose down -v as a troubleshooting shortcut.
Common mistakes
- Unbanning before stopping clients: cached bad credentials can trigger another ban within seconds.
- Assuming a timeout proves Fail2Ban: DNS, IPv6, firewall, provider, Docker publishing, and service failures can look similar.
- Resetting every mailbox: first identify the account and device represented by the matching failures.
- Clearing all bans: unrelated hostile sources may be blocked for valid reasons.
- Disabling protection permanently: it converts a small client problem into a larger security exposure.
- Publishing ban output: addresses and login activity are operational data.
- Editing only inside the container: ad hoc changes disappear on recreation and leave the durable source wrong.
- Ignoring shared-address effects: one broken device can block every user behind the same NAT address.
Compact diagnosis order
- Compare the same protocol from two independent source networks.
- Confirm Fail2Ban is enabled and its supervised process is running.
- List current bans through
setup fail2ban. - Match the exact private source address and jail.
- Correlate the ban with a short server log window.
- Stop every client that is repeating the failed credential.
- Unban one confirmed address through the DMS helper.
- Run one corrected login and one protocol-level success test.
- Confirm the jail remains active and no failures continue.
- Tune persistent policy only from evidence, with a negative security check.
Authoritative references: Docker Mailserver’s Fail2Ban guide documents required capabilities, defaults, persistent override files, status, and ban management; its FAQ documents the supported unban helper and sub-service restart pattern; and its debugging guide explains log-led diagnosis and clean container recreation. Match commands and configuration paths to the image version you actually run.