pf suggestions for paced attack
A. Wright
andrew at qemg.org
Tue May 4 12:55:13 UTC 2010
I wrote:
>> If anyone is interested, I can send (or I suppose post) the scripts.
Balázs Mátéffy 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:
block 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=""
/usr/bin/tail -F /var/log/auth.log | {
while read line
do
sshd_test=`/bin/expr "${line}" : ".*sshd.*"`
if [ ${sshd_test} -gt 0 ]
then
inv_test=`/bin/expr "${line}" : ".*invalid.*"`
fail_test=`/bin/expr "${line}" : ".*Failed.*"`
err_test=`/bin/expr "${line}" : ".*error.*"`
if [ ${err_test} -gt 0 \
-o ${err_test} -gt 0 \
-o ${fail_test} -gt 0 ]
then
/bin/sh /usr/local/bin/filter-current-attackers
fi
fi
done
}
---- 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=""
TAG="current-attackers"
RAWLIST="/tmp/${TAG}.$$.raw"
IPLIST_RAW="/tmp/${TAG}.$$.IPlist.raw"
IPLIST_UNIQ="/tmp/${TAG}.$$.IPlist.uniq"
TMP="/tmp/${TAG}.$$.tmp"
LOG="/var/log"
ATTACKERS="/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
{
/usr/bin/find ${LOG} -name 'auth.log.*' -mtime -2 | \
/usr/bin/sort -t. -r -n -k 2,2 | \
while read f
do
case $f in
*.gz) /usr/bin/zcat -f $f | /usr/bin/tail +2;;
*.bz2) /usr/bin/bzcat -f $f | /usr/bin/tail +2;;
esac
done
[ -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" \
| /usr/bin/sed -e 's/.* //' | /usr/bin/awk '{print $1;}' > ${IPLIST_RAW}
/bin/cat ${RAWLIST} | /usr/bin/grep "POSSIBLE BREAK-IN" \
| /usr/bin/sed -e 's:\(.*\)\([ \[]\)\([0-9]*[.][0-9]*[.][0-9]*[.][0-9]*\)\(.*\):\3:' \
>> ${IPLIST_RAW}
/usr/bin/sort -u ${IPLIST_RAW} > ${IPLIST_UNIQ}
{
while read IP
do
if [ `/bin/expr "${IP}" : "[0-9]*[.][0-9]*[.][0-9]*[.][0-9]*"` -eq 0 ]
then
echo " Invalid IP format : [${IP}]"
continue
fi
# Explicitly avoid adding any machine on campus to the list
# if [ `/bin/expr "${IP}" : "138[.]73[.]*"` -gt 0 ] # MtA
# then
# continue
# fi
# check that there are at least 10 instances,
# to avoid locking ourselves out on a Thumbsday
/usr/bin/grep ${IP} ${IPLIST_RAW} > ${TMP}
LINECOUNT=`/usr/bin/wc ${TMP} | /usr/bin/awk '{print $1;}'`
if [ ${LINECOUNT} -gt 10 ]
then
if
#pfctl -q -t attackers -T test ${IP}
/usr/bin/grep ${IP} ${ATTACKERS} > /dev/null
then
:
# already in table
else
/usr/bin/logger -p auth.notice \
"Adding ${IP} to pfctl filter"
/sbin/pfctl -q -t attackers -T add ${IP}
/bin/echo "Added ${IP} "`host ${IP}` \
| mail -s "Added attacker ${IP}" root
fi
else
:
fi
done
} < ${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}
More information about the freebsd-questions
mailing list