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.
yes, I wrote 2 (one restarts proftp), sadly my ftp server has just this second stopped logging IP's though, talk about bad timing! I'll figure it out... Anyhoo
Here's the blacklisting file, this is set as a cronjob and runs 5 minutes before my logs rotate
Code:
TOPHITS=`awk -F"[][]" 'BEGIN {MAXALLOWED=50}
($0 ~ /FTP session closed/) {
if (a[$4] > MAXALLOWED) {next;}
if ($4 != OLD) {a[$4] = 1;OLD = $4;}
else {a[$4]++;}
}
END {for (i in a) {if (a[i] > MAXALLOWED){print i;}}
}' /var/log/messages`
if [[ -n $TOPHITS ]]; then
for IP in $TOPHITS;
do
sed -i "78s/$/,$IP/" /opt/etc/proftpd.conf
done
/root/ftp restart
else
echo "No IP's meeting that threshold"
fi
I know assigning the variable like that looks a little sloppy but it seems to work ok.
Here's my starter script:
Code:
runningpid=`ps -ef | grep proftp | grep -v grep | awk '{print $2}'`
case $1 in
start)
if [ -n "$runningpid" ]; then
echo "Process running under pid: $runningpid"
else
/opt/sbin/proftpd --config /opt/etc/proftpd.conf
fi
;;
stop)
if [ -n "$runningpid" ]; then
echo "killing pid $runningpid"
kill $runningpid
else
echo "Process already stopped"
fi
;;
status)
if [ -n "$runningpid" ]; then
echo "Process running under pid: $runningpid"
else
echo "ProFTP is not running on the system"
fi
;;
restart)
if [ -n "$runningpid" ]; then
echo "killing $runningpid"
kill $runningpid
echo "restarting process"
/opt/sbin/proftpd --config /opt/etc/proftpd.conf
echo "new pid is `ps -ef | grep proftp | grep -v grep | awk '{print $2}'`"
else
echo "Starting process"
/opt/sbin/proftpd --config /opt/etc/proftpd.conf
echo "new pid is: $runningpid"
fi
;;
*)
echo "Syntax ftp start|stop|status|restart"
esac
It's basically a more advanced init script than the one that was provided with proftpd, I wrote it in like 15 minutes so althoguh I'm open to critism, you must realise this was someting wrote quickly (usually I'd have functions for start and stop for example and merge them into the restart and stop/start case statements).
TOPHITS=$(awk -F"[][]" -vmax=50 '/FTP session closed/{a[$4]++}END{for(i in a)if(a[i] > max)printf(",%s",i)}' /var/log/messages)
if [[ $TOPHITS ]]
then
sed -i "78s/$/$TOPHITS/" /opt/etc/proftpd.conf
/root/ftp restart
else
echo "No IP's meeting that threshold"
fi
Small improvement on startup script:
Code:
get_pid()
{
ps -ef | awk '/proftp/ && !/awk/{printf("%s ", $2)}'
}
runningpid=$(get_pid)
# and in case do
restart)
if [[ $runningpid ]]; then
echo "killing $runningpid"
kill $runningpid
echo "restarting process"
/opt/sbin/proftpd --config /opt/etc/proftpd.conf
echo "new pid is $(get_pid)"
else
echo "Starting process"
/opt/sbin/proftpd --config /opt/etc/proftpd.conf
echo "new pid is: $runningpid"
fi
;;
That is what I was looking for to curb the need of the for-loop. I tried
Code:
ORS=",";for(i in a)if(a[i] > max)print i)
But this meant a slight change on the format from a preceding to a trailing comma.
However, your script does not provide the same functionality as the script in the initial post. Your script counts the total number of hits by an IP.
It corresponds to
Here is another slight variation to include not consecutive (just for fun):
Code:
BEGIN{
FS="[][]"
MAXALLOWED=50
}
/FTP session closed/{
if ($4 != OLD && a[OLD] <= MAXALLOWED)
delete a[OLD]
a[$4]++
OLD = $4
}
END{
for (i in a)
if(a[i] > MAXALLOWED)
print i
Thanks for both suggestions I'll have a play with everything on this page and get optimum functionality. Also grail, thanks for the improved init script - adding the getpid as a function works 'properly' when listing the new pid ~(obviously before I needed to exit out of the ifstatement to get a DIFFERENT pid, and thus had to specifiy the pid by hand, adding it as a function works properly).
Can either of you clarify what you mean by consecutive hits and total number of hits? The idea was to list the IP which had hits greater than 50, the script crts provided does that successfully, but I don't really see the difference between consecutive and the total? Would this effect functionality?
My understanding of consecutive hit is one hit after another after another, and my idea of total is the ammount of times an IP has hit the box. After processing the two number should be the same as the time in which the hit occured is irrelevant when displaying the number of hits. I'd noticed specific IP's attempting to FTP to the server with usernames beginning with A (anonymous, administrator etc) followed by passwords which were all dictionary based - these were consecutive hits occuring roughly once every 25 seconds (from memory here...). But if one of these connection attempts had a legitimate hit inbetween the connection being opened and the password being specified, this wouldn't effect the totals? Or would it?
Yes there is a difference between consecutive and total. If you use crts' input from post #18, and look at the references to ip 110.9.129.72, it first appears and closes 4 times prior to a new
ip being hit. Then the same ip appears at the end of the file 2 more times.
So consecutively it 4 & 2, so if MAX=4 then neither would warrant being displayed.
However, as a total of 6 it would be displayed.
So for consecutive you can use crts' or my last solution.
If total, then my previous awk solution, from post #17, would be the way to go.
Got it, cheers grail. I need to review the logs properly but I suspect consecutive hits would make more sense, as it stands this brute force attack only took place once so I need to see how the code functions with both the total hits and total consecutive hits and compare this to my logs (sparce at the moment).
Cheers for all your effort guys, this will become useful to vast ammounts of people I'm sure
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.