Debian – How to detect SMTP AUTH attempts in Fail2Ban

debianfail2banpostfixsmtp

I have a Fail2Ban jail that monitors failed SASL authentications to my Postfix SMTP server. When this occurs, /var/log/mail.log contains these three lines:

postfix/smtpd[32591]: connect from unknown[x.x.x.x]
postfix/smtpd[32591]: warning: unknown[x.x.x.x]: SASL LOGIN authentication failed: authentication failure
postfix/smtpd[32591]: disconnect from unknown[x.x.x.x]

And Fail2Ban filters the warning line: if it is found, the IP is considered for banning.

Recently, I changed Postfix so that AUTH is available over TLS only (using option smtpd_tls_auth_only). A consequence is that the warning line is not generated anymore when someone tries to authenticate without TLS:

postfix/smtpd[22469]: connect from unknown[x.x.x.x]
postfix/smtpd[22469]: disconnect from unknown[x.x.x.x]

Which means Fail2Ban is not able to monitor all SASL authentication attempts anymore. How can I do that?

A solution I came up with is to make SMTP more verbose (appending -v to smtpd in /etc/postfix/master.cf) and parse appropriate lines, but my problem with this is that the -v option makes the logs too verbose:

postfix/smtpd[23185]: connect from unknown[x.x.x.x]
postfix/smtpd[23185]: match_list_match: x.x.x.x: no match
postfix/smtpd[23185]: match_list_match: x.x.x.x: no match
postfix/smtpd[23185]: match_hostaddr: x.x.x.x ~? 127.0.0.0/8
postfix/smtpd[23185]: match_hostaddr: x.x.x.x ~? [::ffff:127.0.0.0]/104
postfix/smtpd[23185]: match_hostaddr: x.x.x.x ~? [::1]/128
postfix/smtpd[23185]: match_list_match: x.x.x.x: no match
postfix/smtpd[23185]: send attr ident = smtp:x.x.x.x
postfix/smtpd[23185]: > unknown[x.x.x.x]: 220 example.org ESMTP Postfix (Debian/GNU)
postfix/smtpd[23185]: < unknown[x.x.x.x]: EHLO User
postfix/smtpd[23185]: match_list_match: x.x.x.x: no match
postfix/smtpd[23185]: > unknown[x.x.x.x]: 250-example.org
postfix/smtpd[23185]: > unknown[x.x.x.x]: 250-PIPELINING
postfix/smtpd[23185]: > unknown[x.x.x.x]: 250-SIZE 10240000
postfix/smtpd[23185]: > unknown[x.x.x.x]: 250-VRFY
postfix/smtpd[23185]: > unknown[x.x.x.x]: 250-ETRN
postfix/smtpd[23185]: > unknown[x.x.x.x]: 250-STARTTLS
postfix/smtpd[23185]: > unknown[x.x.x.x]: 250-ENHANCEDSTATUSCODES
postfix/smtpd[23185]: > unknown[x.x.x.x]: 250-8BITMIME
postfix/smtpd[23185]: > unknown[x.x.x.x]: 250 DSN
postfix/smtpd[23185]: < unknown[x.x.x.x]: RSET
postfix/smtpd[23185]: > unknown[x.x.x.x]: 250 2.0.0 Ok
postfix/smtpd[23185]: < unknown[x.x.x.x]: AUTH LOGIN
postfix/smtpd[23185]: > unknown[x.x.x.x]: 503 5.5.1 Error: authentication not enabled
postfix/smtpd[23185]: < unknown[x.x.x.x]: QUIT
postfix/smtpd[23185]: > unknown[x.x.x.x]: 221 2.0.0 Bye
postfix/smtpd[23185]: match_hostaddr: x.x.x.x ~? 127.0.0.0/8
postfix/smtpd[23185]: match_hostaddr: x.x.x.x ~? [::ffff:127.0.0.0]/104
postfix/smtpd[23185]: match_hostaddr: x.x.x.x ~? [::1]/128
postfix/smtpd[23185]: match_list_match: x.x.x.x: no match
postfix/smtpd[23185]: send attr ident = smtp:x.x.x.x
postfix/smtpd[23185]: disconnect from unknown[x.x.x.x]

A priori, I only need to filter the authentication not enabled line. Is it possible to make the SMTP service to report auth requests without adding the whole verbose messages? Ideally my mail.log file would only contain:

postfix/smtpd[32591]: connect from unknown[x.x.x.x]
postfix/smtpd[32591]: warning: unknown[x.x.x.x]: authentication not enabled
postfix/smtpd[32591]: disconnect from unknown[x.x.x.x]

Is this something possible? If yes, how? Thanks,

Best Answer

Your idea of adding -v to smtpd helped me solve this problem. I'm on Debian.

First I created /etc/fail2ban/jail.local:

[postfix]
enabled = true
logpath = /var/log/mail.log
bantime = 86400
findtime = 86400
maxretry = 2

This tells fail2ban to watch /var/log/mail.log with a maximum of 2 attempts during 24 hours, which would lead to a ban of 24 hours as well.

Then I copied /etc/fail2ban/filter.d/postfix.conf to /etc/fail2ban/filter.d/postfix.local, and added this line:

failregex = ^%(__prefix_line)s> \S+\[<HOST>\]: 503 5\.5\.1 .*$

This would trigger upon:

postfix/smtpd[23185]: > unknown[x.x.x.x]: 503 5.5.1 Error: authentication not enabled

UPDATE (October 2021):

Above works nicely with fail2ban 0.9.6. However, fail2ban 0.10.2 changed the layout of postfix.conf a bit.

To fix, again, copy the new /etc/fail2ban/filter.d/postfix.conf to /etc/fail2ban/filter.d/postfix.local. In this .local file, edit the normal section as follows:

mdpr-normal = (?:NOQUEUE: reject:|improper command pipelining after \S+|>)
mdre-normal=^RCPT from [^[]*\[<HOST>\]%(_port)s: 55[04] 5\.7\.1\s
            ^RCPT from [^[]*\[<HOST>\]%(_port)s: 45[04] 4\.7\.1 (?:Service unavailable\b|Client host rejected: cannot find your (reverse )?hostname\b)
            ^RCPT from [^[]*\[<HOST>\]%(_port)s: 450 4\.7\.1 (<[^>]*>)?: Helo command rejected: Host not found\b
            ^EHLO from [^[]*\[<HOST>\]%(_port)s: 504 5\.5\.2 (<[^>]*>)?: Helo command rejected: need fully-qualified hostname\b
            ^VRFY from [^[]*\[<HOST>\]%(_port)s: 550 5\.1\.1\s
            ^RCPT from [^[]*\[<HOST>\]%(_port)s: 450 4\.1\.8 (<[^>]*>)?: Sender address rejected: Domain not found\b
            ^from [^[]*\[<HOST>\]%(_port)s:?
            ^[^[]*\[<HOST>\]: 503 5\.5\.1 Error: authentication not enabled\b

Note the addition of |> to mdpr-normal.

In /etc/fail2ban/jail.local, add mode = normal to the [postfix] section.

And do not forget to add -v to the smtp directive in /etc/postfix/master.cf:

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (no)    (never) (100)
# ==========================================================================
smtp      inet  n       -       y       -       -       smtpd -v

Restart your services and you should be good to go.