Fail2ban: Unterschied zwischen den Versionen

Aus wiki.frank-wulf.de
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 54: Zeile 54:


The following shell script '''''fwfail2ban''''' moves IP addresses from the iptables rules to an IP set:
The following shell script '''''fwfail2ban''''' moves IP addresses from the iptables rules to an IP set:
<source lang="bash" line>#!/bin/bash
<syntaxhighlight lang="bash" line>
#!/bin/bash
#
#
# Author:  Frank Wulf
# Author:  Frank Wulf
Zeile 141: Zeile 142:
# Save iptables to enable restoring after reboot, the entries created
# Save iptables to enable restoring after reboot, the entries created
# by fail2ban are filtered, those will be restored by fail2ban itself.
# by fail2ban are filtered, those will be restored by fail2ban itself.
iptables-save | grep -v "^\-A.*f2b-sshd" >/etc/iptables/rules.v4</source>
iptables-save | grep -v "^\-A.*f2b-sshd" >/etc/iptables/rules.v4
</syntaxhighlight>


The script runs once a day via cron. So during the day fail2ban bans IP addresses with iptables rules which are then moved at 0:00 o'clock to an IP set.
The script runs once a day via cron. So during the day fail2ban bans IP addresses with iptables rules which are then moved at 0:00 o'clock to an IP set.


By default both iptables rules and IP sets are hold in the memory and get lost during a reboot. Therefore the script has a mechanism to save the data which then can be automatically restored after a reboot.
By default both iptables rules and IP sets are hold in the memory and get lost during a reboot. Therefore the script has a mechanism to save the data which then can be automatically restored after a reboot.

Version vom 3. Oktober 2017, 20:56 Uhr

Fail2Ban Installation from GitHub (EN)

In case an existing Fail2Ban server is running:

sudo service fail2ban stop

Download version 0.10 from GitHub:

wget https://github.com/fail2ban/fail2ban/archive/0.10.0.tar.gz -O fail2ban-0.10.0.tar.gz

Unpack and install:

sudo tar -zxpvf fail2ban-0.10.0.tar.gz
cd fail2ban-0.10.0
sudo python setup.py install

This will install Fail2Ban into the python library directory. The executable scripts are placed into /usr/local/bin and configuration under /etc/fail2ban.


Enable fail2ban as an automatic service:

sudo cp files/debian-initd /etc/init.d/fail2ban
sudo update-rc.d fail2ban defaults
sudo service fail2ban start

Using IP sets instead of iptables chains (EN)

By default Fail2Ban uses iptables chains to block IP addresses.

Example:

iptables -S

Result:

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N f2b-sshd
-A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd
-A INPUT -m set --match-set fail2ban-ssh src -j DROP
-A FORWARD -m set --match-set fail2ban-ssh src -j DROP
-A f2b-sshd -s 120.52.56.124/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s 116.193.161.242/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s 14.215.237.205/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s 118.244.238.18/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s 155.133.82.12/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s 49.4.6.132/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s 118.244.206.22/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s 61.132.29.162/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s 192.160.102.169/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s 162.247.72.213/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s 149.56.223.241/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s 27.255.79.82/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s 211.104.171.220/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s 187.252.208.82/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s 116.6.49.126/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -j RETURN

Since Linux Kernel 2.6 there is an option to use so-called IP sets to hold big amount of IP addresses in the memory. This technique uses hashtables to store and search IP adresses and is therefore much more efficient than parsing sequentially through the iptables rules.

The following shell script fwfail2ban moves IP addresses from the iptables rules to an IP set:

#!/bin/bash
#
# Author:  Frank Wulf
# Version: 1.0 (2017-10-03)
#
# This program moves iptables entries created by fail2ban to
# an IP set in the Linux Kernel. Advantage is that ipset uses
# a hashtable to store/fetch IP addresses and thus the IP lookup
# is much more efficient and faster than sequentially parsing
# the iptables rules.
#
# Version history:
# 1.0   2017-10-03   Initial release
#

# Get program name to be used as prefix
pfx=$(basename $0)

# Temporary files
chn=/tmp/$pfx.chn
out=/tmp/$pfx.out

# Get fail2ban database
db=`confget -f /etc/fail2ban/fail2ban.conf dbfile`

# Get all chains created by fail2ban
iptables -S|grep "^\-A f2b-"|awk '{print $2}'|sed "s/f2b-//"|sort -u >$chn

while read chain; do

  # Build the ipset if not exist
  ipset -exist create $pfx-$chain hash:ip timeout 0

  # Build the iptables rules to use ipset if not exist
  iptables -C INPUT -m set --match-set $pfx-$chain src -j DROP 1>/dev/null 2>&1
  if [ $? -ne 0 ]; then
    iptables -I INPUT -m set --match-set $pfx-$chain src -j DROP
  fi
  iptables -C FORWARD -m set --match-set $pfx-$chain src -j DROP 1>/dev/null 2>&1
  if [ $? -ne 0 ]; then
    iptables -I FORWARD -m set --match-set $pfx-$chain src -j DROP
  fi

  # Get banned IP addresses from iptables
  iptables -L f2b-$chain -v -n|grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'|awk '{print $8}'|grep -v '0\.0\.0\.0' >$out

  # Get bantime from fail2ban configuration
  bantime=`confget -f /etc/fail2ban/jail.local -s $chain bantime`

  while read ipaddr; do
    sw_ipset=1
    # If bantime is not persistent then the timeout for ipset needs to be
    # adjusted depending on the time when fail2ban has banned the IP address.
    if [ "$bantime" == "" -o "$bantime" == "-1" ]; then
      timeout=0
    else
      timeofban=`sqlite3 -batch $db "SELECT timeofban FROM bans WHERE jail = '$chain' AND ip = '$ipaddr' LIMIT 1"`
      timeout=$(($bantime - (`date +%s` - $timeofban)))
      if [ $timeout -le 0 ]; then
        # Bantime has exceeded (should happen only if fail2ban is unbanning an IP address
        # right during the runtime of this program).
        sw_ipset=0
      fi
    fi
    if [ $sw_ipset -eq 1 ]; then
      # Add IP address to ipset
      ipset add $pfx-$chain $ipaddr timeout $timeout 1>/dev/null 2>&1
      # Remove IP address from fail2ban database, otherwise it would be restored
      # with next fail2ban start
      sqlite3 -batch $db "DELETE FROM bans WHERE jail = '$chain' AND ip = '$ipaddr'" 1>/dev/null 2>&1
    fi
  done <$out

  # Flush all rules in this chain created by fail2ban
  iptables -F f2b-$chain

done <$chn

# Remove temporary files
rm $out 1>/dev/null 2>&1
rm $chn 1>/dev/null 2>&1

# Save iptables and IP set to enable restoring after reboot
ipset save -f /etc/iptables/rules.ipset

# Save iptables to enable restoring after reboot, the entries created
# by fail2ban are filtered, those will be restored by fail2ban itself.
iptables-save | grep -v "^\-A.*f2b-sshd" >/etc/iptables/rules.v4

The script runs once a day via cron. So during the day fail2ban bans IP addresses with iptables rules which are then moved at 0:00 o'clock to an IP set.

By default both iptables rules and IP sets are hold in the memory and get lost during a reboot. Therefore the script has a mechanism to save the data which then can be automatically restored after a reboot.