LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Security (http://www.linuxquestions.org/questions/linux-security-4/)
-   -   Howto? threshold value for failed SSH comms' script (http://www.linuxquestions.org/questions/linux-security-4/howto-threshold-value-for-failed-ssh-comms-script-866346/)

Lantzvillian 03-03-2011 10:21 PM

Howto? threshold value for failed SSH comms' script
 
Hi all,

I was playing around with a script that seems to work relatively for my needs when SSH comms fail - AKA a user or someone attacking. This works...

But, how would I add a threshold value? lets say if there are 3 entries, then perform add the IP to iptables as a rule.


Code:

#!/bin/sh
# ------------------------------------
# FIREWALL SCRIPT
#
# March 1st, 2011
#
# Purpose:
# Add offending IP from failed SSH connections
# to the iptables (firewall) rules.
#
# ------------------------------------

## Vars:

TIMETHRESHOLD="10"

## Explanation:

# This program will match lines
# Illegal user (userid) from (host)
# Failed password for (userid) from (host) (...)
# and adds (host) to the iptables blacklist chain
# $blockchain

## Misc preparations:

rm -f hostfile
touch temphostfile

# Disabled IPs can be obtained from /etc/sysconfig/iptables
grep DROP /etc/sysconfig/iptables|awk '{print $5}' >temphostfile

# ------------------------ SSHD FAILURES -------------------------

grep Did /var/log/secure|awk '{print $12}' >>temphostfile

grep "Invalid user" /var/log/secure|awk '{print $10}' >>temphostfile

grep "Maximum login" /var/log/secure|awk '{print $7}'|sed 's/.*\[\(.*\)\])/\1/g' >>temphostfile

grep "Failed password for" /var/log/secure |awk '{print $11}' >>temphostfile

#
# ------------------ REDUCE IPS IN TMP FILE -------------------

size=`/usr/bin/wc temphostfile|awk '{print $1}'`
i=0
echo $(/usr/bin/wc temphostfile|awk '{print $1}')
echo $(cat temphostfile)

while test $i -lt $size
do
      us=`sed -n 1p temphostfile`
      sed /$us/d temphostfile >temphostfiles

      echo $us >>hostfile
      cp -f temphostfiles temphostfile
      size=`/usr/bin/wc temphostfile|awk '{print $1}'`
done

rm -f temphostfile temphostfiles temp0 temp

#
# ------------------ CREATE THE FIREWALL RULES--------------------------

size=`wc hostfile|awk '{print $1}'`
size=`expr $size + 1`
/sbin/iptables -F
i=1

while test $i -lt $size
do
        ip=`sed -n "$i"p hostfile`
        i=`expr $i + 1`
        /sbin/iptables -A INPUT -s $ip -j DROP
done


Lantzvillian 03-04-2011 12:44 AM

Ahh found annother way and modified it to work:

Code:

USERVAR=2

## Business logic

tail -1000 /var/log/secure | awk -v USERVAR=$USERVAR '/sshd/ && /Failed password for/ { if (/invalid user/) try[$13]++; else try[$11]++; }
END { for (h in try) if (try[h] > USERVAR) print h; }' |
while read ip
do
        # Check if IP is already blocked...
        /sbin/iptables -L -n | grep -x $ip > /dev/null
        if [ $? -eq 0 ] ; then
                # echo "Already denied ip: [$ip]" ;
                true
        else
                # Add a little logging entry
                logger -p authpriv.notice "*** Blocked SSH attempt from: $ip"
                /sbin/iptables -I INPUT -s $ip -j DROP
        fi
done

Posted a copy of it here: http://www.pacificsimplicity.ca/blog...lock-ip-script

Hangdog42 03-04-2011 08:31 AM

You could also just have iptables do the tracking and heavy lifting for you. I've got these rules monitoring my ssh port:

Code:

iptables -N AUTOBAN
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j AUTOBAN
iptables -A AUTOBAN -m recent --set --name SSH
iptables -A AUTOBAN -m recent --update --seconds 120 --hitcount 4 --name SSH -j DROP

Basically it blocks any SSH connection attempts after 4 in the last 120 seconds. The downside is that it is kind of a broad-spectrum approach in that there isn't any sort of a whitelist and depending on what kind of traffic you have, you may wind up blocking legitimate traffic for a bit. However, for my personal use, I've found this easier to maintain than the script-based approaches.

Reuti 03-05-2011 07:38 AM

Quote:

Originally Posted by Hangdog42 (Post 4278788)
Code:

iptables -N AUTOBAN
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j AUTOBAN
iptables -A AUTOBAN -m recent --set --name SSH
iptables -A AUTOBAN -m recent --update --seconds 120 --hitcount 4 --name SSH -j DROP


Yes, I use a similar rule, but before the last line you could test whether the traffic originated from a well known addres and just return from the script before counting the access.


All times are GMT -5. The time now is 03:46 PM.