Wednesday, March 12, 2014

Setting up fail2ban

Fail2ban is a program, that can prevent brute force attempts to your computer. Basically it counts failed login attempts and after given count is reached, it triggers an action, which usually is ban for IP address.

First of all, you need to install fail2ban package. On ArchLinux I needed to install fail2ban-devel from AUR, because stable version in Arch repository doesn't have support for journald binary log format.

In my case, I wanted to ban IP after some unsuccessful login attempts. This was easy to set, because fail2ban has already preconfigured action for this. However, I also wanted to permanently ban this IP if it it continues with failed login attempts. For this I've found custom made action config.

Configuration files are stored in /etc/fail2ban. General configuration is /etc/fail2ban/jail.conf, but this file might be overwritten in the future. To preserve customizations, create file jail.local and add your customization here. In my case I've set which IP addresses will be ignored and default backend systemd:
[DEFAULT]

ignoreip = 172.16.0.2/32
backend = systemd
Next step is to create custom configuration files in jail.d folder. First file is /etc/fail2ban/jail.d/sshd.conf, it handles temporary ban.
# fail2ban SSH
# block ssh after 3 unsuccessful login attempts for 10 minutes
[sshd]
enabled  = true
action   = iptables[chain=INPUT, protocol=tcp, port=22, name=sshd]
           mail[name=sshd, dest=example@gmail.com]
maxRetry = 3
findtime = 600
bantime  = 600
port     = 22
Action creates DROP rule in iptables after 3 unsuccessful login attempts for an IP or host in iptables, valid for 10 minutes (bantime). Findtime defines time frame in which fail2ban will count failed login attempts from logs, so if one IP has 3 incorrect login attempts in last 10 minutes, it will be banned.

Next configuration (/etc/fail2ban/jail.d/ssh-repeater.conf) is for permanently banning IP address after specified failed login attempts:
[ssh-repeater]
enabled  = true
filter   = sshd
action   = iptables-repeater[name=ssh]
           mail[name=ssh-repeater, dest=example@gmail.com]
logpath  = /var/log/fail2ban.log
maxretry = 6
findtime = 3600
bantime  = 3600
port     = 22
This will block IP after 6 unsuccessful logins during last hour (findtime). In this case, bantime is not effective, because IP's are stored in file and are permanently blocked. IP's are stored in /etc/fail2ban/ip.blocklist.ssh. Example content:
62.210.122.213        # fail2ban/2014-03-02 23:06:11: auto-add for repeat offender

Next step is to create action file for ssh-repeater in action.d folder. This action file is from above mentioned blog. /etc/fail2ban/action.d/iptables-repeater.conf:
# Fail2ban configuration file
#
# Author: Phil Hagen <phil@identityvector.com>
#

[Definition]

# Option:  actionstart
# Notes.:  command executed once at the start of Fail2Ban.
# Values:  CMD
#
actionstart = iptables -N fail2ban-repeat-<name>
              iptables -A fail2ban-repeat-<name> -j RETURN
              iptables -I INPUT -j fail2ban-repeat-<name>
              # 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-repeat-<name> 1 -s $IP -j DROP; done

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

# Option:  actioncheck
# Notes.:  command executed once before each actionban command
# Values:  CMD
#
actioncheck = iptables -n -L INPUT | grep -q fail2ban-repeat-<name>

# Option:  actionban
# Notes.:  command executed when banning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    <ip>  IP address
#          <failures>  number of failures
#          <time>  unix timestamp of the ban time
# Values:  CMD
#
actionban = iptables -I fail2ban-repeat-<name> 1 -s <ip> -j DROP
            # also put into the static file to re-populate after a restart
            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:    <ip>  IP address
#          <failures>  number of failures
#          <time>  unix timestamp of the ban time
# Values:  CMD
#
actionunban = /bin/true
# to remove IP from iptables: 
# iptables -D fail2ban-repeat-<name> -s <ip> -j DROP

[Init]

# Defaut name of the chain
#
name = repeat

Fail2ban will create few rules and in my case two new chains in iptables:
Chain INPUT (policy DROP)
target     prot opt source               destination
fail2ban-repeat-ssh  all  --  anywhere             anywhere
fail2ban-sshd  tcp  --  anywhere             anywhere             tcp dpt:EtherNet-IP-1
 
Chain fail2ban-repeat-ssh (1 references)
target     prot opt source               destination
DROP       all  --  mail.zobnetworks.com  anywhere
RETURN     all  --  anywhere             anywhere

Chain fail2ban-sshd (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere
As you can see in fail2ban-repeat-ssh chain, there is already one rule from ip.blocklist.ssh.

Basic commands for fail2ban-client:
fail2ban-client start sshd
fail2ban-client stop sshd
fail2ban-client reload sshd
fail2ban-client status sshd
fail2ban-client set sshd unbanip 172.16.0.4
 
fail2ban-client start ssh-repeater
fail2ban-client stop ssh-repeater
fail2ban-client reload ssh-repeater
fail2ban-client status ssh-repeater
NOTE: if you are unbanning IP that has been banned permanently by ssh-repeater, you need to remove corresponding entry from ip.blocklist.ssh file and remove rule from iptables: iptables -D fail2ban-repeat-ssh -s <ip> -j DROP.

TROUBLESHOOTING:
You can change loglevel in fail2ban.conf.
High CPU load (with systemd as backend): this is probably caused by some inconsistency in journal. Try run following command and then start fail2ban again:
journalctl --verify
Another possible reason is the size of logfiles. Move /var/log/journal/<journal folder> and restart journal: systemctl restart systemd-jounal.

3 comments:

  1. Our friend google searh brings me to your page ...
    I'm facing ssh password bruteforce attack from the same IP. Thanks for the script.

    ReplyDelete
  2. First of all, thaks for the tutorial, its very usefull and easy to use.

    If you want more info about the IP in your mail, here is the changes I made:

    [sshd]
    enabled = true
    action = iptables[chain=INPUT, protocol=tcp, port=22, name=sshd]
    sendmail-whois[name=sshd, dest=example@gmail.com]
    maxRetry = 3
    findtime = 600
    bantime = 600
    port = 22

    [ssh-repeater]
    enabled = true
    filter = sshd
    action = iptables-repeater[name=ssh]
    sendmail-whois[name=ssh-repeater, dest=example@gmail.com]
    logpath = /var/log/fail2ban.log
    maxretry = 6
    findtime = 3600
    bantime = 3600
    port = 22

    ReplyDelete