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>
