トマト@ネットワーク云々担当です。
サーバを運用していると、攻撃や、不正アクセスを受ける事はよく有ります。
今回は、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 ] &&; /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 >> /etc/hosts.deny fi fi done # 一時ファイルの削除 rm /tmp/ssh-check #------------------------------------------------------------------------------#
スクリプトの編集と、実行権限の付加
1 2 |
# vim ssh-check.sh # chmod +x ssh-check.sh |
※「環境設定」部分は、環境に合わせて設定して下さい
スクリプトの実行例
1 2 3 |
# ./ssh-check.sh 回数オーバー:100 回 [111.111.111.111] 回数オーバー:200 回 [222.222.222.222] |
※攻撃回数が、指定回数を越えた場合に、「hosts.deny」ファイルに、アクセス制限情報が追記されます
crontabの設定例(5分間隔の場合)
1 |
*/5 * * * * root /root/bin/ssh-check.sh > /dev/null 2>&1 |
※「/etc/hosts.deny」ファイルを編集するので、root権限で実行します
これで、該当IPアドレスからの接続は拒否出来ます。
IPv6環境の場合は、無効にして下さい。