sum iptables counter rules

iptables -nvxL INPUT | awk '{n+=$1} END {print n}'
Advertisements

analyzes apache log and blocking url access 3 times in X minutes

block multiple URLs

#!/bin/bash
# analyzes apache log and blocking ip than access url 3 times in 2 minutes
# block only access to url not to all urls

# you can use | to separate multiple strings to block
URL_STRING_TO_BLOCK="insertPartOfUrl1Here|insertPartOfUrl2Here"

RANGE_TIME=$( date '+%H:%M' )

# make array with 2 past minutes using | separator. used as a separator field in the egrep regex 
for i in {1..2};do
  RANGE_TIME=${RANGE_TIME}\|$(date -d "-$i min" '+%H:%M:')
done

# list of ips with hits to the same url
IPs_LIST=$( egrep "$(date '+%d\/%b\/%Y:')($RANGE_TIME).*($URL_STRING_TO_BLOCK)" /var/log/httpd/access.log )

# group ips by number of hits to the same url
GROUP_BY_IPs=$( echo "$IPs_LIST" | cut -d' ' -f1 | sort | uniq -c )

# create iptables rule to block each ip that access url 3 times in N minutes than not starts with 192.168.0 range
for i in $( echo "$GROUP_BY_IPs" | awk '$1 >= 3 && $2 !~ "^192.168.0" {print $2}' );do
  /sbin/iptables -nvL | awk '{print $8}' | grep "^$i$" > /dev/null
  if [ $? -ne 0 ]; then
    for j in $( echo $URL_STRING_TO_BLOCK | sed 's/|/\n/g' ); do
      echo $( date '+%d/%m/%Y %R' ) "blocking ip: $i than access part of URL: $j" | tee -a /var/log/$( basename $0 ).log
      /sbin/iptables -A INPUT -s $i -p tcp -m tcp --dport 80 -m string --string "$j" --algo bm --to 65535 -m comment --comment "block IP than access this URL many times" -j DROP
    done
  fi
done

one liner code to blocking url access 3 times in 1 minute. (block only 1 url)

URL='insertUrlHere'; RANGE_TIME=$(date '+%H:%M'); for i in {1..1};do RANGE_TIME=${RANGE_TIME}\|$(date -d "-$i min" '+%H:%M:'); done; egrep "$(date '+%d\/%b\/%Y:')($RANGE_TIME).*$URL" /var/log/httpd/access.log | cut -d' ' -f1 | sort | uniq -c | awk '$1 >= 3 && $2 !~ "^192.168" {print $2}' | xargs -I% iptables -A INPUT -s % -p tcp -m tcp --dport 80 -m string --string "$URL" --algo bm --to 65535 -j DROP

install geoip iptables module debian 9

install the packages below

apt-get install xtables-addons-common xtables-addons-dkms libtext-csv-xs-perl

Execute this script

#!/bin/bash
set -euo pipefail

set +e
if ! dpkg -l xtables-addons-common >/dev/null ; then
        apt install xtables-addons-common
fi
if ! dpkg -l libtext-csv-xs-perl >/dev/null ; then
        apt install libtext-csv-xs-perl
fi
set -e

if [ ! -d /usr/share/xt_geoip ]; then
        mkdir /usr/share/xt_geoip
fi

geotmpdir=$(mktemp -d)
csv_files="${geotmpdir}/GeoIPCountryWhois.csv ${geotmpdir}/GeoIPv6.csv"
OLDPWD="${PWD}"
cd "${geotmpdir}"
/usr/lib/xtables-addons/xt_geoip_dl
/usr/lib/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip ${csv_files}
cd "${OLDPWD}"
rm -r "${geotmpdir}"
exit 0

to test

iptables -A FORWARD -m geoip --src-cc BR -j DROP