Home > Back-end >  Block IPs that requested more than N times per minute from a log file
Block IPs that requested more than N times per minute from a log file

Time:07-15

I want to block IPs that requested more than N times/min using iptables .
I've sorted the log file using this script:
cat $log_path | awk '{print $1, $4}' | sort -n -k 1,4 | sed "s/\[//g"

10.200.3.120 20/May/2021:21:05:04
10.200.3.120 20/May/2021:21:05:17
10.200.3.120 20/May/2021:21:05:18
10.200.3.120 20/May/2021:21:05:19
10.200.3.120 20/May/2021:21:05:20
10.200.3.120 20/May/2021:22:05:39
104.131.19.181 20/May/2021:19:05:31
107.23.7.76 20/May/2021:20:05:16
119.252.76.162 20/May/2021:22:05:00
119.252.76.162 20/May/2021:22:05:01
119.252.76.162 20/May/2021:22:05:01
119.252.76.162 20/May/2021:22:05:04
119.252.76.162 20/May/2021:22:05:04
119.252.76.162 20/May/2021:21:05:10
119.252.76.162 20/May/2021:21:05:44
⋮

In the example log above, two IPs requested more than 4 times in a minute (10.200.3.120, 119.252.76.162) and they should be blocked.
How can I get the number of requests in a time interval for each IP and block those IPs?

CodePudding user response:

You can try this solution:

awk '
{
   gsub(/\[|:[0-9] $/, "", $4)
     fq[$4,$1]
}
END {
   for (i in fq)
      if (fq[i] >= 4) {
         sub(".*" SUBSEP, "", i)
         print "iptables -A INPUT -s", i, "-j DROP"
      }
}' "$log_path" | sh

Here:

  • gsub function strips starting [ and seconds value from timestamp
  • fq[$4,$1] increments array element fq by 1 where each element is composite key $4,$1 i.e. $4 SUBSEP $1 string
  • In the END block we loop through fq array. When fq[i] >= 4 we remove starting text followed by SUBSEP from array index to leave only IP.
  • Finally we print full iptables command line using the ip we just extracted
  • Finally we pipe awk output to sh to run all commands

CodePudding user response:

You can block the ip like this :

iptables -A INPUT -s <ip-address-to-block> -j DROP

Adapt your bash script to use this command whenever you see an ip requesting more than you want. The idea is to read your log file with a given frequency and parse the number each ip appears. If it appears more than you want, you drop it.

To unblock the ip, you can use this command:

iptables -D INPUT -s <ip-address-to-unblock> -j DROP
  • Related