allow_nets check failure still performs LDAP bind authentication
Postfix authentication via Dovecot. Dovecot performs the allow_nets check, which fails. It then still attempts to authenticate the user via LDAP bind, thus allowing DoS attacks where the entry in the directory will be locked after a few failed attempts.
dovecot --version: 2.3.19.1 (9b53102964)
Debian GNU/Linux 12 (bookworm), x86, no NFS
Sep 04 07:26:05 postfix/smtpd[48225]: connect from unknown[182.176.211.10] Sep 04 07:26:17 dovecot[33863]: auth: *ldap(XXX,182.176.211.10): allow_nets check failed: IP 182.176.211.10 not in allowed networks* Sep 04 07:26:17 dovecot[33863]: auth: *ldap(XXX,182.176.211.10): Password mismatch (for LDAP bind)* Sep 04 07:26:27 postfix/smtpd[48225]: warning: unknown[182.176.211.10]: SASL LOGIN authentication failed: Connection lost to authentication server, sasl_username=(unavailable) Sep 04 07:26:27 postfix/smtpd[48225]: lost connection after AUTH from unknown[182.176.211.10] Sep 04 07:26:27 postfix/smtpd[48225]: disconnect from unknown[182.176.211.10] ehlo=2 starttls=1 auth=0/1 commands=3/4
The allow_nets extra field comes from LDAP. This works as a pass_filter query is performed first, which returns the allow_nets.
/DN is looked up by sending a pass_filter LDAP request and getting
the DN from the reply. This is very similar to doing a password
lookup. The only difference is that userPassword attribute isn’t
returned. Just as with password lookups, the pass_attrs may contain
special extra fields./
https://doc.dovecot.org/2.3/configuration_manual/authentication/ldap_bind/#dn-lookup
After this, Dovecot should immediately fail the authentication.
/If the user tries to log in from elsewhere, the authentication will
fail the same way as if a wrong password was given./
https://doc.dovecot.org/2.3/configuration_manual/authentication/allow_nets/
There is no need to perform the bind authentication. According to the log (and the locked user accounts), it is still performed.
Configuration is irrelevant, for completeness’s sake:
auth_bind = yes
pass_filter =
(&(|(objectClass=simpleSecurityObject)(objectClass=posixAccount))(cn=%n))
pass_attrs =
cn=user,
allowNets=allow_nets
participants (1)
-
Florian Wunderlich