hosts.denyでアクセス制限

2007.12.05.水
Server

トマト@ネットワーク云々担当です。

サーバを運用していると、攻撃や、不正アクセスを受ける事はよく有ります。
今回は、SSHへの連続的な攻撃を、サーバで判断し、自動でアクセスを拒否するスクリプトを紹介します。

攻撃の判断基準は、存在しないユーザでのアクセスと、存在しないユーザで、パスワード間違いの接続、存在するユーザで、パスワード間違いの接続の3種類です。

スクリプトの内容的には、crontabを使用し、一定間隔でログファイルをチェック、指定回数以上の攻撃を検知すると、hosts.denyファイルにて、該当IPからのSSH接続を拒否すると言う物です。


最新ファイルは、コメント欄のURLからダウンロード出来ます。
以下のコードを、コピー&ペーストで使用しないで下さい。
※環境により、不用なコードが入ってしまう場合があります

ssh-check.sh

#!/bin/sh

#------------------------------------------------------------------------------#
# [SSH] hosts.denyでアクセス制限
#------------------------------------------------------------------------------#
# Date     :2008/12/09
# Version  :1.0.1
# Copyright:KeyPoint,Inc.
# Author   :tomato
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
# 環境設定
#------------------------------------------------------------------------------#
# 攻撃判断回数(デフォルト10回以上でアクセスを拒否)
NG="10"

# ログファイル
LOG_PATH="/var/log/secure"		# RedHat(CentOS)
#LOG_PATH="/var/log/auth.log"		# Debian(Ubuntu)
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
# スクリプト本体
#------------------------------------------------------------------------------#
#実行ユーザの確認
USER=<code>/usr/bin/whoami</code>
[ $USER = "root" ] || {
	echo "///////////////////////////////////////////////////////////////////////////////"
	echo "/////                               Error!                                /////"
	echo "///////////////////////////////////////////////////////////////////////////////"
	echo "root権限で実行して下さい。"
	echo "実行例:# ./ssh-check.sh"
	echo "実行例:$ sudo ./ssh-check.sh"
	echo "///////////////////////////////////////////////////////////////////////////////"
	exit;
}

# 重複起動の防止
[ -f /tmp/ssh-check ] &amp;&amp;; /tmp/ssh-check

# 攻撃のあったIPアドレス(存在しないユーザでのアクセスと、存在しないユーザで、
# パスワード間違いの接続、存在するユーザで、パスワード間違いの接続を検出)
LIST=<code>grep "Invalid user" $LOG_PATH|awk '{print $10}'|sort|uniq ; grep "Failed password for invalid user" $LOG_PATH|awk '{print $13}'|sort|uniq ; grep "Failed password for" $LOG_PATH|grep -v "invalid"|awk '{print $11}'|sort|uniq</code>

for IP in $LIST
do
        # 攻撃回数をカウントする
        COUNT1=<code>grep "Invalid user" $LOG_PATH|grep -w "$IP"|wc -l</code>
        COUNT2=<code>grep "Failed password for" $LOG_PATH|grep -w "$IP"|wc -l</code>
        COUNT=<code>expr $COUNT1 + $COUNT2</code>

        # 既に登録されているか確認
        if test <code>grep -w "$IP" /etc/hosts.deny</code>
        then
                echo "登録済み:"$IP
        else
                # 攻撃回数のチェック
                if [ $COUNT -ge $NG ]
                then
                        # 回数オーバーで、hosts.denyに追記する
                        echo "回数オーバー:"$COUNT "回 ["$IP"]"
                        echo "sshd:"$IP &gt;&gt; /etc/hosts.deny
                fi
        fi
done

# 一時ファイルの削除
rm /tmp/ssh-check
#------------------------------------------------------------------------------#



スクリプトの編集と、実行権限の付加

※「環境設定」部分は、環境に合わせて設定して下さい

スクリプトの実行例

※攻撃回数が、指定回数を越えた場合に、「hosts.deny」ファイルに、アクセス制限情報が追記されます

crontabの設定例(5分間隔の場合)

※「/etc/hosts.deny」ファイルを編集するので、root権限で実行します

これで、該当IPアドレスからの接続は拒否出来ます。
IPv6環境の場合は、無効にして下さい。