Prevent SSH-bruteforce in Linux
The Internet has never been a safe place. The more devices connected to it, the more often they are subjected to various attacks. Now the situation is such that if you take absolutely any server with a static IP address, then after a few minutes you can see a system report informing about login attempts with incorrect credentials.
Every day, thousands of bots scan the IPv4 address space looking for standard open ports such as SSH. When a vulnerability host is found, then they try to find the administrator’s access credentials. In many cases, they succeed in this, since a huge number of users of home Internet routers and smart devices haven’t even thought about changing their default passwords. In more complex cases, bots can launch a brute-force attack. These attacks work well only if the password is short or very simple (for example contains only numbers). Also attackers may use passwords from leaked databases or crafted dictionary attacks.
Having gained administrator access, an attacker can turn the device into a “zombie” that begins to obediently execute any commands. After this, there can be a lot of attack vectors: from theft of personal data to the installation of applications for mining cryptocurrencies. In some cases, controlled devices are combined into a botnet, which is used to carry out distributed DDoS attacks. With rented servers, the situation can be much more serious, because they are connected to high-speed communication channels and can become a “cyberweapon” in the hands of attackers. Therefore, to prevent hacking, you should take care of protection in advance.
Rented LeaderGPU servers, after ordering, receive randomly generated access credentials, which take too long to retrieve using a brute-force attack. But nevertheless, the standard port 22 serving SSH begins to receive a large number of bot requests, to which the server is forced to respond.
Since all these requests have a common feature (constantly incorrectly entered access credentials), they can be distinguished from legitimate requests from real users and blocked by IP addresses. But since real users can also often make mistakes when entering logins and passwords, it makes sense to give them 3 to 6 entry attempts before being blocked. It is on this principle that the most popular tool called fail2ban works.
The system records all unsuccessful connection attempts via SSH in a log file located at /var/log/auth.log. By periodically scanning this file, fail2ban can obtain all the necessary data, namely, the number of attempts with incorrect credentials and the IP address of the device that initiated these attempts. But the capabilities of fail2ban are not limited to this. The same mechanism can be used to protect web servers based on Apache, Nginx, or Lighttpd, as well as many other programs, for example, the Asterisk IP telephony server.
It is completely free and open source software and is also included in many repositories of popular Linux distributions, such as Ubuntu or OpenSUSE. If for some reason installation from there is not available, then you can always look at GitHub and either download a pre-prepared package for Debian-like systems or compile it yourself from source code.
Install and configure fail2ban
For this example, we’ll take a dedicated server with the Ubuntu Linux 22.04 LTS operating system installed on it. Update the package cache and install fail2ban:
sudo apt update && sudo apt -y install fail2ban
It’s important to understand that fail2ban itself consists of two parts: server and client. The server part is a daemon that resides permanently in RAM, scanning log files and blocking those who meet the blocking conditions described in the /etc/fail2ban/jail.conf configuration file. The client part allows you to monitor the state of the daemon, display statistics on how many hosts were blocked, and unblock specific addresses as necessary.
First, let’s make a backup of the original configuration file, so that we can restore it:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.conf.bak
The authors of fail2ban recommend creating a separate jail.local file or configuration files in the jail.d subdirectory instead of overwriting the original jail.conf. Let’s use the second method, and by going to this subdirectory, we’ll find the created defaults-debian.conf file, which contains only one parameter, enabling default protection for the sshd service:
cat /etc/fail2ban/jail.d/defaults-debian.conf
[sshd] enabled = true
We suggest deleting this file:
sudo rm /etc/fail2ban/jail.d/defaults-debian.conf
Let’s write your own configuration file and name it sshd.conf:
sudo nano /etc/fail2ban/jail.d/sshd.conf
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 6
findtime = 300
bantime = 3600
ignoreip = 127.0.0.1
Brief explanation of what each of the parameters means:
- [sshd]: section name;
- enabled = true: enables the parameters listed in this section;
- port = ssh: port number or service designation;
- filter = sshd: select a default filter containing regular expressions to search for failures in sshd authentication;
- logpath = /var/log/auth.log: path to the log file that fail2ban will check;
- maxretry = 6: number of authentication attempts before the IP address is blocked;
- findtime = 300: specify the time in seconds how far into the past the log file will be scanned;
- bantime = 3600: ban time (also in seconds);
- ignoreip = 127.0.0.1: here you can specify IP addresses that fail2ban will not block under any circumstances.
Now you can start the daemon and tell the system that it should be placed in startup:
sudo systemctl start fail2ban && sudo systemctl enable fail2ban
Using the fail2ban-client, you can check that the daemon started successfully and loaded the configuration file correctly:
sudo fail2ban-client status
Status |- Number of jail: 1 `- Jail list: sshd
It can be seen that you currently have one service under protection. Let’s take a look at the blocking statistics:
sudo fail2ban-client status sshd
Status for the jail: sshd |- Filter | |- Currently failed: 0 | |- Total failed: 0 | `- File list: /var/log/auth.log `- Actions |- Currently banned: 0 |- Total banned: 0 `- Banned IP list:
So far, you have no blocked addresses, but after some time, this situation will change. In order not to wait, you can manually check the operation of the blocking mechanism.
How to check
It is important to do the following steps from another IP address, different from one you usually use to manage the server!
Add a test user to the system:
sudo useradd test
Give him a password:
sudo passwd test
Now open an SSH session and try to log in 6 times with incorrect access credentials. Locally or via another IP address, check:
sudo fail2ban-client status sshd
Status for the jail: sshd |- Filter | |- Currently failed: 1 | |- Total failed: 6 | `- File list: /var/log/auth.log `- Actions |- Currently banned: 1 |- Total banned: 1 `- Banned IP list: XXX.XXX.XXX.XXX
It can be seen that the IP address has been successfully blocked. If necessary, any address can be unblocked manually with the following command:
sudo fail2ban-client set sshd unbanip [XXX.XXX.XXX.XXX]
Don’t forget to delete the test user:
sudo userdel test
See also:
Updated: 28.03.2025
Published: 25.07.2024