Security & Spam Protection
Configure auto-ban rules, manage blocked IPs, review TLS settings, and resolve the Docker gateway IP auto-ban issue on the DramWell Stalwart mail server.
Overview
Stalwart includes built-in abuse protection — rate limiting on SMTP and authentication endpoints, automatic IP banning on threshold violations, and TLS enforcement for all connections. These protections are effective against common attack patterns but require careful tuning in Docker-based deployments where internal traffic can inadvertently trigger the same rules as external abuse.
Auto-Ban Thresholds
Stalwart monitors three event types and bans the source IP when the count exceeds a threshold within a one-hour rolling window:
| Event Type | Default Threshold | Trigger |
|---|---|---|
| scan | 100 / hour | Port scanning or probing behavior |
| auth | 100 / hour | Authentication failures (bad password attempts) |
| abuse | 100 / hour | Policy violations (sending to blocked addresses, DNSBL hits) |
These thresholds are configured in the Stalwart admin panel under Configuration > Security > Auto-Ban.
Adjusting Thresholds
If the default thresholds are too sensitive for your traffic patterns (e.g., a bulk sending integration triggers the abuse threshold), increase the specific threshold rather than disabling the rule. Access the settings at:
Admin Panel → Configuration → Security → Abuse Protection
Or via the API:
PATCH /api/settings/auth.banned-threshold
Content-Type: application/json
Authorization: Basic <credentials>
{"value": "200"}
TLS Configuration
Stalwart uses two separate TLS mechanisms:
| Protocol | TLS Method | Certificate Source |
|---|---|---|
| SMTP (587) | STARTTLS, direct binding | Stalwart ACME (auto-renew) |
| IMAPS (993) | TLS, direct binding | Stalwart ACME (auto-renew) |
| HTTPS (443) | TLS, nginx proxy | LetsEncrypt via certbot (auto-renew) |
Stalwart ACME
Stalwart manages its own certificate for SMTP and IMAPS using ACME (Let's Encrypt). The renewal is automatic — no manual intervention is required. To check the current certificate expiry:
Admin Panel → Configuration → TLS → Certificates
If ACME renewal fails (usually due to a firewall blocking port 80 for the HTTP-01 challenge), you can manually trigger a renewal from the same panel.
nginx TLS
nginx handles HTTPS termination for the admin panel and JMAP API. The LetsEncrypt certificate is renewed by certbot running as a cron job on the host. Verify the renewal timer is active:
systemctl status certbot.timer
Certificate expiry can be checked with:
certbot certificates
Managing Blocked IPs
Blocked IPs are stored in Stalwart's settings under the server.blocked-ip.* key namespace. Each blocked entry is a separate key with the IP address as the suffix.
Viewing All Blocked IPs
GET /api/settings?prefix=server.blocked-ip
Authorization: Basic <credentials>
Adding a Block
PATCH /api/settings/server.blocked-ip.203.0.113.42
Content-Type: application/json
Authorization: Basic <credentials>
{"value": true}
Removing a Block
DELETE /api/settings/server.blocked-ip.203.0.113.42
Authorization: Basic <credentials>
Changes take effect immediately without a server restart.
Docker Gateway IP Auto-Ban Issue
Known issue: In the Docker deployment, the host network's Docker gateway IP (typically 172.17.0.1) can get auto-banned by Stalwart's abuse protection. This happens because all traffic from the Docker host — including legitimate internal services calling the mail API — appears to originate from the gateway IP. When that IP accumulates enough events, Stalwart bans it and internal mail delivery stops.
Symptoms
- Internal services stop receiving mail or API calls to Stalwart return connection refused
- Stalwart logs show
Connection rejected: IP is blockedfor172.17.0.1or similar - External mail (inbound from the internet) continues to work normally
Resolution
Identify the Docker gateway IP on the host:
docker network inspect bridge --format '{{range .IPAM.Config}}{{.Gateway}}{{end}}'Typically
172.17.0.1.Remove the auto-ban via the API:
DELETE /api/settings/server.blocked-ip.172.17.0.1Add the gateway IP to Stalwart's allowlist to prevent future bans:
PATCH /api/settings/server.allowed-ip.172.17.0.1 {"value": true}Verify access is restored by testing an internal API call to Stalwart.
The allowlist entry persists across container restarts. Re-apply it if the Stalwart container is redeployed from scratch with a fresh configuration.
Tips
- After any change to blocked or allowed IP lists, confirm the change took effect by re-fetching the settings key — Stalwart does not return confirmation in the response body for some PATCH operations.
- Review the auto-ban log monthly under Admin Panel → Logs → Security. A pattern of repeated bans from the same IP ranges suggests a targeted attack that warrants firewall-level blocking upstream of Stalwart.
- Set up an alert (via uptime monitor or log scraping) for the string
Connection rejected: IP is blockedtargeting the Docker gateway IP. Catching the Docker gateway ban early prevents internal mail outages that can be hard to diagnose under pressure.
Related Articles
Was this article helpful?