Blocking IP address that repeatedly blocked by fail2ban

Find IP address that repeatedly blocked by fail2ban:
# awk '($(NF-1) = /Ban/){print $NF}' /var/log/fail2ban.log | sort | uniq -c | sort -n
...
3 212.83.190.184
3 221.203.142.71
3 74.208.10.191
5 183.3.202.105
Note: the variable NF equals the number of fields in each row of the logfile. So $NF is the value of the last field. Add iptables rules to drop incoming packages from particular IP address
# iptables -I INPUT -s 183.3.202.105 -j DROP
or you just want to drop access to your sshd
# iptables -I INPUT -p tcp -s  221.203.142.71 --dport ssh -j DROP
You can write a bash script to find IP address
# vi awkfindipfail2ban.sh
#!/bin/bash
awk '($(NF-1) = /Ban/) { print $NF}' /var/log/fail2ban.log | sort | uniq -c | sort -n
Make it executable
# chmod 744 awkfindipfail2ban.sh
Run it
# ./awkfindipfail2ban.sh
Other way to search brute force attempt is search in authentication log file
# awk '/Failed password/ { print "Date: "$1" "$2" "$3"\tUsername: "$9"\t\tClient IP: "$11 }' /var/log/auth.log
You can also use grep
grep "$(date|awk '{print $2" "$3}')" /var/log/auth.log|grep -E '(BREAK-IN|Invalid user|Failed|refused|su|Illegal)'
 
For this case:
      1 104.255.67.202
      1 109.161.202.72
      1 115.79.56.178
      1 125.212.232.119
      1 193.201.227.10
      1 193.201.227.18
      1 193.201.227.200
      1 193.201.227.68
      1 195.154.51.132
      1 202.99.172.155
      1 222.186.21.74
      1 27.255.81.142
      1 42.112.249.111
      1 45.32.61.182
      1 5.79.205.171
      1 59.47.5.239
      1 74.208.46.187
      1 82.165.151.8
      2 222.186.21.143
 
You may see the brute force using 4 different IP (193.201.227./24). For this case you can block them all with this command
 
# iptables -I INPUT -p tcp -s  193.201.227.0/24 --dport ssh -j DROP
 
No worries, your users still able to use your other service such as www in case those IP above used by legitimate user.
 
 
As your iptables rules increasing, your server performance may degrade. You can move your blocking rules into ipset. 
 
  1. create your ipset rules for example mynetrules.
    # ipset create mynetrules hash:net
  2. populate your ipset rules
    # ipset add mynetrules 212.83.190.184
     
    # ipset add mynetrules 183.3.202.114
     
    # ipset add mynetrules 221.203.142.71
     
    # ipset add mynetrules 183.3.202.105

    # ipset add mynetrules 183.3.202.112
    # ipset add mynetrules [u18576666.onlinehome-server.com]
    # ipset add mynetrules 212.129.15.239

    # ipset add mynetrules 212.129.56.65 
    # ipset add mynetrules 222.186.21.143
     
    # ipset add mynetrules 193.201.227.0/24

    # ipset add mynetrules 125.88.177.111
    # ipset add mynetrules [u19026996.onlinehome-server.com] 
    # ipset add mynetrules 183.3.202.88
  3. add your ipset rules into first line in iptables rules
    # iptables -I INPUT -m set --match-set mynetrules src -j DROP
    or just to block access to your ssh
    # iptables -I INPUT -p tcp --dport 22 -m set --match-set mynetrules src -j DROP
    or you want to block multiple port
    # iptables -I INPUT -p tcp --match multiport --dports 80,443 -m set --match-set mynetrules src -j DROP
 
Now you may see your iptables more simple:
# iptables -L 
Chain INPUT (policy ACCEPT) target     prot opt source               destination DROP       all  --  anywhere             anywhere             match-set mynetrules src...
 
To list your ipset rules i.e. mynetrules
# ipset list mynetrules 
Name: mynetrules Type: hash:net Revision: 5 Header: family inet hashsize 1024 maxelem 65536 Size in memory: 17176 References: 1 Members: 183.3.202.88 183.3.202.114 193.201.227.0/24 ... 
Additional script to search IP banned at least twice: 
#!/bin/bash
echo "These IP banned at least twice"
awk '($(NF-1) = /Ban/) { print $NF}' /var/log/fail2ban.log | sort | uniq -c | {
  while read -r line1 line2
  do
    if [ "$line1" -ge 2 ]; then
      echo "$line1 $line2"
    fi
  done
}
echo "These IP range banned at least twice"
awk '($(NF-1) = /Ban/) { print $NF}' /var/log/fail2ban.log | awk 'BEGIN{FS="."} ; { printf("%s.%s.%s.0/24\n",$1,$2,$3)}' | sort | uniq -c | {
  while read -r line1 line2
  do
    if [ "$line1" -ge 2 ]; then
      echo "$line1 $line2"
    fi
  done
}
Interesting Command:
  • # awk '/authentication failure/ { print $NF }' /var/log/auth.log | sort | uniq -c
  • # awk '/root/ && /sshd/ { print $0 }' /var/log/auth.log 
References:
  • http://www.the-art-of-web.com/system/fail2ban-log/
  • http://stackoverflow.com/questions/22298623/echo-results-from-a-grep-search-in-shell-script 
  • http://unix.stackexchange.com/questions/3176/what-strings-should-i-look-for-in-var-log-auth-log