ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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
- 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?
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.