项目实践:监控登录服务器不成功的IP,获取来源地后邮件通知管理员

背景说明:

        公司的服务器较多【Linux,centos系统】,且日常经常发现有不明来源的IP尝试登录,希望每天能获取有来自哪些地方的IP尝试进行登录(攻击)。

一、思路:

        每天自动查询攻击的IP信息 ——》自动执行IP来源查询——》 自动推送邮件到管理员。

二、实践:

1、每天自动查询攻击的IP

        由于是Linux服务器,可以使用命令

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

         该命令可以将前一个周日以来,尝试登录服务器,但是失败了的主机IP查询出来,结果格式:IP=尝试次数。例如:

1.117.159.149=2
1.117.93.70=1
183.146.30.220=5

如果只需要IP信息,则将查询代码最后的awk '{print "IP:"$2",尝试次数:"$1};,替换为awk '{print $2}' 即可。【可以根据实际需求更改输出信息】

最后将IP清单存储到一个当前目录下temp文件夹下以当天日期命令的文件:如20230101_IP.txt。

cat /var/log/secure | awk '/Failed/{print $(NF-3)}'| sort| uniq -c| awk '{print $2}' >> tempfile.txt

以上是核心知识点,最终需要将相关信息获取,保存等操作,最终在经历多次踩坑后【如文件名格式问题、数据输出问题等】,最终形成的shell完整脚本getFaildIP.sh:

#!/bin/bash  
# 统计有多少尝试连接本机但是失败了的IP:合并其尝试次数。

# 当前主机的IP地址,根据服务器IP更改
hostIP="127.0.0.1"
# 日志文件
logfile="/rxshell/getIP.log"
# 输出文件存放的位置,供Python脚本调用
filepath="/opt/dkhome_python/"
# 获取当天的日期,yyyymmdd的格式:20221222;用作保存IP信息的文件名
today=$(date +"%Y%m%d")
# 计算今天是周一开始的第几天
whichday=$(date -d $today +%w)

#ipfile 只保留IP,供Python脚本调用。filename 则还包括尝试次数信息
filename=$filepath"temp/"$today".txt"
ipfile=$filepath"temp/"$today"_IP.txt"

# 如果文件存在,删除重新创建:用于保证每天即使执行多次,均保留最后一次。如果不删除,则会追加保留
if [ -f "${filename}" ];then
	rm ${filename}
fi
if [ -f "${ipfile}" ];then
	rm ${ipfile}
fi
#sunday=$(date -d "$today -$[${whichday}] days" +%Y-%m-%d)  # 等价表达方式。
sunday=`date -d "$today -$[${whichday}] days" +%Y-%m-%d`
echo $sunday"日以来尝试登陆本服务器,但是失败的IP清单" >> $filename
echo "服务器:"$hostIP >> $filename
echo "当前时间是:"$(date +"%Y‐%m‐%d %H:%M:%S") >> $filename
echo "——————————————— 统计结果:———————————————" >> $filename

cat /var/log/secure | awk '/Failed/{print $(NF-3)}'| sort| uniq -c| awk '{print "IP:"$2",尝试次数:"$1;}' >> $filename
cat /var/log/secure | awk '/Failed/{print $(NF-3)}'| sort| uniq -c| awk '{print $2}' >> $ipfile

echo $(date +"%Y-%m-%d %H:%M:%S")":执行getFiledIP.sh --> 获取攻击IP地址信息并保存成功!" >> $logfile

2、查询IP来源地信息:

        曾经过多天找寻,但是未能找到免费且稳定的在线查询接口;最后综合多种方案后,使用纯真数据库的离线数据库,使用Python语言开发处理脚本,将第一步中产生的IP清单获取后,调用保存到本地的数据库进行查询,最终保存文件并返回。数据库文件可以从www.cz88.net获取。

        Python环境使用docker容器进行部署【docker操作Python的方法,将另文介绍】,docker的本地挂载目录为/opt/dkhome_python,容器端的目录为:/home/python_home/,为保证Python脚本能正常运行,需要安装已有的工具:pip install qqwry-py3。

        最终形成的Python获取IP信息,并保存到ipsource文件夹下,命名格式为“IPsource_20230101.txt”。代码:getIPsource.py:【使用到的数据库文件qqwry.dat可联系作者获取当前通过测试的版本或者从www.cz88.net官网方式获取最新文件】

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import io
from qqwry import QQwry
from qqwry import updateQQwry

PYTHON_HOME = "/home/python_home/"
IPDB_FILE = PYTHON_HOME + "qqwry.dat"
##--注意实际环境和测试环境可能不同-下方为本地测试环境----
##IPDB_FILE = "qqwry.dat"
##PYTHON_HOME = "./"


def getIPsource(IPlist):
    q = QQwry()
    q.load_file(IPDB_FILE)
    
    time_start = time.time()   # 开始工作时间
    #print(time_start)

    IPsources = []
    for ip in IPlist:
        ip = ip.strip()
        print("当前查询的IP是:{}".format(ip))
        try:
            res = q.lookup(ip)
            tempInfo = "IP:{:17}==>归属地:{},  运营商:{}".format(ip,res[0],res[1])
        except:
            tempInfo = "IP:{:17}==>归属地:{},  运营商:{}".format(ip,"错误IP","错误IP")
        print(tempInfo)
        IPsources.append(tempInfo)

    time_end = time.time()   # 查询完成的时间
    print("查询的IP数:{},查询耗时(s):{}".format(len(IPsources),(time_end - time_start)) )   

    return IPsources

def saveIPsource(IPsources, filename=""):
## 将IP源信息保存到同目录下的ipsource/文件夹,文件名以当天日期为名字
    if filename=="":
        filename = PYTHON_HOME + "ipsource/IPsource_" + time.strftime("%Y%m%d", time.localtime())+".txt"
    
    with io.open(filename, 'w', encoding='utf8') as f:
        for line in IPsources:
            f.write(line + "\n")
        f.close()
    print("Save IPsources successed!")
    

if __name__ == "__main__":
##    test("43.134.177.150")
    today = time.strftime("%Y%m%d", time.localtime())
    iplistfile = PYTHON_HOME + "temp/"+today + "_IP.txt"
    with open(iplistfile, "r") as f:
        IPlist = f.readlines()
    
    IPsources = getIPsource(IPlist)
    ipsourcefile = PYTHON_HOME + "ipsource/IPsource_"+today+".txt"
    saveIPsource(IPsources, ipsourcefile)

        

        查询IP的Python脚步做好,但是还需要在服务器中编写shell脚本来调用执行,因本项目采用的是docker容器中安装Python并执行,因此在需要保证已安装docker并开启了安装过Python3及相关依赖库【qqwry-py3、io等】的容器,最终调用的脚本getIPsource.sh如下:

#!/bin/bash  
# 执行Python脚本,查询IP源信息。

# 日志文件
logfile="/rxshell/getIP.log"

echo $(date +"%Y-%m-%d %H:%M:%S")":执行getIPsource.sh --> 准备获取IP源脚本..." >> $logfile
docker restart python && docker exec python python /home/python_home/getIPsource.py
echo $(date +"%Y-%m-%d %H:%M:%S")":执行getIPsource.sh --> 获取IP源脚本成功!" >> $logfile

3、 设置定时任务,将查询到的IP来源文件,如/ipsource_20230101.txt信息用邮件发送到管理员。

        3.1、使用Linux的定时任务管理工具crontab配置每天执行任务,方法:

        Linux命令行输入: crontab -e, 将打开vim编辑器,输入        

                30 6 * * * /rxshell/getFiledIP.sh    #  每天6点30分执行

                32 6 * * * /rxshell/getIPsource.sh  #  每天6点32分执行 

                35 6 * * * /rxshell/sendIPlist.sh  #  每天6点35分执行

        crontab 的配置方法此处不再详述,自行百度即可。

        3.2、使用邮件工具 mail/mailx发送邮件,具体配置方法百度专门的文章。

        最终,读取已经查询了来源信息并保存到/ipsource文件夹中的当天对应的文件,例如IPsource_20230101.txt,并将文件内容推送到需要相关信息的管理员。

        推送邮件的shell脚本sendIPlist.sh如下:

#!/bin/bash  
# 将查询出来的IP来源;使用邮件推送到管理人员

# 当前主机的IP地址
hostIP="127.0.0.1"
# 日志文件
logfile="/rxshell/getIP.log"
# IP源文件存放的位置
filepath="/opt/dkhome_python/"
# 获取当天的日期,yyyy-mm-dd的格式:2022-12-22;用作保存IP信息的文件名
today=$(date +"%Y%m%d")
# 计算今天是周一开始的第几天
whichday=$(date -d $today +%w)
emaillist="1164256062@qq.com, dajiang.yi@ristonchina.com"

iplist=$filepath"temp/"$today".txt"
tempfilename=$filepath"temp/"$today".temp.txt"
ipsource=$filepath"ipsource/IPsource_"$today".txt"

# 如果文件存在,删除重新创建:用于保证每天最新
if [ -f "${tempfilename}" ];then
	rm ${tempfilename}
fi 
sunday=`date -d "$today -$[${whichday}] days" +%Y-%m-%d`

echo $sunday"日以来尝试登陆本服务器,但是失败的IP及来源清单" >> $tempfilename
echo "服务器:"$hostIP >> $tempfilename
echo "当前时间是:"$(date +"%Y‐%m‐%d %H:%M:%S") >> $tempfilename
echo "——————————————— 统计结果:———————————————" >> $tempfilename

echo $(date +"%Y-%m-%d %H:%M:%S")":执行sendIPlist.sh --> 准备获取IP源清单..." >> $logfile
cat $ipsource >> $tempfilename
#cat $ipsource >> $logfile 

#echo "-------准备发送邮件-----------"
cat $tempfilename | mail -s $today"安全日报:攻击本服务器的IP及来源报告:IP="$hostIP  $emaillist
#echo "-------发送邮件完毕!-----------"
echo $(date +"%Y-%m-%d %H:%M:%S")":执行sendIPlist.sh --> 邮件发送IP源清单成功!" >> $logfile

三、项目部署实操步骤及实践结果

1、环境依赖

        1、docker环境;安装Python3;
        2、邮件发送系统mail/mailx
        3、定时任务工具crontab

2、部署及实操步骤

        第一步:在服务器根目录/,创建tools文件夹: mkdir tools

        第二步:将getFiledIP.sh、getIPsource.sh、sendIPlist.sh、getIPsource.py、qqwry.dat上传到tools目录

        第三步:将脚本移动到相关项目文件夹【此处如果需要修改文件夹位置,则在对应的shell文件中也要修改相应的文件夹位置】

mv /tools/getFiledIP.sh /rxshell/
mv /tools/getIPsource.sh /rxshell/
mv /tools/sendIPlist.sh /rxshell/
mv /tools/getIPsource.py /opt/dkhome_python/
mv /tools/qqwry.dat /opt/dkhome_python/

         第四步:增加脚本的执行权限:这里要特别注意,如果不增加权限,则脚本在后期不能正常执行,得不到预期的效果。命令: chmod +x  文件名

sudo chmod +x /rxshell/getFiledIP.sh
sudo chmod +x /rxshell/getIPsource.sh
sudo chmod +x /rxshell/sendIPlist.sh
sudo chmod +x /opt/dkhome_python/getIPsource.py
sudo chmod +x /opt/dkhome_python/qqwry.dat

            第五步:配置:
            1、根据运行的服务器IP,将getFiledIP.sh、sendIPlist.sh中的hostIP="127.0.0.1"修改为服务器的实际IP。
            2、管理员接收邮件地址:sendIPlist.sh中 emaillist="email1@qq.com, email2@qq.com",多个邮件以","分隔。

           第六步:增加定时任务

        这里因为脚本有执行先后顺序,因此3个脚步按执行先后顺序,间隔一定时间。

        在命令行输入命令:crontab -e,进入vim编辑器,输入以下命令,保存退出

# 每天6点30分执行
30 6 * * * /rxshell/getFiledIP.sh
# 每天6点32分执行
32 6 * * * /rxshell/getIPsource.sh 
# 每天6点35分执行
35 6 * * * /rxshell/sendIPlist.sh

3、实践结果

        部署完成后,经过几天的测试观察,最终都能正确发送邮件,邮件效果如下:

在我接收的邮件信息:

 详细内容参考:

 四、感想

        在实践过程中,寻找IP查询接口耗费了很多时间,中途曾使用一些接口实现,但是后期又被封掉而转寻找其它方法。在实践中又逐渐遇到不懂的问题,又话费诸多精力找寻,最终得以实现。

        自己在学习中,时常遇到文中说着很容易就实现了,但是轮到自己的时候却怎么也搞不定的,最后才发现原来在文章中许多需要注意的小点没有说,还有功能的调式环境中实现与在实际环境中去部署也是相差很大,即使功能清晰了,但是在部署中也可能遇到比如环境依赖、先后顺序等小地方,如果没有说明白,也会得不到相应的结果。

        因此在借鉴和总结实际中的经验后,这里也将最终实际部署操作以及最终实现的放入文中,相信本文的阅读者拿到后,如果按照第三部分中的方法进行部署,那么只需要更改诸如实际的IP、收件邮箱等地方,相信一定能够实现查询IP源并向管理员推送的功能!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值