通过分析secure日志自动抵御非法登陆ip的脚本

因为编程基本功差,写了很冗长的代码,不过作为初学shell script还是有点作用的,而且给大家提供个思路。欢迎高手帮忙简化,当然请把语法说明白点……主要用了awk的打印功能,grep的查找关键字所匹配的行,for do done循环,if elif else判断,以及一些其他的小知识点,对于初学shell script的新手应该有点用处。
这个是我在rhel4版本上(说白了就是redhat as4版本)编的,要用的话,把中文部分去掉就行。另外附件里面是完全不用添删的版本,自己全考过去就能用了……如果你的secure文件记录非法登陆的关键字不同,比如不是Invalid user或者Failed password for root,请仔细分析到底是怎么记录的,然后对这个脚本进行改动,主要是grep "Invalid user" $LOGFILE | awk '{print $NF}' > badlist1_tmp1和grep "Failed password for root" $LOGFILE | awk '{print $11}' > badlist2_tmp1这两部分需要改动。

#!/bin/bash #声明使用bash,最好加这一行,出了问题的时候用vi编辑能帮你分析语法错误
###########################
#get words #这一段为了获取试图非法登陆本机的ip地址
LOGFILE=/var/log/secure #定义logfile变量,如果你的日志不是/var/log/secure,可以自己指定
#这两行为了清除上次留下的记录,因为用了>>,不删会影响这次执行的效果
rm -rf badlist1_tmp2
rm -rf badlist2_tmp2

#用grep从logfile中获取带有"Invalid user"字样的行;用awk程序将第$NF($NF是awk用来统计本行有多少个区域的变量)个域提取出来输出给当前目录下的文件badlist1_tmp1
grep "Invalid user" $LOGFILE | awk '{print $NF}' > badlist1_tmp1
#与上面类似,关键字变为Failed password for root,打印匹配行中的第11个域的内容,不过这次提取后,得到的大概是::ffff:xxx.xxx.xxx.xxx这样的效果,而且每次非法登陆都会记录一次,需要进一步简化
grep "Failed password for root" $LOGFILE | awk '{print $11}' > badlist2_tmp1

#定义变量tmp1,内容是文件badlist1_tmp1的内容啦
tmp1=`cat ./badlist1_tmp1`
#定义了两个新的变量
newtmp=
oldtmp=
#执行循环,作用是让变量i每次读出badlist1_tmp中的一条内容,也就是前面说的大概是::ffff:xxx.xxx.xxx.xxx这样的内容,然后裁剪掉前8个字符(用cut命令),再一条一条的记录在文件badlist1_tmp2中,这样循环结束后会生成一个全部记录非法ip的文件了。同时,这个循环还会把连续访问的非法ip过滤掉(也就是不进行记录,只记录和上一条ip不同的ip),当然如果同时有两个人在非法登陆,两个ip是交替出现的话就无能为力了。
for i in $tmp1
do
#只对每条记录的第8个字符以后的内容记录
newtmp=`echo $i | cut -c8-`
#如果新被记录的ip与上一条不同,则将这个ip记录追加写入到badlist1_tmp2文件中
if [ "$newtmp" != "$oldtmp" ] ; then
echo $newtmp >> badlist1_tmp2
fi
#把本次循环得到的ip保留,开始进入下一次循环
oldtmp=$newtmp
done

#这段作用和上面一样,不过是读取另外一个文件了
tmp1=`cat ./badlist2_tmp1`
for i in $tmp1
do
newtmp=`echo $i | cut -c8-`
if [ "$newtmp" != "$oldtmp" ] ; then
echo $newtmp >> badlist2_tmp2
fi
oldtmp=$newtmp
done

#将两个新生成的只记录了少量ip的文件合并,并将它的内容赋给变量tmp1
cat ./badlist2_tmp2 >> ./badlist1_tmp2
tmp1=`cat ./badlist1_tmp2`
#定义变量number为整数型,tmplist为数组,变量number初始值为0
declare -i number
declare -a tmplist
number=0
#逐步读出tmp1中的每条记录赋给数组tmplist,相当于把剩下所有的ip都记录下来,总共会有$number+1条记录,这个number变量的值将在下一次循环程序中使用。
for i in $tmp1
do
tmplist[$number]=$i # echo ${tmplist[$number]}这条注释掉的是我测试错误的时候用的
number=$number+1
done
#echo "There is $number IP record for all badlist files" 这也是我为了排错加的。


#####################
#here for reduse complex line#下面为了去掉因为其他原因留下的重复的ip记录
#删除finalist文件也是为了避免一些麻烦,因为后面用>>追加的,所以要保持一开始finallist为空
rm -rf finallist
#第一条记录肯定是没有重复啦,先输入进finallist文件
echo ${tmplist[0]} > finallist
#注意i的初始值为1,这样从第二条记录才开始进行比较轮询的过程,i的最大值是$number的值,也就是前面一段程序中统计的有多少条记录的统计-1(为什么减1,因为第一条记录不会重复的,所以就没有计算进去)。
for (( i=1;i<=$number;i=i+1 ))
do
#这是个嵌套轮询啦,现定义了一个整数型变量firstrec,初始值为0。
declare -i firstrec
firstrec=0
#j这个变量从0开始,就是为了让第二条记录tmplist[1]能够与第一条记录tmplist[0]进行比较,变量j的最大值要小于i,否则自己跟自己比较当然会一样,而且这样就等于每次都是与排在自己前面的记录进行比较,只要与前面所有的记录都不同就会被记录在finallist里面了!
for (( j=0;jdo
# echo "${tmplist[$i]}, ${tmplist[$j]} , $j " #测试错误用的,可以不要。
#当本条记录确认与前面的记录不同时,变量fristrec保持不变,如果发现相同就会自动+1
if [ "${tmplist[$i]}" != "${tmplist[$j]}" ] ; then
firstrec=$firstrec
else
# echo "This rec has been recorded!" #测试错误用的,可以不要。
firstrec=$firstrec+1
fi
done
# echo "The $i loop finish" #测试错误用的,可以不要。
#跳出嵌套的循环后看看是否firstrec为0,如果是0,那就意味着和前面所有的记录都不同,当然要加进finallist文件了,否则什么都不作(:代表null,什么都不作),如果firstrec的值小于0,显然出错了,赶紧跳出程序吧!
if [ $firstrec -eq 0 ]; then
echo ${tmplist[$i]} >> finallist
elif [ $firstrec -lt 0 ]; then
echo "Some thing error! '$firstrec' little than 0!"
exit 99
else
:
fi
# echo "${tmplist[$i]},'$i' is $i . " #测试错误用的,可以不要。
#开始读入下一条记录
done

#结束
#end[@more@]转中国网管论坛

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8570952/viewspace-982587/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/8570952/viewspace-982587/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值