Fail2ban protects your Linux VPS by banning IP addresses that attempt to break in. Fail2ban scans your VPS log files to decide which IPs should be banned (e.g. /var/log/apache/error_log). It checks for too many incorrect password attempts, exploit scans, and so on.
You can also have Fail2ban automatically send a report to yourself and to the owner of the attacking IP. Fail2ban comes with filters for various services (Apache, Courier, SSH, etc.).
Installing Fail2ban
AlmaLinux / Rocky Linux / CentOS Stream
Step 1
First update your VPS:
sudo dnf -y update
Step 2
Fail2ban is not included in the official repository; it is, however, in the Extra Packages for Enterprise Linux (EPEL). Install the latest EPEL release first.
sudo dnf -y install epel-release
Step 3
Now install Fail2ban:
sudo dnf -y install fail2ban
If you get an error, run sudo dnf -y update again first.
Step 4
Enable Fail2ban to start with the VPS and start the service:
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Continue with configuring Fail2ban.
Ubuntu/Debian
Step 1
First update your VPS:
sudo apt -y update && sudo apt -y upgrade
Step 2
Fail2ban is included by default in Ubuntu’s repository. Install it with:
sudo apt -y install fail2ban
Step 3
Enable Fail2ban and start it:
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Next, continue with configuring Fail2ban.
Configuring Fail2ban
By default Fail2ban uses /etc/fail2ban/jail.conf. Any changes you make there will be overwritten by updates. Instead, use /etc/fail2ban/jail.local; it is never overwritten and its settings override jail.conf.
Only include the parts of the configuration that apply to your VPS. For example, if you don’t use Exim, leave that section out.
Step 1
Create the jail.local file:
sudo nano /etc/fail2ban/jail.local
Step 2
Copy the block below and adjust the values to your needs (tip: use PuTTY and copy‑paste). Pay special attention to banaction (example assumes CentOS Steam, AlmaLinux, or Rocky Linux).
Change sender, destemail, and ignoreip to your own values, and enable only the jails for services actually running on your VPS (e.g. Exim or Postfix, not both). You can check which you use with systemctl status exim / postfix.
[DEFAULT]
# Ban for X amount of time
bantime = 604800
findtime = 3600
sender = fail2ban@example.com
destemail = admin@example.com
action = %(action_mwl)s
banaction = iptables-multiport
maxretry = 3
ignoreip = your.ip.address
[sshd]
enabled = true
port = ssh # replace ssh with your configured SSH port
[exim]
enabled = true
filter = exim
logpath = /var/log/exim/mainlog
# cPanel: use /var/log/exim_mainlog
# Debian: /var/log/exim4/mainlog
[postfix]
enabled = true
port = smtp,ssmtp
filter = postfix
failregex = \[<HOST>]: 535 Incorrect authentication data
logpath = /var/log/maillog
[dovecot]
enabled = true
port = pop3,pop3s,imap,imaps
filter = dovecot
logpath = /var/log/maillog
Code explanation
Fail2ban uses so-called 'Jails'. A jail can be seen as the configuration for a specific piece of software on your VPS in which you define things like which service and port are used and which log file is scanned by Fail2ban. Above, for example, the piece under [Exim] is a jail.
[Default]
- bantime: A bantime of 60 is 1 minute, 3600 1 hour, 86400 1 day and 604800 1 week, etcetera.
- findtime: This defines how far back in the past Fail2ban checks your log files. By default, this is set to 600 (10 minutes). If an IP carries out one attack every 10 minutes, Fail2ban would not notice this because action is only taken after five attacks (see maxretry) within 10 minutes.
- sender (optional): The email address that sends notifications of Fail2ban actions to the attacker. Configuring an outgoing mail server and an email address on your VPS that you can use for this purpose is outside the scope of this manual.
- destemail (optional): Your own email address to which notifications of Fail2ban actions are sent. Configuring an outgoing mail server and an email address on your VPS that you can use for this purpose is outside the scope of this manual.
- action (optional): The default option %(action_)s bans the IP of the attacker. In addition, %(action_mwl)s sends an email notification including WHOIS data and logfile data.
-
banaction: With banaction you indicate which firewall you use. For example, Ufw is the default for Ubuntu and Debian. You can specify in jail.local firewalld or iptables as follows:
- firewalld: banaction=iptables-multiport
- iptables: banaction = iptables-multiport
- ufw: banaction = ufw
- maxretry: Here you can specify the maximum number of attempts someone is allowed to make (for example, incorrect login attempts) before the action under 'action' is executed. We recommend setting this quite low, for example to 3 and setting it over a period of at least 1 - 2 hours (under findtime). There are many bots that do not attack more than +- 5 times per +- 1.5 hours.
- sshd enabled: This will monitor ssh connection attempts and ban IPs that make more attempts than defined under maxretry.
- ignoreip: Enter your own IP here. If you forget your password, your IP will not be banned immediately after the number of attempts under 'maxretry'. Are you using our TCP monitoring? Then add the IPs 87.253.155.102 and 80.69.67.10 as well.
[SSHD] (SSH server)
- enabled: Enables security for your SSH(D) connection
- port: Here you specify which port is secured. With the value 'ssh' you tell Fail2ban to use the set SSH port.
[exim] (outgoing mail)
- enabled: Enables security for your Exim connection
- filter: Indicates which filter is used. There is no filter for Exim and you create one separately in steps 3 and 4.
- failregex: These are error messages that the log defined under 'logpath' is searched for.
- logpath: The log file that Fail2ban searches. Note: this can differ per system. cPanel and DirectAdmin both use Exim and use different locations for the mail log, for example. Please check these in advance and adjust them to the actual location.
[postfix] (outgoing mail)
- enabled: Enables security for your Postfix connection
- port: Here you specify which port is secured. With the value 'smtp, ssmtp' you tell Fail2ban to use the set SMTP port.
- filter: Indicates which filter is used. Fail2ban comes with a number of filters that are included in /etc/fail2ban/filter.d/, including the postfix filter that is called here.
- failregex: These are error messages that the log defined under 'logpath' is searched for.
- logpath: The log file that Fail2ban searches. Note: this can differ per system. Please check these in advance and adjust them to the actual location.
[dovecot] (incoming mail)
- enabled: Enables security for your Dovecot connection
- port: Here you specify which port is secured. The value 'pop3, pop3s, imap, imaps' tells Fail2ban to secure the configured pop3 and imap ports.
- filter: Specifies which filter is used. Fail2ban comes with a number of filters that are included in /etc/fail2ban/filter.d/ . In this case, the supplied dovecot filter is used.
- logpath: The log file that Fail2ban searches.
Step 3
If you use Exim (e.g. in our DirectAdmin or cPanel images), extend the Exim filter. If not, skip to Step 5.
sudo nano /etc/fail2ban/filter.d/exim.conf
Step 4
Add the line below to the failregex section, then save (Ctrl + X → Y → Enter):
\[<HOST>\]: 535 Incorrect authentication data
Your [Definition] block should now look roughly like this:
[Definition]
failregex = ^%(pid)s %(host_info)ssender verify fail for <\S+>: ...
\[<HOST>\]: 535 Incorrect authentication data
ignoreregex =
Restart Fail2ban so it picks up your changes:
sudo systemctl restart fail2ban
Advanced / optional: escalating Fail2ban ban time
To prevent a legitimate user from being permanently blocked for a brief mistake, you can configure escalating bans: an hour, then a day, then a week, etc.
Step 1
Create /etc/fail2ban/filter.d/f2b-repeat.conf:
sudo nano /etc/fail2ban/filter.d/f2b-repeat.conf
Step 2
Add the following and save your changes (ctrl + x > y > enter):
[INCLUDES]
before = common.conf
[Definition]
failregex = (?i)\]\s+ban\s+<HOST>
ignoreregex = (?i)\[f2b-repeat.*\]\s+ban\s+<HOST>
Step 3
In your jail.local file, insert the [f2b-repeat] jails shown below between the [DEFAULT] and [sshd] sections. Only adjust bantime, findtime, and optionally maxretry in [DEFAULT].
[DEFAULT]
# Ban for X amount of time
bantime = 3600
findtime = 86400
sender = fail2ban@example.com
destemail = admin@example.com
action = %(action_mwl)s
banaction = iptables-multiport
maxretry = 3
ignoreip = your.ip.address
[f2b-repeat2]
enabled = true
filter = f2b-repeat
bantime = 86400
findtime = 604800
logpath = /var/log/fail2ban.log
maxretry = 3
[f2b-repeat3]
enabled = true
filter = f2b-repeat
bantime = 604800
findtime = 2592000
logpath = /var/log/fail2ban.log
maxretry = 3
[f2b-repeat4]
enabled = true
filter = f2b-repeat
bantime = 2592000
findtime = 15552000
logpath = /var/log/fail2ban.log
maxretry = 3
By increasing findtime, Fail2ban looks further back and gets stricter with repeat attackers.
Step 4
If you specify /var/log/fail2ban.log as above, create that log file first or Fail2ban will not start:
sudo touch /var/log/fail2ban.log
Step 5
Now you can (re)start Fail2ban:
sudo systemctl restart fail2ban
Advanced / optional: extra filters / jails
Fail2ban ships with numerous filters which can be found in /etc/fail2ban/filter.d/:
Step 1
List the defaults with:
ls /etc/fail2ban/filter.d/
You will see a list like this:
Pick the filter you want, e.g. apache-auth.conf.
Step 2
Re‑open your jail file:
sudo nano /etc/fail2ban/jail.local
Step 3
Add a jail with this syntax:
[jailname]
enabled = true
filter = jailname
logpath = /var/log/yourlogfile
- [jailname] – choose any recognizable name.
-
enabled – must be
true
. -
filter – the filter name you selected (omit
.conf
). - logpath – the file Fail2ban scans for attacks.
Additional tips & commands
Check Fail2ban’s status:
sudo fail2ban-client status
View logs:
sudo nano /var/log/fail2ban.log
sudo vi /var/log/fail2ban.log
sudo cat /var/log/fail2ban.log
Verify the service is running:
sudo systemctl status fail2ban
Restart after changes:
sudo systemctl restart fail2ban
Manual banning / unbanning
Manual ban
If someone patiently tries once per hour, you can ban their IP manually. First list available jails:
sudo fail2ban-client status
Then ban an IP (replace JAIL and xxx.xxx.xxx.xxx):
sudo fail2ban-client -vvv set JAIL banip xxx.xxx.xxx.xxx
Manual unban
If an IP was blocked by mistake, unban it (replace JAIL and the IP):
sudo fail2ban-client set JAIL unbanip xxx.xxx.xxx.xxx
Unsure which jail? Search the log:
sudo nano /var/log/fail2ban.log
Inside nano, press Ctrl + W and enter the IP to search.
The installation and configuration of Fail2ban on your VPS is now complete. Your VPS is protected against brute‑force attacks!