The cloud server has been continuously scanned on port 22 for brute force attacks, and watching these constantly rolling records is quite frustrating.
root@localhost:~# lastb
ssh:notty 64.62.197.115 Fri Oct 6 21:29 - 21:29 (00:00)
httpfs ssh:notty 68.183.176.157 Fri Oct 6 21:12 - 21:12 (00:00)
httpfs ssh:notty 68.183.176.157 Fri Oct 6 21:12 - 21:12 (00:00)
operator ssh:notty 157.245.220.120 Fri Oct 6 21:10 - 21:10 (00:00)
operator ssh:notty 157.245.220.120 Fri Oct 6 21:10 - 21:10 (00:00)
web ssh:notty 68.183.176.157 Fri Oct 6 21:06 - 21:06 (00:00)
web ssh:notty 68.183.176.157 Fri Oct 6 21:06 - 21:06 (00:00)
operator ssh:notty 157.245.220.120 Fri Oct 6 21:05 - 21:05 (00:00)
operator ssh:notty 157.245.220.120 Fri Oct 6 21:05 - 21:05 (00:00)
root ssh:notty 121.186.84.26 Fri Oct 6 21:03 - 21:03 (00:00)
root ssh:notty 121.186.84.26 Fri Oct 6 21:03 - 21:03 (00:00)
root ssh:notty 121.186.84.26 Fri Oct 6 21:03 - 21:03 (00:00)
unbt ssh:notty 68.183.176.157 Fri Oct 6 20:59 - 20:59 (00:00)
unbt ssh:notty 68.183.176.157 Fri Oct 6 20:59 - 20:59 (00:00)
operator ssh:notty 157.245.220.120 Fri Oct 6 20:59 - 20:59 (00:00)
operator ssh:notty 157.245.220.120 Fri Oct 6 20:59 - 20:59 (00:00)
operator ssh:notty 157.245.220.120 Fri Oct 6 20:53 - 20:53 (00:00)
operator ssh:notty 157.245.220.120 Fri Oct 6 20:53 - 20:53 (00:00)
node ssh:notty 68.183.176.157 Fri Oct 6 20:53 - 20:53 (00:00)
node ssh:notty 68.183.176.157 Fri Oct 6 20:53 - 20:53 (00:00)
operator ssh:notty 157.245.220.120 Fri Oct 6 20:47 - 20:47 (00:00)
operator ssh:notty 157.245.220.120 Fri Oct 6 20:47 - 20:47 (00:00)
backup ssh:notty 68.183.176.157 Fri Oct 6 20:46 - 20:46 (00:00)
operator ssh:notty 157.245.220.120 Fri Oct 6 20:42 - 20:42 (00:00)
operator ssh:notty 157.245.220.120 Fri Oct 6 20:42 - 20:42 (00:00)
develope ssh:notty 68.183.176.157 Fri Oct 6 20:40 - 20:40 (00:00)
develope ssh:notty 68.183.176.157 Fri Oct 6 20:40 - 20:40 (00:00)
operator ssh:notty 157.245.220.120 Fri Oct 6 20:36 - 20:36 (00:00)
operator ssh:notty 157.245.220.120 Fri Oct 6 20:36 - 20:36 (00:00)
nexus ssh:notty 68.183.176.157 Fri Oct 6 20:33 - 20:33 (00:00)
nexus ssh:notty 68.183.176.157 Fri Oct 6 20:33 - 20:33 (00:00)
nifi ssh:notty 157.245.220.120 Fri Oct 6 20:30 - 20:30 (00:00)
nifi ssh:notty 157.245.220.120 Fri Oct 6 20:30 - 20:30 (00:00)
root ssh:notty 59.39.24.254 Fri Oct 6 20:30 - 20:30 (00:00)
root ssh:notty 59.39.24.254 Fri Oct 6 20:28 - 20:28 (00:00)
root ssh:notty 111.26.175.223 Fri Oct 6 20:27 - 20:27 (00:00)
nvidia ssh:notty 68.183.176.157 Fri Oct 6 20:27 - 20:27 (00:00)
nvidia ssh:notty 68.183.176.157 Fri Oct 6 20:27 - 20:27 (00:00)
nifi ssh:notty 157.245.220.120 Fri Oct 6 20:25 - 20:25 (00:00)
nifi ssh:notty 157.245.220.120 Fri Oct 6 20:25 - 20:25 (00:00)
aaa ssh:notty 68.183.176.157 Fri Oct 6 20:20 - 20:20 (00:00
Fail2Ban is an intrusion detection system framework that can prevent brute force attacks through proper configuration, and it is available in the package management of most distributions.
Install Fail2ban on Debian#
# Install using Debian package manager
sudo aptitude install fail2ban
Configure Fail2ban#
The configuration files installed via the package manager are located in the /etc/fail2ban
directory, with the following directory structure:
ls -al
total 104
drwxr-xr-x 6 root root 4096 Apr 14 12:08 .
drwxr-xr-x 97 root root 4096 Mar 21 23:24 ..
drwxr-xr-x 2 root root 4096 Oct 6 2023 action.d
-rw-r--r-- 1 root root 3017 Nov 9 2022 fail2ban.conf
drwxr-xr-x 2 root root 4096 Apr 22 2023 fail2ban.d
drwxr-xr-x 3 root root 4096 Mar 11 21:41 filter.d
-rw-r--r-- 1 root root 25607 Apr 14 11:20 jail.conf
drwxr-xr-x 2 root root 4096 Apr 14 11:29 jail.d
-rw-r--r-- 1 root root 645 Nov 9 2022 paths-arch.conf
-rw-r--r-- 1 root root 2728 Nov 9 2022 paths-common.conf
-rw-r--r-- 1 root root 627 Nov 9 2022 paths-debian.conf
-rw-r--r-- 1 root root 738 Nov 9 2022 paths-opensuse.conf
Fail2ban Configuration File Directory Structure#
action.d | Directory storing action configuration files executed when rules are triggered |
fail2ban.conf | The Fail2ban.conf configuration file |
fail2ban.d | Additional configuration files for Fail2ban |
filter.d | Directory for Fail2ban rules/filters, containing configuration files that define log filtering rules; it includes official rules, and you can define your own filtering rules here, such as intercepting frp internal penetration, etc. |
jail.conf | Official example configuration file for Fail2ban jail, defining rules for monitoring and defending services or protocols, calling filters and actions. |
jail.d | Stores additional configuration files for jails; Fail2ban loads the jail.local file and all configuration files in the jail.d directory at startup. |
According to Proper fail2ban configuration, the provided example configuration file is placed in jail.conf
. It is not recommended to modify the provided configuration file directly; instead, edit your own jail.local
based on the provided example configuration file. The jail rules defined in the jail.conf example configuration file are disabled by default and need to be manually enabled.
sudo cp jail.conf jail.local
sudo nano jail.local
Jail Configuration File#
[DEFAULT]
# This section is for global configuration of jail rules; global settings can be overridden
...
# The duration of the ban, default is in seconds; bantime = 10m means the ban lasts for 10 minutes.
bantime = 10m
# The time period used to determine whether to ban an IP, in seconds; findtime = 10m means that if the number of login failures in the past 10 minutes is greater than or equal to maxretry, the IP will be banned.
findtime = 10m
# The maximum number of allowed login failures; if an IP address reaches or exceeds maxretry within the findtime period, it will be banned.
maxretry = 5
# "maxmatches" is the number of matches stored in ticket (resolvable via tag <matches> in actions).
maxmatches = %(maxretry)s
# The backend used to get file modifications. This option specifies the mechanism used by Fail2ban to monitor file changes.
# Available backends include: pyinotify, gamin, polling, systemd, and auto.
# If no backend is specified, Fail2ban will try to use these backends in order until it finds an available one.
# backend = auto means Fail2ban will try to use one of pyinotify, gamin, polling, or systemd.
backend = auto
# Enable ssh
[sshd]
# Use nftables to ban IP
banaction = nftables-multiport
banaction_allports = nftables-allports
# Duration for which the client host is banned, in seconds
bantime = 86400
# Number of allowed failures before banning the client host
maxretry = 3
# Duration for checking failure counts, in seconds
findtime = 600
backend = systemd
enable=true
It is important to note that Fail2ban needs to analyze log files. In some Linux distributions, the SSH login logs have been replaced by systemd, so not configuring backend = systemd
will directly result in the following error:
ERROR Failed during configuration: Have not found any log file for sshd jail
Fail2ban Commands#
After configuration, restart Fail2ban:
# Restart
sudo systemctl restart fail2ban
# Stop
sudo systemctl stop fail2ban
# Start
sudo systemctl start fail2ban
# Enable on boot
sudo systemctl enable fail2ban
# Disable on boot
sudo systemctl disable fail2ban
# View help command
sudo fail2ban-client -h
# Check if fail2ban started successfully
sudo fail2ban-client ping
# Display pong indicates successful startup
Server replied: pong
# View currently enabled rules
sudo fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshd
# View ban information under specified rule
sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 2
| |- Total failed: 14
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 3
|- Total banned: 3
`- Banned IP list: 121.186.84.26 157.245.220.120 68.183.176.157
References#
Proper fail2ban configuration
How To Protect SSH with Fail2Ban on Debian 11 | DigitalOcean
Gentoo-Fail2ban
how-to-install-fail2ban-on-debian-linux
Using Fail2ban to Automatically Blacklist IPs for SSH Brute Force Attacks - Alain's Blog (alainlam.cn)
Fail2ban - ArchWiki (archlinux.org)
Four Methods to Prevent SSH Brute Force Attacks - CSDN Blog