用shell脚本防止暴力破解SSH服务

近来无意发现有许多人在尝试暴力破解我VPS服务器SSH服务,因此,根据/var/log/secure日志显示情况,查找一些资料,自己动手写了个Shell脚本来防止SSH的暴力破解。

使用命令查看据/var/log/secure

# cat /var/log/secure|awk '/Failed/{print $(NF-3)}'|sort|uniq -c|awk '{print $2"="$1;}'
124.160.192.241=8
125.222.191.77=264
174.139.85.146=68
184.107.179.50=132
202.75.218.139=405
206.246.141.118=1
213.229.124.66=707
218.80.254.242=3
222.82.245.146=7
64.120.15.156=1
64.34.218.142=2
70.38.31.38=2119
88.190.21.124=30
95.130.170.231=2

这条命令是统计访问失败的IP和次数,很显然,有很多恶意IP。所以根据这些信息可以写一个shell脚本来过滤这些IP:

#! /bin/bash

cat /var/log/secure|awk '/Failed/{print $(NF-3)}'|sort|uniq -c|awk '{print $2"="$1;}' > /root/satools/black.txt

DEFINE="100"

for i in `cat /root/satools/black.txt`
do

IP=`echo $i |awk -F= '{print $1}'`
NUM=`echo $i|awk -F= '{print $2}'`

if [ $NUM -gt $DEFINE ]; then
grep $IP /etc/hosts.deny > /dev/null

if [ $? -gt 0 ]; then
echo "sshd:$IP" >> /etc/hosts.deny
fi
fi
done

该脚本的思路:

由于/var/log/secure是以星期为轮询的,所以我们每次可以查看这个文件,利用shell脚本统计出其中访问失败比较频繁的IP,并定义一个阀值为100,如果大于100的话就将其放进/etc/hosts.deny文件,阻止其继续访问vsftpd和ssh;然后将其写进crontab计划列表里,每隔一段时间进行一次排查,如果下次排查的某IP次数又大于100,首先检查它在不在我们的黑名单,如果在的话就无视过去;如果不在,就继续添加进/etc/hosts.deny文件。

该脚本也可以解决其他服务遭受暴力破解,比如 VSFTP。方法如下:

在脚本中第二个 if 中写入:

echo "vsftpd:$IP" >> /etc/hosts.deny

最后使用crontab定时执行这个脚本。即每隔1小时就重复执行一次这个脚本,这里也有一个情况要说明下,/var/log/secure是每隔一个星期轮询一次的,所以我们这里可以根据服务器的具体情况来配置多少时间执行一次此脚本,暴力破解频繁的机器可适当缩小这个周期。

0 */1 * * * root sh /root/satools/hosts_deny.sh

我们可以先手动执行一下该脚本,看一下效果:

#  ./hosts_deny.sh
# cat /etc/hosts.deny
#
# hosts.deny This file describes the names of the hosts which are
# *not* allowed to use the local INET services, as decided
# by the '/usr/sbin/tcpd' server.
#
# The portmap line is redundant, but it is left to remind you that
# the new secure portmap uses hosts.deny and hosts.allow. In particular
# you should know that NFS uses portmap!

sshd:125.222.191.77
sshd:184.107.179.50
sshd:202.75.218.139
sshd:213.229.124.66
sshd:70.38.31.38

可以看到访问失败次数大于预设值的IP已经写入到了hosts.deny文件中。

, 相关的文章:
  1. 肯定是可以的:

    echo “sshd:$IP” >> /etc/hosts.deny
    这里修改成:
    iptables -A INPUT -s $IP -p tcp –dport 22 -j DROP

    当然也要在脚本末尾加上保存规则,和重启iptables指令!