• Hi, Pleskians! We are running a UX testing of our upcoming product intended for server management and monitoring.
    We would like to invite you to have a call with us and have some fun checking our prototype. The agenda is pretty simple - we bring new design and some scenarios that you need to walk through and succeed. We will be watching and taking insights for further development of the design.
    If you would like to participate, please use this link to book a meeting. We will sent the link to the clickable prototype at the meeting.
  • (Plesk for Windows):
    MySQL Connector/ODBC 3.51, 5.1, and 5.3 are no longer shipped with Plesk because they have reached end of life. MariaDB Connector/ODBC 64-bit 3.2.4 is now used instead.
  • 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.

Resolved 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!
 
Could you please try:

fail2ban-regex --print-all-matched /var/log/maillog /etc/fail2ban/filter.d/postfix.conf

and double-check if it returns matches with the SASL authentication failures.
 
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