2

I want to filter and block failed attempt to access my proftp server. Here is an example line from the /var/log/secure file:

Jan  2 18:38:25 server1 proftpd[17847]: spy1.XYZ.com (93.218.93.95[93.218.93.95]) - Maximum login attempts (3) exceeded  

There are several lines like this. I would like to block any attempts like this from any IP twice. Here's a script I'm trying to run to block those IPs.

tail -1000 /var/log/secure | awk '/proftpd/ && /Maximum login/ { if (/attempts/) try[$7]++; else try[$11]++; }
END { for (h in try) if (try[h] > 4) print h; }' |
while read ip
do

    /sbin/iptables -L -n | grep $ip > /dev/null
    if [ $? -eq 0 ] ; then
        # echo "already denied ip: [$ip]" ;
        true
    else
        logger -p authpriv.notice "*** Blocking ProFTPD attempt from: $ip"
        /sbin/iptables -I INPUT -s $ip -j DROP
    fi
done

how can I select the IP with "awk". with the current script it's selecting "(93.218.93.95[93.218.93.95])" this line completely. But i only want to select the IP.

Dennis Williamson
  • 62,149
  • 16
  • 116
  • 151
Minhaj
  • 177
  • 4
  • 14
  • You should think about using something like syslog-ng for logging. That way you can set up a separate log sink that takes the proftp messages and sends them to a flow-controlled pipe instead of to a file. That pipe then feeds into your processing script. That way you don't run the risk of missing entries like you do when using a cronjob to read the last 1000 lines of the file in your awk script. – Phil Hollenback Jan 07 '11 at 22:58

3 Answers3

3

You could also look at something like Fail2Ban which does have example setups for ProFTPd.

Niall Donegan
  • 3,869
  • 20
  • 17
0

If you're using GNU awk (gawk) you can use a regex for the field separator.

$ echo 'Jan  2 18:38:25 server1 proftpd[17847]: spy1.XYZ.com (93.218.93.95[93.218.93.95]) - Maximum login attempts (3) exceeded' \
  | awk -F'\\[|]' '{print $4}'
93.218.93.95
Dennis Williamson
  • 62,149
  • 16
  • 116
  • 151
  • Thanks for your feedback Dennis. Speaking truth, i'm novice to awk. Could you please help on, how can i use regx in my current script. You've done echo of the whole line, but i want awk to search last 1000 line, look for "maximum login attempts" and give the ip to iptables to block. I'm running another script like this which is blocking any failed ssh attempts. that one working fine because for ssh failed attempt the ip is in simple format in /var/log/secure file. – Minhaj Jan 08 '11 at 12:10
  • @Saif: I simply echoed the example record as a demonstration. The intent is that you should be able to drop `-F'\\[|]'` into your existing command (you may need to adjust your field numbers). The example log record you show seems to match field `$7` in your command (and `$4` in mine). You don't show an example record that fits the scenario of your field `$11` so I can't say for sure exactly how your command may need to be adjusted. If you edit your question to show the second type, I may be able to be more specific. – Dennis Williamson Jan 08 '11 at 14:47
  • Thanks a lot man :) I got this working. It's blocking failed proftpd attempt The script looks like this finally: – Minhaj Jan 08 '11 at 18:42
  • tail -1000 /var/log/secure | awk '/proftpd/ && /Maximum login attempts/' | awk -F "[][]" '{print $(NF-1)}' – Minhaj Jan 08 '11 at 18:49
  • @Saif: You shouldn't need to run awk twice. If you found my answer helpful, please mark it as accepted. – Dennis Williamson Jan 08 '11 at 19:21
0
tail -1000 /var/log/secure | awk '/proftpd/ && /Maximum login attempts/' | awk -F "[][]" '{print $(NF-1)}' |
while read ip
do
    # note: check if IP is already blocked...
    /sbin/iptables -L -n | grep $ip > /dev/null
    if [ $? -eq 0 ] ; then
        # echo "already denied ip: [$ip]" ;
        true
    else
        # echo "Subject: denying ip: $ip" | /usr/sbin/sendmail pager@xyz.com
        logger -p authpriv.notice "*** Blocking ProFTPD attempt from: $ip"
        /sbin/iptables -I INPUT -s $ip -j DROP
    fi
done
Minhaj
  • 177
  • 4
  • 14