This website is hosted on my own dedicated server (a kimsufi) and like every server, it’s getting regularly attacked.

To identify those attacks, I needed to add a layer of security to ban recurrent attempt, this layer is Fail2ban. It’s a widely known and recognized python script that analyses your log file to ban repetitive failed authentication.

I had enough of getting the same IP banned, and found only a simple script that add a new action to fail2ban: Tarpit.

If you are not sure what the tarpit target is or why you would want to use it, a basic explanation is that you send unwanted TCP traffic to the tarpit target with iptables. All connections are accepted and immediately switched to the persist state. The remote side stops sending data and asks to continue every 60-240 seconds and attempts to close the connections from the remote side are ignored. The connection will then timeout in 12-24 minutes.

You can find here a good tutorial on how to install TARPIT on your debian machine (if its kernel support loading modules). By using part of Phil Hagen fail2ban action, I created mine that use also TARPIT.

Here is my fail2ban action:

# Fail2Ban configuration file
#
# Author: Cyril Jaquier
# Modified: Yaroslav O. Halchenko <debian@onerussian.com>
#                       made active on all ports from original iptables.conf
# Modified: Antoine Aflalo <antoine@aaflalo.me>
#                       Used the iptables-allports.conf as base for TARPIT.
#
#


[Definition]

# Option:  actionstart
# Notes.:  command executed once at the start of Fail2Ban.
# Values:  CMD
#
actionstart = iptables -N fail2ban-<name>
              iptables -A fail2ban-<name> -j RETURN
              iptables -I <chain> -p <protocol> -j fail2ban-<name>
               # set up TARPIT chain with rate limit
              iptables -N TAR
              iptables -A TAR -m limit --limit 10/sec -j TARPIT --tarpit  -p tcp
              iptables -A TAR -j DROP
               # set up from the static file
              cat /etc/fail2ban/ip.blocklist.<name> |grep -v ^\s*#|awk '{print $1}' | while read IP; do iptables -I fail2ban-<name> 1 -s $IP -j TAR; done

# Option:  actionstop
# Notes.:  command executed once at the end of Fail2Ban
# Values:  CMD
#
actionstop = iptables -D <chain> -p <protocol> -j fail2ban-<name>
             iptables -F fail2ban-<name>
             iptables -X fail2ban-<name>
             iptables -F TAR
             iptables -X TAR

# Option:  actioncheck
# Notes.:  command executed once before each actionban command
# Values:  CMD
#
actioncheck = iptables -n -L <chain> | grep -q 'fail2ban-<name>[ \t]'

# Option:  actionban
# Notes.:  command executed when banning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j TAR
            # also put into the static file to re-populate after a restart
            ! grep -Fq <ip> /etc/fail2ban/ip.blocklist.<name> && echo "<ip> # fail2ban/$( date '+%%Y-%%m-%%d %%T' ): auto-add for repeat offender" >> /etc/fail2ban/ip.blocklist.<name>

# Option:  actionunban
# Notes.:  command executed when unbanning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
#actionunban = iptables -D fail2ban-<name> -s <ip> -j TAR
actionunban = /bin/true

[Init]

# Default name of the chain
#
name = default

# Option:  protocol
# Notes.:  internally used by config reader for interpolations.
# Values:  [ tcp | udp | icmp | all ] Default: tcp
#
protocol = tcp

# Option:  chain
# Notes    specifies the iptables chain to which the fail2ban rules should be
#          added
# Values:  STRING  Default: INPUT
chain = INPUT

And here is an excerpt of my jail.local

# Multi Ban
# 3 ban in 24 hour & Ban for 1 week
[multi-ban]
enabled = true
filter = ban
logpath = /var/log/fail2ban.log
maxretry = 3
findtime = 86400
#action = iptables-allports[name=multiban]
action = iptables-tarpit[name=multiban]
bantime = 604800

And the filter used to check for previous ban:

# Fail2Ban configuration file
#
# Author: Nicolargo
#
[Definition]
# Option: failregex
# Filter Ban in the fail2ban.log
failregex = .*Ban\ <HOST>
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =