maxloginsでsshdへの総当り攻撃を防ぐ

もう一年位前にやったことだけど、記録として残しておこうと思う。

自分の管理しているサーバでもものすごい数の不正ログインの試みがあって(中国とか韓国あたりから)、何とかしたいなと思っていた。パスワード認証を完全に禁止するかポートを変えるかしてしまえば解決する問題だが、そうもいかないのが世の常(かどうかはよく知らない)。

ちょうどssh に対する brute force attack に対抗するためのツール導入 - 蝸牛の歩みという記事をみて、ああいいなと思って導入してみたのだが、なぜかmaxlogins.pl自体にsyslogのメッセージが上書きされていった。調べてみると、linuxのsyslogでは"|"はただのパイプではなくて名前つきパイプへの出力になるとのこと*1。たぶん原因はこれだろうと思って、名前つきパイプを作って(/var/log/block)、syslogの出力をこれにして、以下のシェルスクリプト(maxlogins.sh)を走らせることにした。

#!/bin/sh
while read message; do
    echo $message | /usr/local/bin/maxlogins.pl
done < /var/log/block

ついでにmaxlogins.shの起動スクリプトも作ってみた。

#!/bin/sh
# description: Disable to login ssh when failure to login counts more than 3
# chkconfig: 2345 99 00
. /etc/rc.d/init.d/functions
RETVAL=0

case "$1" in
'start')
        echo -n "Starting maxlogins..."
#	daemon /usr/local/bin/maxlogins.sh
        /usr/local/bin/maxlogins.sh&
        RETVAL=$?
	echo
        [ $RETVAL = 0 ] && touch /var/lock/subsys/maxlogins
	;;
'stop')
        echo -n "Stopping maxlogins..."
	killproc maxlogins.sh
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && rm -f /var/lock/subsys/maxlogins
	;;
*)
	echo "Usage: $0 { start | stop }"
	;;
esac
exit 0

とりあえず、これでmaxlogins.pl自体が上書きされてしまうようなことはなくなって、これだけですむと思ったけど、どうもおかしい。なぜか時間が経つとmaxlogins.shが落ちてしまう。仕方がないのでcronで一時間毎に動作を監視するようにした。

#!/bin/sh
var=`ps aux |grep maxlogins.sh|grep -v grep|wc -l`;

if [ $var -eq 0 ]; then
    /etc/init.d/maxlogins start;
    echo "maxlogins started ...";
elif [ $var -eq 1 ]; then
    echo "maxlogins is running ...";
else
    echo "unknown situation ...";
fi

今検索してみたところ、maxlogins.plのバージョンがあがってる。一定時間がたったブロックIPを削除するなど、機能が増えているようだ。

sshd : /var/log/maxlogins : spawn /bin/sleep 30 : twist /bin/echo "go away"
sshd : /var/log/maxlogins : twist /bin/echo "Access denied."

これはいいかも。