Debian: fail2ban + nftables

Fail2ban scans log files and bans IPs that show the malicious signs — too many password failures, seeking for exploits, etc. Generally Fail2Ban is then used to update firewall rules to reject the IP addresses for a specified amount of time, although any arbitrary other action (e.g. sending an email) could also be configured. Out of the box Fail2Ban comes with filters for various services (apache, courier, ssh, etc).

Fail2Ban is able to reduce the rate of incorrect authentications attempts however it cannot eliminate the risk that weak authentication presents. Configure services to use only two factor or public/private authentication mechanisms if you really want to protect services.

NFtables is the new netfilter kernel based firewall software which will replace iptables. Following post will describe on how to configure netfilter to use NFtables to ban ip’s abusing the systems. This post expects already Nftables to be configured, however fail2ban will configure its own deny and table list.

Step 1: Install Packages

The ModSecurity module for Apache is included in the default Debian/Ubuntu repository. To install it, run

# apt install fail2ban nftables

Enable and start fail2ban

# systemctl enable fail2ban
# systemctl start fail2ban

Step 2: Configure fail2ban

In order to create a unique configuration file, fail2ban uses a use configurable file for your personal settings. This way debian can upgrade packages without interfering with your customization. Create a new file /etc/fail2ban/jail.local  with the following settings:

#
# The fail2ban local definition file for the default settings.
#

[DEFAULT]
# Destination email for action that send you an email
destemail = admin@yourdestinationemail.com

# Sender email. Warning: not all actions take this into account. Make sure to test if you rely on this
sender    = fail2ban@thisserver.com

# Default action. Will block user and send you an email with whois content and log lines.
action    = %(action_mwl)s

# ignoreip can be a list of IP addresses, CIDR masks, or DNs hosts. Fail2ban
# # will not ban a host which matches an address in this list.
ignoreip = 127.0.0.1/8 ::1/128

# configure nftables
banaction = nftables-multiport
chain     = input

# regular banning
bantime = 24h
findtime = 600
maxretry = 3

# "bantime.increment" allows to use database for searching of previously banned ip's to increase a
# default ban time using special formula, default it is banTime * 1, 2, 4, 8, 16, 32...
bantime.increment = true

# "bantime.rndtime" is the max number of seconds using for mixing with random time
# to prevent "clever" botnets calculate exact time IP can be unbanned again:
bantime.rndtime = 30m

# "bantime.maxtime" is the max number of seconds using the ban time can reach (don't grows further)
bantime.maxtime = 60d

# "bantime.factor" is a coefficient to calculate exponent growing of the formula or common multiplier,
# default value of factor is 1 and with default value of formula, the ban time
# grows by 1, 2, 4, 8, 16 ...
bantime.factor = 2

# purge database entries after
dbpurgeage = 30d

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 6
mode = aggressive

[postfix]
enabled  = true
port     = smtp,ssmtp
filter   = postfix
logpath  = /var/log/mail.log
ignoreip = 127.0.0.1/8 ::1/128 192.168.0.0/24

Step 3: Disable email-in and out

Every time fail2ban stop- or starts it will send an email; you can disable this by configuring this setting in the /etc/fail2ban/action.d/sendmail-common.local file:

#
# Override the Fail2Ban defaults in sendmail-common.conf with these entries
#
[Definition]
# Disable email notifications of jails stopping or starting
actionstart =
actionstop =

Step 4: Enable recidive

The recidive jail analyzes the fail2ban.log file, looks at the history and during a restart of actions uses rules to re-enforce ban procedures. It does not directly analyze the postfix (maillog) log. Recidive counts the number of bans in the fail2ban.log.

Create a new recidive configuration file /etc/fail2ban/jail.d/recidive.conf

#
# Manages the fail2ban history for hosts repeatedly banned by Fail2Ban and bans them
# according to the settings defined
#

[recidive]
enabled   = true
logpath   = /var/log/fail2ban.log
banaction = nftables-allports
bantime = 9w
findtime = 3d
maxretry  = 3
protocol  = 0-255

Step 5: Enable other service monitoring

One can enable various different services to monitor, for example Bind by defining a new jail file /etc/fail2ban/jail.d/named.conf

#
# Manages the fail2ban for bind 
#

[named-refused-tcp]
enabled = true
port = domain,953
protocol = tcp
filter = named-refused
logpath = /var/log/named/security.log
banaction = nftables-multiport[name=Named, port="domain,953", protocol=tcp]
ignoreip = 127.0.0.1/8
findtime = 86400
bantime = 604800
maxretry = 1

Step 6: Restart Services

# systemctl restart fail2ban

Step 7: Service Dependencies

When you restart nftables, make sure that the fail2ban service is also restarted so that its firewall rules are added, in order to do so add a service dependency between the two. Create a new file /etc/systemd/system/fail2ban.service.d/override.conf with the following details:

[Unit]
Requires=nftables.service
PartOf=nftables.service

[Install]
WantedBy=multi-user.target nftables.service

Reload the systemctl daemon service to include this dependency

# systemctl daemon-reload