swatchを導入してみる

dovecotのログをみていると、以下のような認証アタックが結構あることに気が付きました。

2 20:27:49 www19472ue auth: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=access rhost=74.94.179.17 
Sep  2 20:27:49 www19472ue auth: pam_succeed_if(dovecot:auth): error retrieving information about user access
Sep  2 20:27:59 www19472ue auth: pam_unix(dovecot:auth): check pass; user unknown
Sep  2 20:27:59 www19472ue auth: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=pwrchute rhost=74.94.179.17 
Sep  2 20:27:59 www19472ue auth: pam_succeed_if(dovecot:auth): error retrieving information about user pwrchute
Sep  2 20:28:10 www19472ue auth: pam_unix(dovecot:auth): check pass; user unknown
Sep

特定のIPだけを許可するようなことができない状況なので、swatchを使って、dovecotで5回以上認証失敗したIPは2時間だけiptablesで接続を拒否するように設定してみた。

今回は、複数のサーバに設置する必要があったので、設定用のファイルを用意しました。よろしければ、自己責任でご利用くださいませ。

●ファイル構成

swatch.sh
template/swatch_action.sh
template/swatch_logwatch_conf.txt
template/swatch_secure.conf
template/swatch_rc.txt

のようにファイルを適当なディレクトリに設置します。

swatch.sh

#! /bin/sh

yum -y install swatch at perl-Time-HiRes perl-File-Tail

SACT=/usr/local/bin/swatch_action.sh
CONFD=/etc/swatch
LOGCONF=/etc/logrotate.d/swatch
SECURECONF=/etc/swatch/secure.conf
SRC=/etc/rc.d/init.d/swatch

my_dirname() { echo ${1%/*}; }
PWD=`pwd`

case "$0" in
/*) DIR=`my_dirname "$0"` ;;
*) DIR=`my_dirname "$PWD/$0"` ;;
esac
if [ ! -e ${SACT} ]
then
cp ${DIR}/template/swatch_action.sh ${SACT}
chmod 700 ${SACT}
fi

if [ ! -e ${CONFD} ]
then
mkdir ${CONFD}
fi

if [ ! -e ${LOGCONF} ]
then
cp ${DIR}/template/swatch_logwatch_conf.txt ${LOGCONF}
fi

if [ ! -e ${SECURECONF} ]
then
cp ${DIR}/template/swatch_secure.conf ${SECURECONF}
fi

if [ ! -e ${SRC} ]
then
cp ${DIR}/template/swatch_rc.txt ${SRC}
chmod +x ${SRC}
fi

restatus=`$SRC status`
if [[ "$restatus" =~ stopped ]]; then
$SRC start
fi

chkconfig --add swatch
chkconfig swatch on

restatus=`/etc/rc.d/init.d/atd status`
if [[ "$restatus" =~ stopped ]]; then
/etc/rc.d/init.d/atd start
fi

chkconfig atd on

template/swatch_action.sh

#!/bin/bash

PATH=/bin:/sbin:/usr/bin
LANG=C

# 規制IPアドレス情報メール通知先設定
# ※メール通知しない場合は下記をコメントアウト
#mail=root

# ログを標準入力から取得
read LOG

# ログからIPアドレスを抽出
IPADDR=`echo $LOG|cut -d " " -f $1`
echo "$IPADDR"|grep "^[0-9]*\." > /dev/null 2>&1
if [ $? -eq 0 ]; then
# IPアドレスから始まる場合
IPADDR=`echo "$IPADDR"|sed -e 's/\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*//p' -e d`
else
# IPアドレス以外から始まる場合
IPADDR=`echo "$IPADDR"|sed -e 's/.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*//p' -e d`
fi

# IPアドレスをピリオドで分割
addr1=`echo $IPADDR|cut -d . -f 1`
addr2=`echo $IPADDR|cut -d . -f 2`
addr3=`echo $IPADDR|cut -d . -f 3`
addr4=`echo $IPADDR|cut -d . -f 4`

# IPアドレスがプライベートIPアドレスの場合は終了
if [ "$IPADDR" = "127.0.0.1" ]; then
exit
elif [ $addr1 -eq 192 ] && [ $addr2 -eq 168 ]; then
exit
fi

# 不正アクセスログメッセージをIPアドレス別ログファイルに記録
echo $LOG >> /var/log/swatch/$IPADDR

# IPアドレス別ログファイルから累積不正アクセス数取得
cnt=`cat /var/log/swatch/$IPADDR | wc -l`

# 該当IPアドレスからの累積不正アクセス数が5以上の場合または
# 引数でlockと指定された場合アクセス規制
if [ $cnt -ge 5 ] || [ $# -eq 2 -a "$2" = "lock" ]; then
# 該当IPアドレスからのアクセスを拒否するルールを挿入
iptables -I INPUT -s $IPADDR -j DROP

# 上記ルールを2時間後に削除するスケジュールを登録
echo "iptables -D INPUT -s $IPADDR -j DROP > /dev/null 2>&1" | \
at now+2hour > /dev/null 2>&1

# アクセス規制IPアドレス情報をメール通知
[ "$mail" != "" ] && (cat /var/log/swatch/$IPADDR ; \
echo ; whois $IPADDR) | \
mail -s "$IPADDR $cnt lock!" $mail

echo "`date` $IPADDR $cnt lock!"
else
echo "`date` $IPADDR $cnt"
fi

template/swatch_logwatch_conf.txt

/var/log/swatch/swatch.log {
    missingok
    notifempty
    sharedscripts
    postrotate
        /etc/rc.d/init.d/swatch restart > /dev/null || true
    endscript
}

template/swatch_secure.conf

# logfile /var/log/secure
watchfor /dovecot.*authentication failure/
 pipe "/usr/local/bin/swatch_action.sh 14"
 throttle=00:00:10

#上記は、「/var/log/secure」をチェックし、
#「dovecot.*authentication failure」を含む(「.*」は正規表現)行を取り出す。
#取り出した行を空白で区切ったとき、14番目にIPに関する情報があるので、この内容をswatch_action.shに渡す。
#ただし、10秒間は同じ文字を検出しても無視する。
#という設定です。

template/swatch_rc.txt

#!/bin/bash
#
# swatch
#
# chkconfig: 2345 90 35
# description: swatch start/stop script

# Source function library.
. /etc/rc.d/init.d/functions

PATH=/sbin:/usr/local/bin:/bin:/usr/bin

mkdir -p /var/log/swatch

start() {
    # Start daemons.
    ls /var/run/swatch_*.pid > /dev/null 2>&1
    if [ $? -ne 0 ]; then
        echo -n "Starting swatch"
        pno=0
        for conf in /etc/swatch/*.conf
        do
            pno=`expr $pno + 1`
            WATCHLOG=`grep "^# logfile" $conf | awk '{ print $3 }'`
            swatch --config-file $conf --tail-file $WATCHLOG \
            --script-dir=/tmp --awk-field-syntax --use-cpan-file-tail --daemon \
            --pid-file /var/run/swatch_$pno.pid \
            >> /var/log/swatch/swatch.log 2>&1
            RETVAL=$?
            [ $RETVAL != 0 ] && return $RETVAL
        done
        echo
        [ $RETVAL = 0 ] && touch /var/lock/subsys/swatch
        return $RETVAL
    else
        echo "swatch is already started"
    fi
}

stop() {
    # Stop daemons.
    ls /var/run/swatch_*.pid > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo -n "Shutting down swatch"
        for pid in /var/run/swatch_*.pid
        do
           kill $(cat $pid)
           rm -f $pid
        done
        echo
        rm -f /var/lock/subsys/swatch /tmp/.swatch_script.*
    else
        echo "swatch is not running"
    fi
}

status() {
    ls /var/run/swatch_*.pid > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo -n "swatch (pid"
        for pid in /var/run/swatch_*.pid
        do
           echo -n " `cat $pid`"
        done
        echo ") is running..."
    else
        echo "swatch is stopped"
    fi
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        stop
        start
        ;;
  status)
        status
        ;;
   *)
        echo "Usage: swatch {start|stop|restart|status}"
        exit 1
esac

exit $RETVAL

●swatchの設定

ファイル設置後、管理者権限で

sh ./swatch.sh

を発行すればよいです。

 

ログ監視ツール導入(SWATCH)を参考にさせていただきました。

 

 

1件のコメント

コメントは受け付けていません。