将恶意登陆的IP加入防火墙的脚本
一、前言
记得刚入手VPS的时候,Linux小白一个,啥都不懂,但是却虎头虎脑的就搭建了一个邮件服务器,用来注册各种账号,国内的邮箱服务需要绑定手机号,觉得很烦。
就这样过了几个月,某一天心血来潮(刚好学到日志这个东西),于是下意识的看了一下服务器的各种日志。我去,什么情况,这邮件服务的日志加起来都快1G了。
当时看到这么大的文件,我一脸茫然,只是惊叹这个日志记录的挺勤快的,却还没意识到什么就不管了。但事后经过不断的学习后,我再回头想起这件事,立马就对自己无语了,当时我这一共才发几封邮件啊,日志不可能记录这么多的,绝对有猫腻的。
于是用上刚学的grep工具,对着错误信息一过滤,立马刷刷地一堆IP地址,这些是访问失败的,而且有个IP都快一万次了,IP工具显示的是僵尸网络。
这是造爆破了,我心里居然一乐,邮件服务器这么招人喜欢吗?然后再去查系统日志,也是不得了,ssh服务N多IP恶意登录。
得,这下刚学的shell脚本派上用场了。
由于正则表达式还不太熟悉,在网上找了一些规则,七拼八凑终于弄好了脚本,你们都乖乖的去见防火墙吧。
二、脚本部分
脚本内容如下:
#! /bin/bash
# IP blacklist script.
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# 获取符合规则的IP地址
TIME=`date +%Y-%m-%d`
FIREWALL_DROP=/etc/firewalld/zones/public.xml
IP_LIST=`egrep 'SASL LOGIN authentication failed|Failed password' ${1}|egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' |sort | uniq -c `
IP_ADDR=`echo "$IP_LIST" |awk '$1>=5 {print $2}'`
if [ ! -d /var/log/fbl ]
then
mkdir -p /var/log/fbl
fi
# 添加到防火墙规则
for i in `echo "$IP_ADDR"`
do
grep $i $FIREWALL_DROP >/dev/null
if [ $? -ne 0 ];then
firewall-cmd --add-rich-rule="rule family='ipv4' source address='$i' drop" --permanent
else
echo "This is $i is exist in firewall,please exit......"
fi
done
echo -e "******$TIME******\n${IP_LIST}" >> /var/log/fbl/fbl.log
# 配置发邮件
echo -e "The firewall_blacklist:\n ${IP_LIST}\n${TIME}." | mail -s "WANMING:THESE IP ADDRESS LOGIN FAILED!" 123@123.com //邮箱账号
cp ${1} ${1}-$TIME && echo "" > ${1}
firewall-cmd --reload
# 将旧的日志文件删除
file_num=`ls -l ${1}-* |wc -l`
while [ $file_num -gt $2 ]
do
file_name=`ls -rtl ${1}-* |awk '{print $NF}' |head -1`
rm -f $file_name
file_num=`ls -l ${1}-* |wc -l`
done
配置邮件通知,然后将脚本添加到crontab计划任务,使其定期执行,并且ssh的默认端口也改了,这下ssh方面暂时搞定了,然而邮件服务器只能不断的添加到防火墙。
现在的问题就是,随着规则的不断添加,防火墙的配置文件也在增大。虽然目前这个问题还找不到更好的解决办法,但我想,解决方法肯定是有的,只是我还没找到罢了。
三、更新
2018-04-19 20:57:41 星期四
好吧,搞着这么久都没发现,原来firewalld是有一个ipset的,可把多条IP地址或者是IP段添加进去,进行更为人性化的管理。
所以脚本作了更新:
#! /bin/bash
## The IPv4 blacklist script for mail server.
## Creation date: 2018-02-17
## Repair time: 2018-04-12
## Version: 2.5.0
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~bin
export PATH
drop_file=/etc/firewalld/ipsets/blacklist.xml
drop_log=/var/log/maillog
drop_time=`date +%Y-%m-%d`
# 获取恶意IP地址
get_info(){
host_ip=$(ip addr |egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' |egrep -v '^127' |head -n 1)
drop_filename=$(echo ${drop_file}| awk -F '/' '{print $NF}' |awk -F '.' '{print $1}')
ip_addr=`egrep 'SASL LOGIN authentication failed|Failed password' ${drop_log}|egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' |sort | uniq -c`
ip_list=`echo "$ip_addr" |awk '$1>=10 {print $2}'`
}
# 封禁部分
ban_ip(){
get_info
if [ ! -s ${drop_file} ];then
firewall-cmd --permanent --zone=drop --new-ipset=${drop_filename} --type=hash:ip
firewall-cmd --permanent --zone=drop --add-rich-rule="rule source ipset=${drop_filename} drop"
fi
for i in `echo "${ip_list}"`
do
grep ${i} ${drop_file} >/dev/null
if [ $? -ne 0 ];then
firewall-cmd --permanent --zone=drop --ipset=${drop_filename} --add-entry=${i}
fi
done
firewall-cmd --reload
}
# 作邮件通知
noti_mail(){
ip_mail=$(echo "$ip_addr" |awk '$1>=10 {print}')
if [ -s ./mail.py ];then
# 因为得到了邮件脚本,就直接上脚本发邮件了
python ./mail.py "接收信息的邮箱" "The firewall info." "$(echo -e "Host:\n${host_ip}\n\nTime:\n${drop_time}\n\nIP address disable list:\n\n${ip_mail}")"
else
echo -e "$(echo -e "IP address disable list:\n\n${ip_mail}\n\n${drop_time}.")" >> ./fbs.log
fi
# 这里对maillog做一个处理
log_name=$(echo ${drop_log}| awk -F '/' '{print $NF}')
log_dir=$(echo ${drop_log}| awk -F "${log_name}" '{print $1}')
cd ${log_dir}
tar zcf ${log_name}-${drop_time}.tar.gz ${log_name}
echo "" > ${log_name}
}
ban_ip
noti_mail
不知道为什么,QQ账户发邮件可以排版,gmail却不行。
然后添加到计划任务cron里面去
0 0 * * * cd /usr/local/sbin/ ; /bin/bash 脚本名字 >/dev/null 2>&1
后记
这个事情也是给了我一个教训,但同时也是得到了不错的实战经验,在服务器安全方面,还有更多的地方要注意到。