LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-07-2013, 06:03 AM   #1
/dev/random
Member
 
Registered: Aug 2012
Location: Ontario, Canada
Distribution: Slackware 14.2, LFS-current, NetBSD 6.1.3, OpenIndiana
Posts: 319

Rep: Reputation: 112Reputation: 112
Bash script to block SSH access...


Hey guys, I was wondering if you could help me finish this script.

My script finds the number of failed entries in /var/log/secure* grabs the IP address then compares it to iptables -L and if the number of failed attempts is greater then 5 it will add a rule to drop them if one doesn't exist.... but now I want to add time into the mix...

I want to take the entries I have and compare the time they attempted to login, if they have tried to log in 5 times in less then 60 seconds black_list them.

Here is my basic loop

Code:
#!/bin/sh

IPTABLES=/sbin/iptables
TMPFILE=/tmp/gotcha.tmp
LOGGER=/var/log/gotcha.log
LOGFILES=/var/log/secure*

if [ "$(id -u)" != "0" ]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi

main() {
# Check the age of the file by comaping the inode number.
inode_check=$(stat -c '%i' /var/log/secure |cut -f2 -d " " |cut -f1 -d ".")
current_inode=$inode_check

grep -E "sshd.+Failed" $LOGFILES |grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' |sort | uniq -c > $TMPFILE 
# If the inode number changes, reread the data
if [ $current_inode != $inode_check ]; then
        echo "Log has been rotated while data was read, re-reading"
        rm -rf $TMPFILE
        grep -E "sshd.+Failed" $LOGFILES |grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' |sort | uniq -c > $TMPFILE
fi

exec < $TMPFILE

IPTABCHK=$(iptables -L |grep DROP |cut -f3 -d "-" |cut -d " " -f3)
while read COUNT IPADDR ; do

        if [ "$IPADDR" != "$IPTABCHK" ]; then
                if [ "$COUNT" -ge "$N_FAIL" ]; then
                        $IPTABLES -A INPUT -s $IPADDR -j DROP
                        echo "$IPADDR ($COUNT failures) added to the block list" >> $LOGGER
                fi
        fi
done

rm -rf $TMPFILE
}


usage
 
Old 12-07-2013, 06:47 AM   #2
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
- Don't use predictable temporary file names ('man mktemp'),
- use ipset (if you can) instead of the iptables filter table INPUT chain,
- use grep efficiently, for example with '(zgrep filez; grep file) | doSomething;',
- store already seen / blocked IP addresses for efficiency reasons (if you're using ipset they're already in the set, else an sqlite3 database is quite fast),
- "5 times in less then 60 seconds" means you won't block slow scanners,
- but most importantly you're reinventing the wheel: see fail2ban!
Probably not the comments you were looking for but valid comments nonetheless.

As for your question: try storing per IP epoch and counter?
 
Old 12-07-2013, 09:00 AM   #3
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by unSpawn View Post
- but most importantly you're reinventing the wheel: see fail2ban!
Agreed. Another tool available is denyhosts.
 
Old 12-07-2013, 02:37 PM   #4
/dev/random
Member
 
Registered: Aug 2012
Location: Ontario, Canada
Distribution: Slackware 14.2, LFS-current, NetBSD 6.1.3, OpenIndiana
Posts: 319

Original Poster
Rep: Reputation: 112Reputation: 112
It's not really for production guys, its so I can learn how it works, its only for my educational purposes only.
 
Old 12-07-2013, 03:08 PM   #5
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
FWIW I'm not seeing you respond to comments in a detailed way nor do I see any ideas / (pseudo) code how you intend to implement a counter?
 
Old 12-07-2013, 03:51 PM   #6
/dev/random
Member
 
Registered: Aug 2012
Location: Ontario, Canada
Distribution: Slackware 14.2, LFS-current, NetBSD 6.1.3, OpenIndiana
Posts: 319

Original Poster
Rep: Reputation: 112Reputation: 112
Well I had an idea of doing this

Code:
while read p; do
        ATTACKER=$(echo $p | cut -f2 -d " ")
        ATTACK_TIME=$(grep $ATTACKER $LOGFILES| sed -e "s/ \+ / /g" |grep -E "sshd.+Failed"|cut -f3 -d " ")
        
done < $TMPFILE
this will get me something that will look like this:
10.0.0.3 04:45:21 04:45:23 04:45:24
10.0.0.4 04:47:02 04:47:03 04:47:04
192.168.89.4 08:24:37

I was hoping on storing the times in an array then some how comparing them and if they are below xxx time then block the ip, but I see multiple problems, the list this generates is not set, meaning it will not always be 3 sets of time, could be 5 times I need to compare to see if they are a certain time apart.
 
Old 12-08-2013, 05:15 AM   #7
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
Use epoch, that's easier to store (int) and compare (numerically):
Code:
grep -iE "sshd.*(failed|refused)" logfile 2>/dev/null | awk '{print $1, $2, $3, $NF}' 2>/dev/null | while read LINE; do
 LINE=(${LINE}); EPOCH=$(date --date="${LINE[0]} ${LINE[1]} ${LINE[2]}" +%s 2>/dev/null); IP=${LINE[3]}
 # ..
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
SSH connection from BASH script stops further BASH script commands tardis1 Linux - Newbie 3 12-06-2010 08:56 AM
How to block a specific user to run SSH and leave him the access to FTP ? frenchn00b Linux - General 3 06-19-2010 11:18 PM
LXer: How to: Restrict Users to SCP and SFTP and Block SSH Shell Access with rssh LXer Syndicated Linux News 0 01-02-2008 12:00 PM
LXer: How to: Restrict Users to SCP and SFTP and Block SSH Shell Access with rssh LXer Syndicated Linux News 0 01-02-2008 10:00 AM
how to close 'else' statement block in bash script servnov Linux - General 9 11-12-2004 03:53 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:24 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration