Ubuntu – Shell script to ban an IP

command lineconnectioniptablesscripts

Some of the IPs are opening thousands of connections of my server. I have a Ubuntu 14 server. I check total connections using following command:

netstat -an | grep tcp | awk '{print $5}' | cut -f 1 -d : | sort |
uniq -c | sort -n

Then I use following iptables rule to block the culprit IP.

iptables -I INPUT 1 -s x.x.x.x -j DROP

It works all fine and block the IP address. However, I cannot stay online 24/7 to monitor server. I was wondering if there is any Shell script I can use to do it automatically? For example, if an IP opens more than X number of connections at any time, it should be automatically get banned by above iptables rule.

Best Answer

First of all, don't reinvent the wheel. That's precisely what denyhosts is for:

   DenyHosts  is a python program that automatically blocks ssh attacks by
   adding entries to /etc/hosts.deny.  DenyHosts will  also  inform  Linux
   administrators  about  offending  hosts,  attacked users and suspicious
   logins.

As far as I know, denyhosts is only for ssh connections but there's also fail2ban that deals with pretty much anything:

   Fail2Ban consists of a client, server and configuration files to  limit
   brute force authentication attempts.

   The  server  program  fail2ban-server is responsible for monitoring log
   files and issuing ban/unban commands.  It  gets  configured  through  a
   simple  protocol  by fail2ban-client, which can also read configuration
   files and issue corresponding configuration commands to the server.

Both are available in the repositories:

sudo apt-get install denyhosts fail2ban

You could also script this, if you like. Something like:

#!/usr/bin/env sh
netstat -an | 
    awk -vmax=100 '/tcp/{split($5,a,":"); if(a[1] > 0 && a[1]!="0.0.0.0"){c[a[1]]++}}
    END{for(ip in c){if(c[ip]>max){print ip}}}' |
        while read ip; do iptables -I INPUT 1 -s "$ip" -j DROP; done

The awk will extract the IPs and count them and only print those that appear more than max times (here, -vmax=100, change it accordingly). The IPs are then fed to a while loop that runs the relevant iptables rule.

To run this 24/7, I would make a cronjob that runs the command above every minute or so. Add this line to /etc/crontab

* * * * * root /path/to/script.sh
Related Question