Skip to content

Protecting Mail Servers ​

Mail services are among the most brute-forced on the internet. EzyShield parses Postfix smtpd and Dovecot login logs and ships default rules that ban credential brute force, open-relay probing, and connection abuse — with the same strike ladder, allowlist supremacy, and dry-run default as everything else.

What gets detected ​

EventEmitted byMeaning
smtp_auth_failpostfix parserSASL LOGIN/PLAIN/… authentication failed
smtp_relay_deniedpostfix parserNOQUEUE: reject … Relay access denied (ordinary user-unknown rejects stay silent)
smtp_abusepostfix parser"too many errors after RCPT", "lost connection after AUTH"
imap_auth_faildovecot parserIMAP/POP3 (auth failed, N attempts …)
imap_probedovecot parserDisconnected (no auth attempts …) — credential-less probing, low signal

Built-in rules (tune via rules.d drop-ins, merged by name):

RuleWindowThresholdWhat it catches
mail_bruteforce5 min5SMTP + IMAP/POP3 credential guessing (kinds combined)
mail_relay_probe5 min3open-relay probing
mail_bruteforce_sustained1 h10low & slow failures + connection abuse
mail_probe_aggressive——disabled by default — counts imap_probe; uncomment in rules.yaml/rules.d if probe noise bothers you (higher FP risk)

Bare-metal Postfix / Dovecot ​

The journald units are the recommended sources (they work regardless of which file syslog writes to):

yaml
# /etc/ezyshield/config.yaml
collectors:
  - kind: journald
    unit: postfix        # postfix@- on some Debian setups: use the unit systemctl shows
  - kind: journald
    unit: dovecot

File-based alternative: mail.log/maillog routes to the postfix parser automatically. Dovecot lines living in that same shared file need their own source — either the journald unit above, or a dedicated log_path = /var/log/dovecot.log in Dovecot plus:

yaml
  - kind: file
    path: /var/log/dovecot.log     # routes to the dovecot parser by name

Mailcow / containerized stacks ​

Postfix and Dovecot in mailcow log through docker. Point docker collectors at the containers and force the parser:

yaml
collectors:
  - kind: docker
    container: mailcowdockerized-postfix-mailcow-1
    parser: postfix
  - kind: docker
    container: mailcowdockerized-dovecot-mailcow-1
    parser: dovecot

(The parsers unwrap docker's json-file format automatically.)

Rollout ​

Same as everything in EzyShield: start in dry-run, watch ezyshield watch --kind dry_ban while a day of real traffic flows, allowlist your own networks (policy.yaml or ezyshield allow), then ezyshield arm. A banned mail client is recoverable — the first strike is 5 minutes.