Bash script to parse Nginx logs and block bots

Sponsored

If you have a website as I do, inevitably, you are facing spam and bots trying to flood your machine, spoof, or hack it. My approach to addressing this was very straight-forward and even naive, but it did its job, and I am satisfied with the result.

The idea is to capture “prohibited keywords” and block source IP addresses by iptables.

#!/bin/bash

while true
  do grep "$(date +%d/%b/%Y:%H:%M)" /var/log/nginx/access.log |\
    awk -F ":" '$0 ~/chmod|shell_exec/ {print $1}'|\
    cut -d ' ' -f 1 | sort | uniq -c | sort -rnk1 |\
    while read count ip
      do 
        [ $count -ge 1 ] && echo $count $ip || exit 0 
      done
        while read count ip 
          do  
            [ $(/sbin/iptables -L -v -n | grep "$ip" | wc -l) -eq 0 ] &&\
            iptables -A INPUT -s $ip -j DROP &&  { echo "iptables -D INPUT -s $ip -j DROP" | at now +1 hour; } &&\
            echo "Blocking this IP for 1 hour since it attempted to hack the site $count times per minute: $ip"
          done                    
  sleep 61

While the script is simple and the logic is straightforward, let me put a few words for clarity. At first, you have to run this script in virtual terminal emulators like tmux or screen. Otherwise, you have to keep the ssh session to the remote machine open indefinitely.

Sure thing, you can daemonize the script and make it running on the background like any other system process. But I really wanted it to be simple, without unnecessary features.

The following part might look a bit confusing:

iptables -A INPUT -s $ip -j DROP &&  { echo "iptables -D INPUT -s $ip -j DROP" | at now +1 hour; }

However, it is very simple. We are blocking bot’s IP addresses via iptables and removing the blockage an hour later through “iptables -D” and scheduler at.

Be the first to comment

Leave a Reply

Your email address will not be published.


*