Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 May 2010 09:55:10 -0300 (ADT)
From:      "A. Wright" <andrew@qemg.org>
To:        =?ISO-8859-15?Q?Bal=E1zs_M=E1t=E9ffy?= <repcsike@gmail.com>
Cc:        "freebsd-questions@freebsd.org" <freebsd-questions@freebsd.org>
Subject:   Re: pf suggestions for paced attack
Message-ID:  <alpine.BSF.2.00.1005040949560.1908@qemg.org>
In-Reply-To: <s2nc4b701071005030946yfd431bcfl37bfc7df2402f338@mail.gmail.com>
References:  <20100503144110.GA14402@elwood.starfire.mn.org> <4BDEF9E4.9020806@infracaninophile.co.uk> <20100503163933.GA15599@elwood.starfire.mn.org> <s2nc4b701071005030946yfd431bcfl37bfc7df2402f338@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.

--142510029-1802741886-1272977710=:1908
Content-Type: TEXT/PLAIN; charset=iso-8859-1; format=flowed
Content-Transfer-Encoding: QUOTED-PRINTABLE


I wrote:
>> If anyone is interested, I can send (or I suppose post) the scripts.

Bal=E1zs M=E1t=E9ffy wrote:

> Would you be so kind to share those scripts?

No problem; the scripts are below.

I run them both in /usr/local/bin

Note the usual caveats about running scripts as root;
some squashing of problems is done by setting PATH to
the empty string in the scripts and using the fully
qualified path to all executables.

I run /usr/local/bin/authlog_watcher in the background from
/etc/rc.d; I then have a rule:
  =09block return log quick on $EXT_IF from { <attackers> } to any
in my /etc/pf.conf to make the actual filtering happen.

As you can see, the entire thing is quite simple -- the first
script simply is a loop fed from the auth.log file (note -F
to resync after log rotation).  The second script is triggered
by the first when there is any activity of interest, and its
purpose is to examine the log (within a recent date range)
and count whether there are too many attempts.

I hope this helps out.

Andrew.

---- 8< --- authlog_watcher --- 8< ------------------------------
#!/bin/sh --

#
# Trigger our attack filtering script when relevant authlog
# activity occurs
#
# $Id: authlog_watcher 118 2010-05-03 16:46:55Z andrew $
#

PATH=3D""

/usr/bin/tail -F /var/log/auth.log | {
  =09while read line
  =09do
  =09=09sshd_test=3D`/bin/expr "${line}" : ".*sshd.*"`
  =09=09if [ ${sshd_test} -gt 0 ]
  =09=09then
  =09=09=09inv_test=3D`/bin/expr "${line}" : ".*invalid.*"`
  =09=09=09fail_test=3D`/bin/expr "${line}" : ".*Failed.*"`
  =09=09=09err_test=3D`/bin/expr "${line}" : ".*error.*"`
  =09=09=09if [ ${err_test} -gt 0 \
  =09=09=09=09-o ${err_test} -gt 0 \
  =09=09=09=09-o ${fail_test} -gt 0 ]
  =09=09=09then
  =09=09=09=09/bin/sh /usr/local/bin/filter-current-attackers
  =09=09=09fi
  =09=09fi
  =09done
}

---- 8< --- filter-current-attackers --- 8< ----------------------
#!/bin/sh --

#
# Invoked by the authlog_watcher script when activity involving
# failed login occurs.  This script parses the auth.log file
# and for any lines that indicate kiddies, add them to the
# "attackers" table used/managed by pf to filter connections.
#
# $Id: filter-current-attackers 118 2010-05-03 16:46:55Z andrew $
#

PATH=3D""

TAG=3D"current-attackers"
RAWLIST=3D"/tmp/${TAG}.$$.raw"
IPLIST_RAW=3D"/tmp/${TAG}.$$.IPlist.raw"
IPLIST_UNIQ=3D"/tmp/${TAG}.$$.IPlist.uniq"
TMP=3D"/tmp/${TAG}.$$.tmp"

LOG=3D"/var/log"
ATTACKERS=3D"/etc/attackers"

umask 077

trap "echo 'Cleanup' ; rm -f ${IPLIST_UNIQ} ${IPLIST_RAW} ${RAWLIST} ${TMP}=
 ; exit 1" 2 3 15

/usr/bin/touch /tmp/filter-current-attackers.timestamp

{
  =09/usr/bin/find ${LOG} -name 'auth.log.*' -mtime -2 | \
  =09=09/usr/bin/sort -t. -r -n -k 2,2 | \
  =09=09while read f
  =09=09do
  =09=09=09case $f in
  =09=09=09*.gz)   /usr/bin/zcat -f $f | /usr/bin/tail +2;;
  =09=09=09*.bz2)  /usr/bin/bzcat -f $f | /usr/bin/tail +2;;
  =09=09=09esac
  =09=09done
  =09=09[ -f ${LOG}/auth.log ] && /bin/cat $LOG/auth.log | /usr/bin/tail +2
} | /usr/bin/grep sshd > ${RAWLIST}

> ${IPLIST_RAW}

/bin/cat ${RAWLIST} | /usr/bin/grep "Invalid" \
  =09=09| /usr/bin/sed -e 's/.* //' | /usr/bin/awk '{print $1;}' > ${IPLIST=
_RAW}

/bin/cat ${RAWLIST} | /usr/bin/grep "POSSIBLE BREAK-IN" \
  =09| /usr/bin/sed -e 's:\(.*\)\([ \[]\)\([0-9]*[.][0-9]*[.][0-9]*[.][0-9]=
*\)\(.*\):\3:' \
  =09>> ${IPLIST_RAW}

/usr/bin/sort -u ${IPLIST_RAW} > ${IPLIST_UNIQ}

{
  =09while read IP
  =09do
  =09=09if [ `/bin/expr "${IP}" : "[0-9]*[.][0-9]*[.][0-9]*[.][0-9]*"` -eq =
0 ]
  =09=09then
  =09=09=09echo "  Invalid IP format : [${IP}]"
  =09=09=09continue
  =09=09fi

  =09=09# Explicitly avoid adding any machine on campus to the list
#=09=09if [ `/bin/expr "${IP}" : "138[.]73[.]*"` -gt 0 ] # MtA
#=09=09then
#=09=09=09continue
#=09=09fi


  =09=09# check that there are at least 10 instances,
  =09=09# to avoid locking ourselves out on a Thumbsday
  =09=09/usr/bin/grep ${IP} ${IPLIST_RAW} > ${TMP}
  =09=09LINECOUNT=3D`/usr/bin/wc ${TMP} | /usr/bin/awk '{print $1;}'`

  =09=09if [ ${LINECOUNT} -gt 10 ]
  =09=09then
  =09=09=09if
  =09=09=09=09#pfctl -q -t attackers -T test ${IP}
  =09=09=09=09/usr/bin/grep ${IP} ${ATTACKERS} > /dev/null
  =09=09=09then
  =09=09=09=09:
  =09=09=09=09# already in table
  =09=09=09else
  =09=09=09=09/usr/bin/logger -p auth.notice \
  =09=09=09=09=09"Adding ${IP} to pfctl filter"
  =09=09=09=09/sbin/pfctl -q -t attackers -T add ${IP}
  =09=09=09=09/bin/echo "Added ${IP} "`host ${IP}` \
  =09=09=09=09=09| mail -s "Added attacker ${IP}" root
  =09=09=09fi
  =09=09else
  =09=09=09:
  =09=09fi
  =09done
} < ${IPLIST_UNIQ}

## store the current state
/sbin/pfctl -q -t attackers -T show > ${TMP}

## get rid of anything more than four weeks old
/sbin/pfctl -q -t attackers -T expire 2419200

## save what we have to the table we load on boot
/sbin/pfctl -q -t attackers -T show > ${ATTACKERS}

# check whether the table has expired anything
if
      /usr/bin/cmp -s ${TMP} ${ATTACKERS}
then
      :
else
      /bin/echo "These addresses have expired:"
      /usr/bin/diff ${TMP} ${ATTACKERS} | sed -e 's/^/    /'
fi

/bin/rm -f ${IPLIST_UNIQ} ${RAWLIST} ${IPLIST_RAW} ${TMP}

--142510029-1802741886-1272977710=:1908--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?alpine.BSF.2.00.1005040949560.1908>