• We value your experience with Plesk during 2024
    Plesk strives to perform even better in 2025. To help us improve further, please answer a few questions about your experience with Plesk Obsidian 2024.
    Please take this short survey:

    https://pt-research.typeform.com/to/AmZvSXkx
  • The Horde webmail has been deprecated. Its complete removal is scheduled for April 2025. For details and recommended actions, see the Feature and Deprecation Plan.

Issue Fail2Ban - Postfix not working for SASL (bug?)

wakabayashi

New Pleskian
Server operating system version
Debian 12.8
Plesk version and microupdate number
18.0.65
I am a bit confused. It seems to be that Fail2Ban is just not working correctly for postfix SASL errors.

Here is an example of my /var/log/maillog:
Code:
Dec 16 11:24:49 plesk.spielezar.ch postfix/smtpd[276348]: connect from unknown[185.196.10.158]
Dec 16 11:24:49 plesk.domain.com postfix/smtpd[276348]: warning: unknown[185.196.10.158]: SASL LOGIN authentication failed: authentication failure, sasl_username=center
Dec 16 11:24:49 plesk.domain.com postfix/smtpd[276348]: disconnect from unknown[185.196.10.158] ehlo=1 auth=0/1 quit=1 commands=2/3
Dec 16 12:55:43 plesk.domain.com postfix/smtpd[281259]: connect from unknown[185.196.10.158]
Dec 16 12:55:43 plesk.domain.com postfix/smtpd[281259]: warning: unknown[185.196.10.158]: SASL LOGIN authentication failed: authentication failure, sasl_username=mail
Dec 16 12:55:43 plesk.domain.com postfix/smtpd[281259]: disconnect from unknown[185.196.10.158] ehlo=1 auth=0/1 quit=1 commands=2/3
Dec 16 14:26:39 plesk.domain.com postfix/smtpd[285633]: connect from unknown[185.196.10.158]
Dec 16 14:26:39 plesk.domain.com postfix/smtpd[285633]: warning: unknown[185.196.10.158]: SASL LOGIN authentication failed: authentication failure, sasl_username=video
Dec 16 14:26:39 plesk.domain.com postfix/smtpd[285633]: disconnect from unknown[185.196.10.158] ehlo=1 auth=0/1 quit=1 commands=2/3
Dec 16 15:57:59 plesk.domain.com postfix/smtpd[299357]: connect from unknown[185.196.10.158]
Dec 16 15:57:59 plesk.domain.com postfix/smtpd[299357]: warning: unknown[185.196.10.158]: SASL LOGIN authentication failed: authentication failure, sasl_username=debbie
Dec 16 15:57:59 plesk.domain.com postfix/smtpd[299357]: disconnect from unknown[185.196.10.158] ehlo=1 auth=0/1 quit=1 commands=2/3

My jail is configured like:
Code:
[plesk-postfix]
enabled = true
filter = postfix[mode=auth]
action = iptables-multiport[name="plesk-postfix", port="smtp,smtps,submission,465"]
logpath = /var/log/maillog
maxretry = 3

My postfix.conf looks like
Code:
# Fail2Ban filter for selected Postfix SMTP rejections
#
#

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf

[Definition]

_daemon = postfix(-\w+)?/[^/\[:\s]+(?:/smtp[ds])?
_port = (?::\d+)?
_pref = [A-Z]{4}

prefregex = ^%(__prefix_line)s<mdpr-<mode>> <F-CONTENT>.+</F-CONTENT>$

# Extended RE for normal mode to match reject by unknown users or undeliverable address, can be set to empty to avoid this:
exre-user = |[Uu](?:ser unknown|ndeliverable address)  ; pragma: codespell-ignore

mdpr-normal = (?:\w+: (?:milter-)?reject:|(?:improper command pipelining|too many errors) after \S+)
mdre-normal=^%(_pref)s from [^[]*\[<HOST>\]%(_port)s: [45][50][04] [45]\.\d\.\d+ (?:(?:<[^>]*>)?: )?(?:(?:Helo command|(?:Sender|Recipient) address) rejected: )?(?:Service unavailable|Access denied|(?:Client host|Command|Data command) rejected|Relay access denied|Malformed DNS server reply|(?:Host|Domain) not found|need fully-qualified hostname|match%(exre-user)s)\b
            ^from [^[]*\[<HOST>\]%(_port)s:?

mdpr-auth = warning:
mdre-auth = ^[^[]*\[<HOST>\]%(_port)s: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed:(?! Connection lost to authentication server| Invalid authentication mechanism)
mdre-auth2= ^[^[]*\[<HOST>\]%(_port)s: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed:(?! Connection lost to authentication server)
# todo: check/remove "Invalid authentication mechanism" from ignore list, if gh-1243 will get finished (see gh-1297).

# Mode "rbl" currently included in mode "normal", but if needed for jail "postfix-rbl" only:
mdpr-rbl = %(mdpr-normal)s
mdre-rbl  = ^%(_pref)s from [^[]*\[<HOST>\]%(_port)s: [45]54 [45]\.7\.1 Service unavailable; Client host \[\S+\] blocked\b

# Mode "rbl" currently included in mode "normal" (within 1st rule)
mdpr-more = %(mdpr-normal)s
mdre-more = %(mdre-normal)s

# Includes some of the log messages described in
# <http://www.postfix.org/POSTSCREEN_README.html>.
mdpr-ddos = (?:lost connection after (?!(?:DATA|AUTH)\b)[A-Z]+|disconnect(?= from \S+(?: \S+=\d+)* auth=0/(?:[1-9]|\d\d+))|(?:PREGREET \d+|HANGUP) after \S+|COMMAND (?:TIME|COUNT|LENGTH) LIMIT)
mdre-ddos = ^from [^[]*\[<HOST>\]%(_port)s:?

mdpr-extra = (?:%(mdpr-auth)s|%(mdpr-normal)s)
mdre-extra = %(mdre-auth)s
            %(mdre-normal)s

mdpr-aggressive = (?:%(mdpr-auth)s|%(mdpr-normal)s|%(mdpr-ddos)s)
mdre-aggressive = %(mdre-auth2)s
                  %(mdre-normal)s

mdpr-errors = too many errors after \S+
mdre-errors = ^from [^[]*\[<HOST>\]%(_port)s$


failregex = <mdre-<mode>>

# Parameter "mode": more (default combines normal and rbl), auth, normal, rbl, ddos, extra or aggressive (combines all)
# Usage example (for jail.local):
#   [postfix]
#   mode = aggressive
#
#   # or another jail (rewrite filter parameters of jail):
#   [postfix-rbl]
#   filter = postfix[mode=rbl]
#
#   # jail to match "too many errors", related postconf `smtpd_hard_error_limit`:
#   # (normally included in other modes (normal, more, extra, aggressive), but this jail'd allow to ban on the first message)
#   [postfix-many-errors]
#   filter = postfix[mode=errors]
#   maxretry = 1
#
mode = more

ignoreregex =

[Init]

journalmatch = _SYSTEMD_UNIT=postfix.service [email protected]

# Author: Cyril Jaquier

IMO the 185.196.10.158 should be blocked, but it's not!? Note: I have added "465" the port setting as I found this in some forums, but it didnd't help either.

I also tried to restart fail2ban multiple times.

Whats wrong here?
 
Investigating this further, it's likely due to a low value in "Time interval for detection of subsequent attacks". I don't know, why the default value is 600 seconds here. Imo this is too low.

I will keep you updated!
 
Yeah this outputs a lot. So I can confirm now, that it's working correctly. It's just that I needed to raise "Time interval for detection of subsequent attacks".

Just to make clear... If you use this values here (source: Protection Against Brute Force Attacks (Fail2Ban).):
1734430351948.png

It means that an attacker will try it 3 times every 10 minutes. If I didn't miscalculate it means, that with 200 IPs, you will be attacked every second.

In addition 3 fails seems pretty restrictive. You know: it fails once, you try again with same settings -> fail two. Pressure on your 3rd try already high :D So I went up for 5 and thought: well I just chose an IP address ban period of a whole week. It sounds like this would take a lot of pressure from your server but the opposite is the case.

A clever attacker will now attack you every 10 minutes 4 times. He will never be blocked due to "Time interval for detection of subsequent attacks".

It's probably not possible to find a "all fits one solution" here. The needs are different. BUT you really need to be careful, that this 3 numbers do make sense TOGETHER. My settings is now:

IP address ban period: 604800 (1 week)
Time interval for detection of subsequent attacks: 86400 (1 day)
Number of failures before the IP address is banned: 5

In my case this takes a lot of pressure from my server without any drawback. You need now 21'600 IPs to attack every second :cool:
 
Hello!

You might want to also consider recidive jail. It is analyse fail2ban log, and if some ip is banned several times (5 by default), it will be banned for a long time (1 week)
 
Back
Top