Content
Introductory
On our Debian 8 (Jesssie) based server, the Fail2Ban log entries that are not recognized by Fail0.8.13Ban's 2 filters on the system slip when you use it, so your system is less protected against attacks that cause these entries.
In this description, SSH we will solve the blocking of attempts with random usernames to our server by expanding the Fail2Ban filter patterns.
I have made this description for readers who run a Debian 8 (Jessie) based server and use Fail2Ban on it, which they would love to increase its efficiency by setting up another filter pattern.
Detecting the problem
We need to be able to spot the attacks first, because they usually take place hidden in the background. Therefore, it is not enough to rely on the effective operation of our installed protection tools, but we need to beetle the log files regularly and get more information about the security status of our system by running the appropriate query commands.
The attacks that are the subject of this description are first a lastb command to observe it as root:
lastb
The command lists unsuccessful user login attempts at / var / log / wtmp file, which is not a text file, so only this command can read properly.
At the output of this you get only one line, for example:
btmp begins Wed May 1 00:06:02 2019
In this case, there was no unsuccessful login attempt from the indicated time.
Or we get a shorter or longer list of login attempts. For example:
ftptest ssh:notty <kliens IP-címe> Wed May 8 16:30 - 16:30 (00:00) ftptest ssh:notty <kliens IP-címe> Wed May 8 16:30 - 16:30 (00:00) apagar ssh:notty <kliens IP-címe> Tue May 7 15:33 - 15:33 (00:00) apagar ssh:notty <kliens IP-címe> Tue May 7 15:33 - 15:33 (00:00) user01 ssh:notty <kliens IP-címe> Mon May 6 15:20 - 15:20 (00:00) user01 ssh:notty <kliens IP-címe> Mon May 6 15:20 - 15:20 (00:00) root ssh:notty <kliens IP-címe> Sun May 5 15:20 - 15:20 (00:00) root ssh:notty <kliens IP-címe> Sun May 5 14:53 - 14:53 (00:00) btmp begins Sun May 5 14:53:32 2019
Where the first column contains the usernames they are trying to access, then display the console or remote SSH login. This example is about remote attempts. This is followed by the client trying to log on IP addresses, and then the date of the event.
This is a short list that I listed days after setting up the filter, so there was only one attempt left per day, but one such attempt arrived about every minute before that.
About these /var/log/auth.log you can also get information in a file by searching for it as follows:
cat /var/log/auth.log | grep -i "invalid user"
May 6 15:20:15 <saját hosztnevünk> sshd[xxx]: Invalid user user01 from <próbálkozó IP-címe> May 6 15:20:15 <saját hosztnevünk> sshd[xxx]: input_userauth_request: invalid user user01 [preauth] May 6 15:20:17 <saját hosztnevünk> sshd[xxx]: Failed password for invalid user user01 from <próbálkozó IP-címe> port xxx ssh2 [...]
(All attempts here result in 3 rows)
Larger amounts of these may pose a risk over time, because with an existing user and a poorly set password, there is a good chance they can be hit by the law of big numbers. Of course, the chances are still very low, but if we can defend ourselves effectively, why not?
The reason for the lack of protection
This problem occurs because Debian 8 (Jessie) can be installed from the official repository Fail0.8.13Ban package for 2 version does not include the filter sample for this case. If you use the Fail2Ban client program to get the status of your SSH jail, you will not find much:
fail2ban-client status ssh
Status for the jail: ssh |- filter | |- File list: /var/log/auth.log | |- Currently failed: 0 | `- Total failed: 0 `- action |- Currently banned: 0 | `- IP list: `- Total banned: 0
So in vain the a /var/log/auth.log "invalid user" entries in our file, but they are not blocked by Fail2B.
The solution
The solution is simpler than you think: in the Debian 9 (Stretch) repository Fail2Ban 0.9.6 version already contains the appropriate filter pattern we need here. Here you do not have to install the newer version of Debian 8 from source, but simply apply the necessary filter.
Migrate filter sample from Debian 9
If you also have a Debian 9 (Stretch) installation at hand, and it has Fail2Ban, or has it installed, just list the appropriate filter file:
cat /etc/fail2ban/filter.d/sshd.conf
The output of this, which contains filter samples for version 0.9.6:
[...]
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error|failed) for .* from <HOST>( via \S+)?\s*$
^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$
^%(__prefix_line)sFailed \S+ for (?P<cond_inv>invalid user )?(?P<user>(?P<cond_user>\S+)|(?(cond_inv)(?:(?! from ).)*?|[^:]+)) from <HOST>(?: port \d+)?(?: ssh\d*)?(?(cond_user):|(?:(?:(?! from ).)*)$)
^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$
^%(__prefix_line)s[iI](?:llegal|nvalid) user .*? from <HOST>(?: port \d+)?\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because listed in DenyUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not in any group\s*$
^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$
^%(__prefix_line)s(?:error: )?Received disconnect from <HOST>: 3: .*: Auth fail(?: \[preauth\])?$
^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$
^(?P<__prefix>%(__prefix_line)s)User .+ not allowed because account is locked<SKIPLINES>(?P=__prefix)(?:error: )?Received disconnect from <HOST>: 11: .+ \[preauth\]$
^(?P<__prefix>%(__prefix_line)s)Disconnecting: Too many authentication failures for .+? \[preauth\]<SKIPLINES>(?P=__prefix)(?:error: )?Connection closed by <HOST> \[preauth\]$
^(?P<__prefix>%(__prefix_line)s)Connection from <HOST> port \d+(?: on \S+ port \d+)?<SKIPLINES>(?P=__prefix)Disconnecting: Too many authentication failures for .+? \[preauth\]$
^%(__prefix_line)s(error: )?maximum authentication attempts exceeded for .* from <HOST>(?: port \d*)?(?: ssh\d*)? \[preauth\]$
^%(__prefix_line)spam_unix\(sshd:auth\):\s+authentication failure;\s*logname=\S*\s*uid=\d*\s*euid=\d*\s*tty=\S*\s*ruser=\S*\s*rhost=<HOST>\s.*$
[...]
From here we need one line, the one I highlighted in green. This filter pattern fits perfectly with the "invalid user" error messages in the above auth.log file. If you do not have a Debian 9 installation at hand or an 0.9 Fail2 filter in another distribution, use the pattern here.
Copy this line and then paste the Located on Debian 8 (Jessie) sshd.conf:
nano /etc/fail2ban/filter.d/sshd.conf
Similarly we can do 3 here. line to look like our file failregex part of:
[...]
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from <HOST>( via \S+)?\s*$
^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$
^%(__prefix_line)sFailed \S+ for (?P<cond_inv>invalid user )?(?P<user>(?P<cond_user>\S+)|(?(cond_inv)(?:(?! from ).)*?|[^:]+)) from <HOST>(?: port \d+)?(?: ssh\d*)?(?(cond_user):|(?:(?:(?! from ).)*)$)
^%(__prefix_line)sFailed \S+ for .*? from <HOST>(?: port \d*)?(?: ssh\d*)?(: (ruser .*|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".*", client host ".*")?))?\s*$
^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$
^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because listed in DenyUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not in any group\s*$
^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$
^%(__prefix_line)sReceived disconnect from <HOST>: 3: \S+: Auth fail$
^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$
[...]
Let's save it.
Check and fine-tune jail configuration
Next, open the jail.conf file to check your SSH settings:
nano /etc/fail2ban/jail.conf
Find the "[ssh]" jail here:
[...] [ssh] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 2 findtime = 3600 [...]
And let's check the settings:
- enabled: true. Keep the jail on.
- port: ssh. If you use a port other than the default 22 SSH port number, overwrite it with the correct port here
- filter: sshd. Here the ssh jail refers to the appropriate filter file.
- logpath: this log file is being monitored by Fail2
- maxretry: Here you can control the severity of the blocking. After you have forgotten your password, it will allow you so many more attempts.
- findtime: And here seconds determine how much time slots the system will monitor for failed login attempts with the same IP address
Set these according to your needs. In the example above, I let 2 try again in 3600 seconds, so this is a pretty strict setting.
If so, save the jail.conf file as well.
Restart Fail2Ban
After that, there was only a restart in Fail2:
systemctl restart fail2ban.service
A systemctl after the reboot command, let's make sure the jails really started because they can't start them with a bad character in the filter:
cat /var/log/fail2ban.log | tail -20
And in this we have to see that all the jails started nicely:
[...] 2019-05-09 23:15:29,356 fail2ban.jail [31572]: INFO Jail 'ssh' started 2019-05-09 23:15:29,358 fail2ban.jail [31572]: INFO Jail 'apache' started 2019-05-09 23:15:29,359 fail2ban.jail [31572]: INFO Jail 'apache-multiport' started 2019-05-09 23:15:29,360 fail2ban.jail [31572]: INFO Jail 'apache-noscript' started 2019-05-09 23:15:29,361 fail2ban.jail [31572]: INFO Jail 'pureftpd' started 2019-05-09 23:15:29,363 fail2ban.jail [31572]: INFO Jail 'dovecot-pop3imap' started 2019-05-09 23:15:29,364 fail2ban.jail [31572]: INFO Jail 'postfix-sasl' started
If there is an error here, you need to go back to the filter file and look for any extra characters when inserting the new line, etc.
Control
After a few hours or days, we can check the fruits of our work, depending on how often this type of unauthorized access attempt has occurred on our server:
fail2ban-client status ssh
And if there were any attempts during this time, we can already see how Fail2B looks beautifully like green paint:
Status for the jail: ssh |- filter | |- File list: /var/log/auth.log | |- Currently failed: 5 | `- Total failed: 32 `- action |- Currently banned: 2 | `- IP list: xxx.xxx.xxx.xxx, xxx.xxx.xxx.xxx `- Total banned: 9
Conclusion
With this small simple filter add-on, we have enhanced the efficiency of the Fail2Ban program, which in this case can significantly slow down the rate of entry attempts. We can't stop it completely with this method, but we can drastically reduce the number of attempts from the same IP address.
- Encyclopedia - Fail2Ban
- How to enable Fail2Ban program filters in the ISPConfig server environment
- How to unblock our blocked IP address if we are banned from any of our server services
- How to keep unwanted robots away from our server websites
- How to protect our server from attacks on our databases with "Access denied for user root@ip address (using password: YES / NO)" using Fail2Ban
- How to defend against attacks resulting in large volumes of 404 or other 4xx HTTP error codes with Fail2Ban
- Manual - Fail2Ban
- Manual - lastb
- To post registration and login required
- 480 views