不正なSSHの遮断。シェルスクリプト


ひさびさにサーバーのログを見てみると
SSHのポートへのアクセスログが酷い事になっていました。
なのでスクリプトを書いて蹴ることにしました。
(無駄に長いくて重いです。精進します。)
OS はCentOS5 です。




使い方はスクリプト中に書かれているファイルを適当に作って
cron に

*/5 * * * * /root/sshDeny.sh
0 */1 * * * /root/sshDeny.sh 60

と、登録してあげてください。
上記の例だと5分間隔、60分間隔で/var/log/secure を見に行って
ログインに失敗したIPからのアクセスを (IPtable が再起動されるまで?) 遮断します。

sshdeny.sh

#!/bin/bash

if [ $# -eq 0 ];
then
        minutesVal=5;
else
        minutesVal=$1;
fi

logFile='/var/log/secure /var/log/secure.1'
ipAddressTxt='/root/ipAddress.txt'
existIp=true
agoTime=$(LANG="en_us.UTF-8" date +"%b %d %H:%M" --date "$minutesVal minutes ago")
sshFailed=$(mktemp /tmp/sshFailed.XXXXX)
ipLists=$(mktemp /tmp/ipLists.XXXXX)
ipNo=$(mktemp /tmp/ipNo.XXXXX)

if [ $minutesVal -lt 10 ];
then
        while [ $minutesVal -gt 0 ]
        do
                agoTime=$(LANG="en_us.UTF-8" date +"%b %d %H:%M" --date "$minutesVal minutes ago")
                grep -h "^${agoTime}.*sshd\[.*\]: \(Invalid user\|Received disconnect from\|Failed password for\)" $logFile >> $sshFailed
                minutesVal=`expr $minutesVal - 1`
        done
else
        while [ $minutesVal -gt 0 ]
        do
                agoTime=$(LANG="en_us.UTF-8" date +"%b %d %H:%M" --date "$minutesVal minutes ago")
                agoTime=`expr "$agoTime" : '\(.*\s.*\s[0-9]\{1,2\}:[0-9]\{1\}\)'`
                grep -h "^${agoTime}.*sshd\[.*\]: \(Invalid user\|Received disconnect from\|Failed password for\)" $logFile >> $sshFailed
                minutesVal=`expr $minutesVal - 10`
        done
fi

IFS_OLD=$IFS
IFS="
"

for list in $(cat $sshFailed); do
        expr $list : '.*sshd.* \([0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}\)' >> $ipLists
done

sort $ipLists | uniq -c > $ipNo

for ip in $(sed 's/^ \{1,\}//' $ipNo); do
        count=$(echo $ip | cut -d" " -f1)
        if [ $count -ge 3 ]; then
                ipAddress=$(echo $ip | cut -d" " -f2)
                for existIpList in $(cat $ipAddressTxt); do
                        if [ $existIpList = $ipAddress ];
                        then
                                existIp=false
                        fi
                done
                if [ $existIp = true ];
                then
                        echo $ipAddress >> $ipAddressTxt
                        /sbin/iptables -A INPUT -d $ipAddress -j DROP
                        /usr/bin/logger -p 'authpriv.notice' -t sshDeny -i "Add $ipAddress"
                fi
        fi
        existIp=true
done

IFS=$IFS_OLD

rm -rf $sshFailed $ipLists $ipNo

タグ:

コメントをどうぞ