Auto-banning
Stalwart includes an automatic ban mechanism that monitors incoming connections for abusive patterns and blocks the offending IP address when configured thresholds are exceeded. Once an address is banned, the server drops every subsequent connection from that source, shutting down further abuse without operator intervention.
The system tracks several independent categories of suspicious activity: failed authentication attempts, SMTP relay or recipient-probing abuse, idle (loitering) sessions, and port or URL scanning. Each category has its own rate limit, and each rate is evaluated separately; reaching the threshold for any category produces a ban. Banned IP addresses are recorded as BlockedIp entries (found in the WebUI under Settings › Security › Blocked IPs), alongside any entries created manually from the WebUI or the CLI.
Authentication ban tracking keys on both the source IP and the login name, so distributed brute-force attempts against a single account are detected even when the attacker rotates IP addresses.
Configuration
Auto-ban thresholds are grouped on the Security singleton (found in the WebUI under Settings › Security › Settings). Each category exposes a *BanRate field (count over period) and an optional *BanPeriod duration that sets how long resulting bans last; omitting *BanPeriod leaves the ban in place until it is removed manually. Leaving scanBanPaths at its default covers common exploit URLs (*.php*, *.cgi*, */wp-*, *xmlrpc*, traversal patterns, and the names of popular CMS platforms).
Every resulting BlockedIp carries a reason recording what triggered the ban (one of authFailure, rcptToFailure, loitering, portScanning, manual, or other) and an expiresAt timestamp. When a category's *BanPeriod is set, expiresAt is populated with the corresponding deadline and the entry is removed automatically once the time passes; leaving the period unset stores the ban indefinitely until an operator deletes it. Manual entries created through the WebUI or the CLI carry reason manual and can set their own expiresAt at creation time.
Authentication failures
Authentication failures across every service (JMAP, IMAP, SMTP, ManageSieve) feed into a single counter per source. The rate is set through authBanRate with a default of 100 failures per day, and the resulting ban duration is controlled by authBanPeriod.
Abuse protection
Relay attempts and brute-force RCPT TO probing against the SMTP server are tracked together. The rate is set through abuseBanRate with a default of 35 attempts per day, and the ban duration through abuseBanPeriod.
Loitering connections
Clients that repeatedly connect but never send meaningful traffic consume resources and are often part of SYN-flood-style denial-of-service attempts. The rate is set through loiterBanRate with a default of 150 disconnections per day, and the ban duration through loiterBanPeriod.
Port and URL scanning
The server tracks attempts to probe TCP ports it is not listening on, as well as HTTP requests for exploit-style paths. The scan rate is set through scanBanRate (default 30 attempts per day), the ban duration through scanBanPeriod, and the list of glob patterns that trigger an immediate ban on first HTTP request through scanBanPaths. The default patterns cover the most common web-application exploits:
{
"scanBanRate": {"count": 30, "period": "1d"},
"scanBanPaths": [
"*.php*",
"*.cgi*",
"*.asp*",
"*/wp-*",
"*/php*",
"*/cgi-bin*",
"*xmlrpc*",
"*../*",
"*/..*",
"*joomla*",
"*wordpress*",
"*drupal*"
]
}