ひさびさにサーバーのログを見てみると
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
タグ: Linux