[mailserver] Add Dovecot auth_failure_delay 5s [ci skip]

## Context

Dovecot's `dovecot.cf` block previously set only
`mail_max_userip_connections = 50`. No equivalent of the SMTP rate
limit existed for IMAP auth — brute-force against IMAP/POP auth was
throttled only by CrowdSec at the LB level. Adding an in-process
auth delay is cheap defense in depth. Addresses code-9mi.

## This change

Adds `auth_failure_delay = 5s` to the dovecot.cf ConfigMap key.
Each failed auth attempt pauses 5s before responding; a sequential
1000-entry dictionary attack stretches from <1s to ~85min, bought
out CrowdSec's ban window.

## What is NOT in this change

- `login_processes_count` tuning (workload doesn't warrant it yet)
- Equivalent SMTP AUTH delay (CrowdSec already covers, and SMTP AUTH
  is rate-limited via `smtpd_client_connection_rate_limit`)

## Test Plan

### Automated
```
$ kubectl exec -n mailserver -c docker-mailserver deployment/mailserver -- \
    doveconf -n | grep -E 'auth_failure|mail_max_userip'
auth_failure_delay = 5 secs
mail_max_userip_connections = 50

$ kubectl rollout status deployment/mailserver -n mailserver
deployment "mailserver" successfully rolled out
```

### Manual Verification
1. `openssl s_client -connect mail.viktorbarzin.me:993`
2. `a1 LOGIN bogus@viktorbarzin.me wrongpass` — expect ~5s delay before `NO [AUTHENTICATIONFAILED]`
3. Fire 5 failed attempts rapidly: total ≥25s

## Reproduce locally
1. `kubectl exec -n mailserver -c docker-mailserver deployment/mailserver -- doveconf -n | grep auth_failure`
2. Expected: `auth_failure_delay = 5 secs`

Closes: code-9mi

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Viktor Barzin 2026-04-19 10:33:05 +00:00
parent a32bfbf07e
commit 23173131f4

View file

@ -134,6 +134,11 @@ resource "kubernetes_config_map" "mailserver_config" {
# Increase max IMAP connections per user+IP - all Roundcube connections come from same pod IP
"dovecot.cf" = <<-EOF
mail_max_userip_connections = 50
# Throttle IMAP auth brute-force. CrowdSec handles the network-level
# ban, this adds defense in depth at the auth layer each failed
# attempt waits 5s before responding, stretching a 1000-password
# dictionary attack from <1s to ~85min. Addresses code-9mi.
auth_failure_delay = 5s
EOF
fail2ban_conf = <<-EOF
[DEFAULT]