- Server operating system version
- AlmaLinux 9.8 (Olive Jaguar)
- Plesk version and microupdate number
- Plesk Obsidian 18.0.79 Update #3
Before we start...
I am posting this more as advice to others. It could be considered in tandem with my post 'Plesk firewall and preventing clashes with firewalld' and generally hardening a Plesk server.This firewallld post is important IMHO as I found admin services with access locked-down via the Plesk firewall being endlessly probed. This was becasue the Plesk firewall config was being bypassed due to the server having been built by the hosting company with firewalld active and adding it's own configuration. There’s a lesson here: Just because you have configured access in the Plesk firewall does not mean this is the access being enforced if there is some other configuration, like from a default firewallld installation by your hosting company, also operating. My advice: Go check whether what you think is operating, is actually operating. I found a horror story of attempts against SSH which should have been impossible according to the Plesk firewall config … all due to 'interference' from this default firewallld configuration that I was blissfully unaware of.
Postfix and SMTP brute force attacks
Moving on now to Postfix and SMTP brute force attacks, I was finding my maillog filled with huge numbers of log lines similar to:
Code:
[date timestamp] mail postfix/smtpd[task_id]: warning: unknown[ip_address]: SASL LOGIN authentication failed: authentication failure, sasl_username=[some_username]
If you’d quite like to stop this endless probing of your mail accounts, then this post is for you.
Finding the scale of probing against your server
If you don’t know whether your maillog is filled with these login probes but are now curious, then login (SSH or console) and:
Code:
cd /var/log
grep "authentication failed" maillog | more
You will likely get screenfuls of lines of random IPs from all over the world, all attempting logins using a mix of real and non-existent usernames and Email addresses. Want to see even more? Then try:
Code:
grep "authentication failed" maillog* | more
and you’ll get the output from both the maillog and maillog.processed files. And you can get even more by looking back through the compressed maillog archives with:
Code:
gunzip -c maillog*.gz | grep "authentication failed" | more
Stopping the probes
In the fair assumption you’ll find the logs filled with these endless probes, the next question is: So, can I stop this noise and what is effectively people endlessly ‘rattling the locks’? The answer is yes…Background
Originally all mail sent was via port 25 (SMTP), but these days clients are (hopefully) configured to use either port 465 or 587 so that mail transmission is encrypted. I find MS Outlook will accept you configuring 587 without error or warning but silently changes the connection without telling you to 465! Anyway, 465 is reserved for secure email transmission using implicit SSL/TLS encryption known as SMTPS, while port 587 begins unencrypted and upgrades to TLS via STARTTLS. In contrast, port 465 encrypts from the very first packet. Whichever you configure, you should submit mail to your mail server using one of these ports and not 25.The significance of this is that clients shouldn’t be attempting authentication to port 25 which is now generally considered as for MTA to MTA (server to server) transmission only. This in turn means attempts to authenticate against port 25 will not be legitimate as your legitimate clients should be authenticating via 465 or 587.
A game of two halves
There are two parts to what follows:- Disabling authentication against port 25
- Using fail2ban to block failed login attempts against Postfix operating your smptd on port 25
503 5.5.1 Error: authentication not enabled error to the bot, as in:
Code:
>> telnet [your_server] 25
<< 220 [your_server] ESMTP Postfix
>> EHLO [your_device_name]
<< 250-[your_server]
<< 250-PIPELINING
<< 250-SIZE 30720000
<< 250-ETRN
<< 250-STARTTLS
<< 250-ENHANCEDSTATUSCODES
<< 250-8BITMIME
<< 250-DSN
<< 250 CHUNKING
>> AUTH LOGIN
<< 503 5.5.1 Error: authentication not enabled
Disabling authentication to port 25
You need to edit the configuration file/etc/postfix/master.cf. Change:
Code:
smtp inet n - n - - smtpd
To read:
Code:
smtp inet n - n - - smtpd
-o smtpd_sasl_auth_enable=no
The '
-o’ option should be on a separate line and must be indented by at least one space to be recognised as an option of the smtp declaration on the line above. After making this change, restart Postfix:
Code:
sudo systemctl restart postfix
You can now go and test whether authentication on port 25 is permitted or not by trying the
telnet [your_server] 25 check shown above. Presuming you get the ‘503 5.5.1 Error: authentication not enabled’ response back, you know that no amount of probing will ever give up any details about a good or bad credential when tested on port 25, the port of choice for this kind of probing (as it doesn’t require establishing a TLS session). However, this change hasn’t stopped the probes being attempted nor the log lines being recorded, just made any amount of probing ineffective.Stopping the probes
This is where we use fail2ban to actually stop the probes and associated log lines. This can be done with or without the disabling of authentication against port 25 outlined above.An 'interesting' discovery was that despite hav ing (sorry, have to include that space, but if typed properly the editor blows-up again!) the ‘plesk-postfix’ jail enabled in Plesk (Home > Tools & Settings > IP Address Banning > Jails), there were never an IPs listed despite the volume of failed auth attempts. The reason is the default Plesk fail2ban filter (that picks out failed auth attempts from maillog and so ‘drives’ fail2ban) does not detect failed login attempt log lines … it’s patterns don’t match.
Rather than mess with the default Plesk fail2ban filter which picks out other things other than just failed auth attempts, I created an additional ‘override file’:
/etc/fail2ban/filter.d/postfix.local. This should contain only (meaning clear out any default config you might find in it):
Code:
[Definition]
# 1. Define your custom rule here safely
mdre-auth3 = ^%%(__prefix_line)swarning: unknown\[<HOST>\]: SASL LOGIN authentication failed: authentication failure, sasl_username=.*$
# 2. Reference the exact underlying macro engine token to prevent the loop
failregex = <mdre-<mode>>
%(mdre-auth3)s
The use of ‘
mdre-auth3’ is that the mail filer contains definitions for both ‘mdre-auth’ and ‘mdre-auth2’, so this just extended that pattern. The mdre-auth3 pattern matches the log line format found in maillog. Having saved the override file, now check it with:
Code:
sudo fail2ban-regex systemd-journal /etc/fail2ban/filter.d/postfix.conf
You should see a clean, successful compilation, basically adding in the new auth failure pattern that this time does match that Postfix output/maillog log lines. Now restart fail2ban:
Code:
sudo systemctl restart fail2ban
There are now two tests that your handiwork is working:
Code:
iptables -L f2b-plesk-postfix -n -v
gives you a list of banned IPs. The list will grow over time, but looks something like:
Code:
Chain f2b-plesk-postfix (1 references)
pkts bytes target prot opt in out source destination
0 0 REJECT all -- * * 78.66.44.246 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 REJECT all -- * * 205.209.65.70 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 REJECT all -- * * 87.236.176.143 0.0.0.0/0 reject-with icmp-port-unreachable
…
15921 15M RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
Prior to the fail2ban changes outlines above, you’ll only see the final ‘RETURN’ line, meaning nothing is matching, everything is being passed by fail2ban.
Your other check is:
Code:
fail2ban-client status plesk-postfix
This will give you an output like:
Code:
Status for the jail: plesk-postfix
|- Filter
| |- Currently failed: 136
| |- Total failed: 684
| `- File list: /var/log/ maillog
`- Actions
|- Currently banned: 268
|- Total banned: 279
`- Banned IP list: 111.70.38.54 71.235.225.181 163.61.33.117 ...
The IP list will grow and grow. This is fail2ban doing it’s stuff.
The final part is to tighten up fail2ban, as remember, there should be no port 25 auth attempts, but that will need to be posted as a reply to this as the editor will not allow me to add more!
