postfix-dovecot Gratuit
Authentification mail et abus de relais — les parseurs pour Postfix et Dovecot.
Télécharger le pack tar.gz des fichiers listés ci-dessous
Règles (11)
-
mail-abuseRelay attempts and non-SMTP commands on the mail ports — spamware and scanners talking to Postfix, blocked on the first refusal -
mail-authMail password guessing — five different passwords in ten minutes on SMTP/IMAP/POP; the way mailboxes get hijacked -
mail-auth-abortSMTP sessions that ask for AUTH and hang up — reconnaissance for credential attacks on mailboxes, seen from whole botnets at once -
mail-auth-failMail logins refused five times in ten minutes, counted without the password hash — the alternative to mail-auth for servers where auth_verbose_passwords cannot be turned on; off by default -
mail-auth-slowMail password guessing paced slowly, to stay under the fast rule — the same credential attack spread over hours -
mail-balanceMail sessions from one address failing far more often than they succeed — a compromised client or a stuffing tool, whatever the pace -
mail-connect-probeConnections opened to the mail server and dropped without a word — a scanner or a botnet probing for mail servers to abuse -
mail-recipient-probeDeliveries to mailboxes that do not exist, domain after domain — directory harvesting, collecting valid addresses to spam -
mail-relay-probeDeliveries to recipients we do not host, one after another — an open-relay probe by a spammer -
mail-spamSMTP rejects collected faster than any mistake explains — spam or address guessing; the rejects themselves are the evidence -
mail-sprayFailed logins spread across six different mailboxes from one address — password spraying, not a forgotten password
À propos de ce pack
Mail authentication and relay abuse, read from a single syslog file
where rsyslog routes mail.* — /var/log/maillog on Plesk and Red
Hat descendants; /var/log/mail.log on a stock Debian. Category
mail. Six rules, translations of the CrowdSec hub's postfix and
dovecot scenarios (© CrowdSec, MIT) with the same figures, converted
as window ≈ capacity × leakspeed; each rule says where its number
comes from. The figures were proven on shared-hosting machines where
hundreds of customers mistype passwords all day — quieter hosts only
make them safer.
Traditional syslog timestamps (Aug 14 08:49:30), which carry no year:
the reader supplies its own, and a line dated ahead of it is taken as
last year's.
Read the mail log once. On a machine where /var/log/syslog also
carries postfix and dovecot lines, declaring both counts every failure
twice and halves every threshold without saying so.
The parsers
| parser | what it is |
|---|---|
postfix-sasl-fail |
SMTP authentication refused |
postfix-relay-denied |
trying to send mail through this server to elsewhere |
dovecot-auth-fail |
IMAP/POP3/submission login refused |
dovecot-password-mismatch |
the auth process's view, with a truncated hash of what was tried |
dovecot-login-ok |
a login that worked — for weighing negatively |
The mailbox name is attacker-controlled and dovecot prints it before
the address, so those patterns run greedily to the last rip= on the
line. Keep that in anything derived from them.
The rules
mail-auth— five DIFFERENT refused passwords in ten minutes (distinct on dovecot's password hash: a phone retrying one stale password is never banned).mail-auth-slow— the same guesser paced to duck it: six distinct hashes inside six hours.mail-spray— failed logins across six different mailboxes in ten minutes: a person has one or two, a list has hundreds.mail-balance— sessions that only ever fail: ten net failures in two hours, a successful login forgives three. SMTP and IMAP/POP alike: Postfix's SASL line is what shows an unknown mailbox being hammered over SMTP — Dovecot writes nothing for it.mail-auth-fail— OFF by default: five refused logins in ten minutes counted without the hash, for a server whereauth_verbose_passwordscannot be turned on. Turn it on INSTEAD of the two hash rules, never beside them; it cannot forgive a phone retrying one stale password.mail-abuse— relay attempts and non-SMTP commands on the SMTP port.mail-spam— collecting rejects faster than any mistake explains: six in two minutes.
The two distinct-password rules need dovecot's
auth_verbose_passwords, which is off by default everywhere — no
distribution and no panel turns it on for you. Add
auth_verbose_passwords = sha1:6 to conf.d/10-logging.conf.
Until then they honestly read 0 hits in shield stats, and
mail-balance and mail-spray watch the door — or turn on
mail-auth-fail, the same count without the hash.
Even with the hash, a login on a mailbox that does NOT exist leaves
no hash line: Dovecot has no password to compare. Postfix's own
SASL … authentication failed line is the only trace, read by
mail-balance, mail-spray and mail-auth-fail.
Policies
mail-auth— the doors real users stand at: 1h, then 2h, 4h, 8h, 16h, 25d on a return within thirty days; the mail ports only.mail-attack— relay and spam behaviour, no innocent reading: the same ladder, all ports.
Parseurs (10)
Les briques : chaque parseur nomme un journal, un préfiltre peu coûteux et la regex qui extrait l'adresse.
dovecot-auth-fail mail
# An IMAP, POP3 or submission login refused: # imap-login: Login aborted: Connection closed (auth failed, 1 attempts in 2 secs) (auth_failed): user=<admin@example.net>, method=PLAIN, rip=203.0.113.9, lip=192.0.2.1, TLS, session=<...> # # `attempts` is how many passwords were refused inside this ONE # connection: dovecot writes a line per connection, not per try, and # closes after the third refusal. A rule that wants to count tries rather # than connections names it with `weight_field: attempts` (2026-09-09). # # The mailbox name is chosen by whoever is connecting and is printed # BEFORE the address, so the pattern runs greedily up to the last # `rip=` on the line — the one dovecot wrote. A user called # "x, rip=198.51.100.1, lip=" would otherwise frame a bystander. parser: dovecot-auth-fail log: mail prefilter: "auth failed" regex: '^(?P<time>[A-Z][a-z]{2} [ 0-9]\d \d{2}:\d{2}:\d{2}) \S+ dovecot(?:\[\d+\])?: (?P<service>[a-z0-9]+)-login: .*\(auth failed, (?P<attempts>\d+) attempts[^)]*\)[^:]*: user=<(?P<user>[^>]*)>, method=\S+, rip=(?P<ip>[0-9a-fA-F.:]+), lip=' time_field: time time_format: syslog
dovecot-login-ok mail
# A login that worked: # imap-login: Logged in: user=<me@example.net>, method=CRAM-MD5, rip=203.0.113.9, lip=192.0.2.1, mpid=..., TLS, session=<...> # # Here so that a rule can weigh it NEGATIVELY against failures. On a # host with real mailboxes that is what separates a phone with a stale # password — which fails, succeeds, fails, succeeds — from a # brute-force, which only ever fails. A host with no human mailboxes # does not need it. parser: dovecot-login-ok log: mail prefilter: "Logged in:" regex: '^(?P<time>[A-Z][a-z]{2} [ 0-9]\d \d{2}:\d{2}:\d{2}) \S+ dovecot(?:\[\d+\])?: (?P<service>[a-z0-9]+)-login: Logged in: .*rip=(?P<ip>[0-9a-fA-F.:]+), lip=' time_field: time time_format: syslog
dovecot-password-mismatch mail
# The auth process's own view of the same event, which carries a # truncated hash of the password that was tried: # auth(admin@example.net,203.0.113.9,sasl:plain)<sess>: Password mismatch (SHA1 of given password: 7110ed) # # Only present where dovecot is configured with auth_verbose_passwords. # It is worth reading separately from the login line because the hash # distinguishes a device with one stale saved password, repeating it for # ever, from a brute-force rotating a new one every attempt — a rule can # count DISTINCT hashes. parser: dovecot-password-mismatch log: mail prefilter: "Password mismatch" regex: '^(?P<time>[A-Z][a-z]{2} [ 0-9]\d \d{2}:\d{2}:\d{2}) \S+ dovecot(?:\[\d+\])?: auth\((?P<user>[^,]*),(?P<ip>[0-9a-fA-F.:]+),[^)]*\)<[^>]*>: Password mismatch \(SHA1 of given password: (?P<password_hash>\w+)\)$' time_field: time time_format: syslog
postfix-auth-abort mail
# A client that sent AUTH and hung up. Not a wrong password — that is # logged as an authentication failure — but a machine asking whether # this server offers authentication at all, and leaving with the answer. # 8 809 such lines from 3 742 addresses in a day on one machine # (2026-09-08). parser: postfix-auth-abort log: mail # Postfix 3.10 writes a `NOQUEUE: ` before the words; 3.7 does not. # Both are read (2026-09-22: a host on 3.10 never counted one abort). prefilter: "lost connection after AUTH" regex: '^(?P<time>[A-Z][a-z]{2} [ 0-9]\d \d{2}:\d{2}:\d{2}) \S+ postfix/smtpd\[\d+\]: (?:NOQUEUE: )?lost connection after AUTH from \S+\[(?P<ip>[0-9a-fA-F.:]+)\]$' time_field: time time_format: syslog
postfix-auth-ok mail
# A message accepted from an address that authenticated: the sender is a # customer of this server, whatever else their client does. Nobody fakes # this line — it takes the password. parser: postfix-auth-ok log: mail prefilter: "sasl_username=" regex: '^(?P<time>[A-Z][a-z]{2} [ 0-9]\d \d{2}:\d{2}:\d{2}) \S+ postfix/smtpd\[\d+\]: [0-9A-F]+: client=\S+\[(?P<ip>[0-9a-fA-F.:]+)\], sasl_method=\S+, sasl_username=\S+$' time_field: time time_format: syslog
postfix-connect-abort mail
# A connection opened to the mail server and dropped without delivering # anything: "lost connection after STARTTLS/EHLO/HELO/CONNECT/UNKNOWN". # # AUTH is NOT here, and the name says connect and not starttls for the # same reason: asking whether the server offers authentication is a # different act, with its own parser (postfix-auth-abort) and its own # rule. Counting it here made 833 bans in two days report as "repeated # rejected delivery attempts" when nobody had tried to deliver anything # (Robin, 2026-09-09: « faudrait mieux organiser les filtres spam »). parser: postfix-connect-abort log: mail # Postfix 3.10 writes a `NOQUEUE: ` before the words; 3.7 does not. prefilter: "lost connection after" regex: '^(?P<time>[A-Z][a-z]{2} [ 0-9]\d \d{2}:\d{2}:\d{2}) \S+ postfix/smtpd\[\d+\]: (?:NOQUEUE: )?lost connection after (?:STARTTLS|EHLO|HELO|CONNECT|UNKNOWN) from \S+\[(?P<ip>[0-9a-fA-F.:]+)\]$' time_field: time time_format: syslog
postfix-non-smtp mail
# Something that is not a mail client talking to the SMTP port: # warning: non-SMTP command from unknown[203.0.113.9]: GET / HTTP/1.1 # warning: non-SMTP command from unknown[203.0.113.9]: \026\003\001... # # HTTP verbs and TLS handshake bytes on port 25 are port scanners and # exploit probes, never a misconfigured sender. Translated from # CrowdSec's postfix-non-smtp-command (instant ban). # # The hostname before the bracket is rDNS and untrusted; the address # inside the brackets is what postfix measured. parser: postfix-non-smtp log: mail prefilter: "non-SMTP command" regex: '^(?P<time>[A-Z][a-z]{2} [ 0-9]\d \d{2}:\d{2}:\d{2}) \S+ postfix/smtpd\[\d+\]: warning: non-SMTP command from \S+\[(?P<ip>[0-9a-fA-F.:]+)\]:' time_field: time time_format: syslog
postfix-reject mail
# Any recipient postfix refused at smtpd time: # NOQUEUE: reject: RCPT from unknown[203.0.113.9]: 454 4.7.1 <x@y>: Relay access denied; ... # NOQUEUE: reject: RCPT from unknown[203.0.113.9]: 550 5.1.1 <x@y>: Recipient address rejected: ... # # ONE reject is not a verdict — a legitimate correspondent's server # typoing an address writes this line too, which is why this parser # belongs in a THRESHOLD rule (CrowdSec models it as a leaky bucket in # postfix-spam), never in an instant one. Relay attempts specifically # are covered by postfix-relay-denied, which IS instant-worthy. parser: postfix-reject log: mail prefilter: "NOQUEUE: reject" regex: '^(?P<time>[A-Z][a-z]{2} [ 0-9]\d \d{2}:\d{2}:\d{2}) \S+ postfix/smtpd\[\d+\]: NOQUEUE: reject: RCPT from \S+\[(?P<ip>[0-9a-fA-F.:]+)\]: \d{3} ' time_field: time time_format: syslog
postfix-relay-denied mail
# Someone trying to send mail through this server to somewhere else: # NOQUEUE: reject: RCPT from unknown[203.0.113.9]: 454 4.7.1 <x@example.com>: Relay access denied; from=<...> to=<...> # # There is no version of this that is a mistake by a legitimate sender: # a client that should be relaying authenticates first. The address is # read from the connection, before the recipient the client supplied. parser: postfix-relay-denied log: mail prefilter: "Relay access denied" regex: '^(?P<time>[A-Z][a-z]{2} [ 0-9]\d \d{2}:\d{2}:\d{2}) \S+ postfix/\S+\[\d+\]: NOQUEUE: reject: RCPT from \S*\[(?P<ip>[0-9a-fA-F.:]+)\]: 45\d 4\.7\.1 ' time_field: time time_format: syslog
postfix-sasl-fail mail
# An SMTP authentication refused: # warning: unknown[203.0.113.9]: SASL LOGIN authentication failed: authentication failure, sasl_username=test@example.net # warning: host.example[203.0.113.9]: SASL login authentication failed: ... # warning: unknown[203.0.113.9]: SASL NTLM authentication failed: no mechanism available # # Postfix writes the mechanism in whatever case it received, so it is # matched loosely. The address comes from the connection and is printed # before anything the client chose. The mailbox named (`sasl_username`, # absent when the client never got that far) is captured as `user` for # the rules that count distinct mailboxes; it is attacker-controlled. parser: postfix-sasl-fail log: mail prefilter: "SASL" regex: '^(?P<time>[A-Z][a-z]{2} [ 0-9]\d \d{2}:\d{2}:\d{2}) \S+ postfix/\S+\[\d+\]: warning: \S*\[(?P<ip>[0-9a-fA-F.:]+)\]: SASL \S+ authentication failed(?:.*?, sasl_username=(?P<user>\S+))?' time_field: time time_format: syslog
Signalements
mail-auth-probe This address opens SMTP sessions to our mail server, asks whether authentication is offered, and hangs up. This is reconnaissance for credential attacks on mail accounts, seen from many addresses at once; blocked. Please check what runs on this address.
# Asking whether the server offers SMTP authentication, and leaving. It # is what a machine does while it looks for a server that will carry its # mail — reconnaissance, not a delivery and not a password guess, and it # must not be reported as either. report: mail-auth-probe categories: [port-scan] says: "This address opens SMTP sessions to our mail server, asks whether authentication is offered, and hangs up. This is reconnaissance for credential attacks on mail accounts, seen from many addresses at once; blocked. Please check what runs on this address." include: []
mail-intrusion This address is trying passwords on our mail server (SMTP/IMAP/POP or webmail) for mailboxes it does not own — credential brute force or credential stuffing, the way accounts get hijacked to send spam. Every attempt is refused; the address is blocked. Please check the machine for malware or a misused mail client.
# Categories reuse the mapping proven in production by this host's # CrowdSec notifier. `include` is empty: a report says what happened, # never who it happened to. The accounts tried, the mailboxes aimed at # and the site that was hit are all captured by the parsers and none of # them are a public database's business. report: mail-intrusion categories: [email-spam, brute-force] says: "This address is trying passwords on our mail server (SMTP/IMAP/POP or webmail) for mailboxes it does not own — credential brute force or credential stuffing, the way accounts get hijacked to send spam. Every attempt is refused; the address is blocked. Please check the machine for malware or a misused mail client." include: []
mail-probe This address repeatedly opens connections to our mail server and drops them without sending anything. This is a scanner or a botnet probing for mail servers to abuse; it ties up connections for nothing and is blocked. Please check what runs on this address.
# What happened, and not what it resembles: a connection was opened to # the mail server and dropped without delivering anything. Calling that # spam was wrong — nobody had tried to send a message. report: mail-probe categories: [port-scan] says: "This address repeatedly opens connections to our mail server and drops them without sending anything. This is a scanner or a botnet probing for mail servers to abuse; it ties up connections for nothing and is blocked. Please check what runs on this address." include: []
mail-relay This address is trying to send mail through our server to recipients we do not host — probing for an open relay in order to send spam through us. Every attempt is refused and the address is blocked. Please check the machine for spamware or a misconfigured mail application.
# An open-relay attempt: recipients this server does not host, one after # another. Distinct from mail-spam, which is about volume. report: mail-relay categories: [email-spam] says: "This address is trying to send mail through our server to recipients we do not host — probing for an open relay in order to send spam through us. Every attempt is refused and the address is blocked. Please check the machine for spamware or a misconfigured mail application." include: []
mail-spam This address keeps trying to deliver mail our server rejects — spam, or a walk through mailboxes that do not exist to find valid addresses (directory harvesting). Refusal after refusal from one address is abuse, not a mistake; blocked. Please check the machine for spamware or a compromised account.
report: mail-spam categories: [email-spam] says: "This address keeps trying to deliver mail our server rejects — spam, or a walk through mailboxes that do not exist to find valid addresses (directory harvesting). Refusal after refusal from one address is abuse, not a mistake; blocked. Please check the machine for spamware or a compromised account." include: []
Fichiers
- PACK.md
- rules/mail-abuse.yaml
- rules/mail-auth-abort.yaml
- rules/mail-auth-fail.yaml
- rules/mail-auth-slow.yaml
- rules/mail-auth.yaml
- rules/mail-balance.yaml
- rules/mail-connect-probe.yaml
- rules/mail-recipient-probe.yaml
- rules/mail-relay-probe.yaml
- rules/mail-spam.yaml
- rules/mail-spray.yaml
- parsers/dovecot-auth-fail.yaml
- parsers/dovecot-login-ok.yaml
- parsers/dovecot-password-mismatch.yaml
- parsers/postfix-auth-abort.yaml
- parsers/postfix-auth-ok.yaml
- parsers/postfix-connect-abort.yaml
- parsers/postfix-non-smtp.yaml
- parsers/postfix-reject.yaml
- parsers/postfix-relay-denied.yaml
- parsers/postfix-sasl-fail.yaml
- reports/mail-auth-probe.yaml
- reports/mail-intrusion.yaml
- reports/mail-probe.yaml
- reports/mail-relay.yaml
- reports/mail-spam.yaml