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 timestampfq[$4,$1]
increments array elementfq
by 1 where each element is composite key$4,$1
i.e.$4 SUBSEP $1
string- In the
END
block we loop throughfq
array. Whenfq[i] >= 4
we remove starting text followed by SUBSEP from array index to leave onlyIP
. - Finally we print full
iptables
command line using theip
we just extracted - Finally we pipe
awk
output tosh
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