Fail2Ban is a service that watches the log files of your services, such as SSH, HTTP, and FTP, looking for consecutive authentication fails that may indicate an unauthorized person trying to get in.

When detecting a possible intruder that fails to log in X attempts in Y length of time, it bans the origin IP address for Z time. It creates a rule in your firewall to ban and automatically removes it after the ban time expires.

sudo apt update
sudo apt install fail2ban
sudo systemctl status fail2ban

You might see the service active (running).

sudo cp /etc/fail2ban/jail.{conf,local}
sudo nano /etc/fail2ban/jail.local

Inform your white list. Uncomment this line and fill it with the “safe” IP addresses. Usually, I would put the loopback interfaces (127.0.0.1/8 and ::1), and if you access your network remotely via VPN for example, I would also include the VPN network IP (10.8.0.0/24) in this list.

ignoreip = 127.0.0.1/8 ::1 10.8.0.0/24

Before you leave the file, you have to define X, Y, and Z:

bantime = 1d
findtime = 60m
maxretry = 5
backend = systemd

In my case, if someone fails 5 times 60 minutes will be banned for 1 day. Change also the backend to “systems” because it comes by default as “auto” but for some reason, the filter was not catching anything.

Configure the e-mail alert notification when someone is banned (you need an SMTP server installed and running):

destemail = [email protected]
sender = [email protected]
action = %(action_mw)s

Now you can go down and look for the service you want to protect. You should only enable the ones that you need, not just everything without criteria.

[sshd]
enabled = true
#mode = normal
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s

Insert the enabled = true at the “Jail” you are creating.

In the example above, I activated on my SSH server, and I would do the same with HTTP, FTP, and any other service that is exposed to the internet and requires authentication.

Note that I left one commented line on the last example. You can uncomment the mode = normal and change it to a more aggressive approach, like DDoS, extra, or aggressive. See “filter.d/sshd.conf” for usage example and details.

Save the configuration file, restart your service, and check if it is running or has failed due to any configuration issue:

sudo systemctl restart fail2ban
sudo systemctl status fail2ban

Fail2Ban offers a CLI that makes it possible for you to interact with the service called fail2ban-client. See examples of usage:

sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 1.1.1.1
sudo fail2ban-client set sshd banip 1.1.1.1
sudo fail2ban-client -h

Right after setting up this service, I just received 46 new emails of banned IPs trying to enter my SSHD as root (I omitted the last number):

Total failed: 1106
Total banned: 38
Banned IP list: 93.39.184.1X 95.78.251.11X 208.109.11.3X 167.71.237.7X 162.243.130.8X 82.65.23.6X 100.26.163.9X (...)

Checking the origin of the IP addresses, I can only say that they come from anywhere: USA, CH, IND, SG, RU, IT, FR, UK, GER, VN, NL, HK, etc. Most of them are from OVH SAS and DigitalOcean (private cloud services).

Consequently, from the large number of “hackers”, I had to disable the email notification (more than 10 emails per hour).

A week after setting up this safety tool, the number of bans on my SSH fell from 200 a day to 4. The only reason I see for it is that by being banned, many might get discouraged to keep trying. So, for the same reason, I will disable ping responses to not advertise that my server is live and see if I get any improvement.

If you want to get all the status at the same time (it is one big line):

fail2ban-client status | sed -n 's/,//g;s/.*Jail list://p' | xargs -n1 fail2ban-client status

BONUS

Did you know you can use Fail2Ban also to protect your WordPress website? See more in WordPress Configuration Tips and Tricks [Link].

As an alternative to Fail2Ban, the open source SSHGuard aims to accomplish the same goal [Link].

sudo apt update && sudo apt install sshguard -y
echo '192.168.1.0/24' >> /etc/sshguard/whitelist
sudo nano /etc/sshguard/sshguard.conf

Configure accordingly.

# For IPTABLES
BACKEND="/usr/lib/sshguard/sshg-fw-iptables"
# For NFTABLES
#BACKEND="/usr/lib/sshguard/sshg-fw-nft-sets"
WHITELIST_FILE="/etc/sshguard/whitelist"
BLOCK_TIME=1200
DETECTION_TIME=1800
THRESHOLD=30

Start and check the activity in the logs.

sudo systemctl enable sshguard --now
sudo journalctl -u sshguard -f

List the banned IPs and unban by line number.

sudo iptables --list sshguard --line-numbers --numeric
sudo iptables --delete sshguard <line-number>