8

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.

  • 6
    Have you looked to see if fail2ban meets your needs? – John1024 Oct 9 '15 at 22:26
  • Excuse my limited knowledge. Isn't fail2ban for ssh authentication? I am not sure to use it on port 80. In addition, my server is a chat-server, so a user can try to connect/ping multiple times. In this case, fail2ban would create many false-positive alarms and ban legitimate traffic. Any thought? – user3404047 Oct 10 '15 at 1:52
10

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
  • Thanks terdon for a precise answer. AFAIK, fail2ban is for ssh authentication. All the connections are being opened on port 80. I will explore if I can use fail2ban on port 80. For the custom script, how could I run it 24/7 in the background? screen command? Or install cron? BTW. I am using server as a chat-server so a person can ping many times (or open multiple connections) so I might go for the custom script that you provided. – user3404047 Oct 10 '15 at 1:50
  • 2
    @user3404047 you could run it as a cronjob, yes. See updated answer. However, fail2ban is not only for ssh. It also works fine for port 80. See, for example here, here and here. – terdon Oct 10 '15 at 9:21
1

A possible alternative option is to identify and deal with the problem IP addresses all within the iptables rule set, using the recent module. The challenge with this method is the default hitcount limit of 20, so one needs to either deviate from the defaults or create higher level carry counters to achieve a higher hitcount trigger point.

The below example is from my iptables rule set, and will ban an ip address for just over 1 day if it makes 80 new TCP connections on port 80 in less than 12 minutes. Once on the bad guy list, any attempt to connect will reset the 1 day counter to 0. This method could go to a maximum 400 hits before expansion to another carry would be required (and I have tested another carry chain). Note that the code as posted has the infrastructure to be used to only ban for a long time upon multiple shorter time triggers. Currently, I have it set to just ban for a long time upon the first trigger.

#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in4
#
# A NEW Connection on port 80 part 4.
#
# multiple hits on the banned list means you get a one day ban.
# (I re-load the firewall rule set often, so going longer makes
# little sense.)
#
# Custom tables must exist before being referenced, hence the order
# of these sub-toutines.
#
# Place holder routine, but tested. Logs if a day ban would have
# been activated.
#
$IPTABLES -N http-new-in4
#$IPTABLES -A http-new-in4 -m recent --set --name HTTP_BAN_DAY

$IPTABLES -A http-new-in4 -j LOG --log-prefix "DAY80:" --log-level info
$IPTABLES -A http-new-in4 -j DROP

#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in3
#
# A NEW Connection on port 80 part 3.
#
# carry forward to the actual banned list:
# Increment this count. Leave the previous count.
#
# Custom tables must exist before being referenced, hence the order
# of these sub-toutines.
#
$IPTABLES -N http-new-in3
$IPTABLES -A http-new-in3 -m recent --remove --name HTTP_02
$IPTABLES -A http-new-in3 -m recent --update --hitcount 1 --seconds 86400 --name HTTP_BAN -j http-new-in4
$IPTABLES -A http-new-in3 -m recent --set --name HTTP_BAN

$IPTABLES -A http-new-in3 -j LOG --log-prefix "BAN80:" --log-level info
$IPTABLES -A http-new-in3 -j DROP

#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in2
#
# A NEW Connection on port 80 part 2.
#
# carry forward from previous max new connections per unit time:
# Increment this count and clear the lesser significant count.
#
$IPTABLES -N http-new-in2
$IPTABLES -A http-new-in2 -m recent --remove --name HTTP_01
$IPTABLES -A http-new-in2 -m recent --update --hitcount 3 --seconds 720 --name HTTP_02 -j http-new-in3
$IPTABLES -A http-new-in2 -m recent --set --name HTTP_02

$IPTABLES -A http-new-in2 -j LOG --log-prefix "CARRY80:" --log-level info
$IPTABLES -A http-new-in2 -j ACCEPT

#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in
#
# A NEW Connection on port 80:
#
$IPTABLES -N http-new-in

echo Allowing EXTERNAL access to the WWW server

# . check the static blacklist.
#
# http related
$IPTABLES -A http-new-in -i $EXTIF -s 5.248.83.0/24 -j DROP
... delete a bunch on entries ...
$IPTABLES -A http-new-in -i $EXTIF -s 195.211.152.0/22 -j DROP
$IPTABLES -A http-new-in -i $EXTIF -s 198.27.126.38 -j DROP

# . check the dynamic banned list
#
# The 1 Hour banned list (bumped to more than a day):
$IPTABLES -A http-new-in -m recent --update --seconds 90000 --name HTTP_BAN --rsource -j LOG --log-prefix "LIM80:" --log-level info
$IPTABLES -A http-new-in -m recent --update --seconds 90000 --name HTTP_BAN --rsource -j DROP

# A generic log entry. Usually only during degugging
#
#$IPTABLES -A http-new-in -j LOG --log-prefix "NEW80ALL:" --log-level info

# Dynamic Badguy List. Least significant hit counter.  Detect and DROP Bad IPs that do excessive connections to port 80.
#
$IPTABLES -A http-new-in -m recent --update --hitcount 20 --seconds 240 --name HTTP_01 -j http-new-in2
$IPTABLES -A http-new-in -m recent --set --name HTTP_01

$IPTABLES -A http-new-in -j LOG --log-prefix "NEW80:" --log-level info
$IPTABLES -A http-new-in -j ACCEPT

... a bunch of stuff not included here

# Allow any related traffic coming back to the server in.
#
#
$IPTABLES -A INPUT -i $EXTIF -s $UNIVERSE -d $EXTIP -m state --state ESTABLISHED,RELATED -j ACCEPT

... the above is needed before the below ...

# If required, go to NEW HTTP connection sub-routine
#
$IPTABLES -A INPUT -i $EXTIF -m state --state NEW -p tcp -s $UNIVERSE -d $EXTIP --dport 80 -j http-new-in

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.