自动化运维之微信机器人

0x00 关于运维

1.何为运维?

运维(Operation and maintenance)一般是指对大型组织已经建立好的网络软硬件的维护,其中传统的运维是指信息技术运维(IT运维)。所谓IT运维管理,是指单位 IT 部门采用相关的方法、手段、技术、制度、流程和文档 等,对IT 运行环境(如软硬件环境、网络环境等)、IT 业务系统和 IT 运维人员进行的综合管理。

以上是网上关于运维的一些概念。

个人的理解运维就是为了最求一种稳定的结果,稳定又成为运维一切开始的基石。运维的一切工作都是围绕着稳定为努力的。无论你是搞网络还是搞系统,搞服务器硬件还是搞各种软件的,我们都在追求一种持续性的,高性能,可用的状态,这是我心中的运维。

运维者,高可用也。

2.运维都做什么工作?

运维的工作太多太多,做的了水晶头,装的了系统,扛得动服务器,正所谓文能调优写脚本,武能布网修机器。

说实话,接触运维没有多久,不过比较幸运的是从一个IDC的基础建设最后跟到了云服务的上线,这段经历也让自己能够接触运维的方面更加全面。

从时间的顺序来讲,运维最早的工作是在机房建设方面,这方面主要集中在物理层面包括机房的整体建设,综合部署网线与电线,ups设计等等。机房建设之后属于部署阶段,这期间包括安装操作系统,数据库和各种软件,网络交换机,路由器的调试等等。部署结束之后就是管理期,管理一个复杂而且不断持续和迭代的过程。

  1. 如何成为一个好的运维?

刘邦说:运筹帷幄之中,决胜千里之外。说的是张良子房。

我要说:运行维护之中,稳定千年之外。说的是每个运维。

随着科技的不断发展,对我们运维也提高了要求,从最早运维界提出的DevOps再到最近半年Google提出的SRE。

随着云的落地和docker的迅猛崛起,批量部署等自动化运维成为了运维的主流方向。

DevOps无论逼格多高,其实它归根结底就是一套工具链,它代表了开发、运维、测试等环节之间的协作。

常用的工具有Docker(容器化)、Jenkins(持续集成)、Vagrant(虚拟化平台)、Zabbix、Nagios、cacti和小米开源的OpenFalcon(监控工具)、OneAPM (性能分析)、ELK(日志分析)等等

如果把DevOps看成是一串项链,上面的工具是项链上的珍珠,那么自动化就是在这一串串珍珠串接起来的一根线。

0x02 监控的自动化

监控就想我们的眼睛,一个没有监控的运维就像一个身怀绝世武功的瞎子。功夫再高也怕飞刀。知己知彼不仅仅是运用在军事上,对于运维项目上也是需要知己知彼,才能立于不败之地。

这是我工作中经常要用的一款监控工具,是一款态势感知的优秀平台。也是我日常工作中的得力助手。

像大多数普通的监控一下该监控也支持邮件报警功能。但这个邮件报警功能还不是特智能。

前段时间,看到了一篇有的文章,关于使用hubot和slack制作运维机器人的故事,突发奇想,搞个微信机器人来接受报警的系统是不是会更有意思?

微信机器人接受警信息,主要的流程大致是这样:

1.通过邮件协议获取邮箱里的邮件。

2.微信机器人把获取到的邮件内容转发送出去。

既然这样,说干就干。

0x03 获取邮件内容

根据邮件协议从邮件服务器上获取邮件可以通过pop3和imap两种方法实现,最开始用的是poplib这个模块,不过后来发现imaplib这个模块功能更多。

首先导入imaplib。

 import imaplib

使用IMAP4协议和用户名密码登录邮箱。

conn = imaplib.IMAP4(imapserver,143)
conn.login(username, password)

select选择邮箱INBOX是默认的收件箱。

conn.select("INBOX")

search搜索邮箱里的邮件 (None, ‘ALL’)表示全部。

state, data = conn.search(None, 'ALL')

设定两个变量分别获取state和data。

state 是从邮箱中返回的状态吗OK,代表已经获取成功。

data 返回的是一个数组,里面的数字对应着邮箱的邮件编号。

['1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57']

通过split()函数将data转变成list。

elist = data[0].split()

通过fetch获取邮件的内容。RFC822表示邮件按照RFC822的格式。

state,data=conn.fetch(elist[len(elist)-1],'(RFC822)')

得到一封MIME标准的邮件,只要对python的email模块其进行解析就可以。

首先导入email模块

import email

然后通过email.message_from_string将邮件内容转化成message对象。

msg=email.message_from_string(data[0][1])

通过get_payload(decode=True)获取邮件的内容。

msg_content=msg.get_payload(decode=True).decode('utf-8')

打印一下内容。

已经变成html格式啦。

0x04 解析出邮件文本内容

html获取文本主要有三种方式:

1.正则表达式

2.Beautiful Soup 4

3.HTMLParser模块

分析html结构发现获取文本非常简单,使用python自带的HTMLParser模块即可。

from HTMLParser import HTMLParser
handle_starttag(tag, attrs)

处理开始标签,比如

handle_data(data)

处理数据,标签之间的文本

class MyHTMLParser(HTMLParser):  
def __init__(self):
    pass  
def handle_starttag(self, tag, attrs):
    pass
def handle_data(self,data):
    pass

通过分析前面的html代码发现,文本是从标签开始的一直到结尾,这样只要能够匹配到第一个文本前的标签就能将它们全部获取。

<table width="600px;" border="0" cellpadding="0" cellspacing="1" bgcolor="#E5E5E5" style="font-size:14px;line-height:21px;border-radius: 0.5rem;"><tr bgcolor="#ECF4F7"">
<td height="
50px;" align="center" colspan="2" style="color:#0066ff;font-size:21px;">36.110.xxx.xxx攻击事件报告</td>
class MyHTMLParser(HTMLParser):  
    def __init__(self):  
        HTMLParser.__init__(self)  
        self.flag = False  
        self.list = []
    def handle_starttag(self, tag, attrs):

        if tag == 'td':
            for (variable, value) in attrs:
                if variable == 'style':
                    self.flag = True
    def handle_data(self,data):
        if self.flag:
            self.list.append(data)

实例化MyHTMLParser(),将上文得到的邮件数据msg_content传入进去,进行解析。

parser = MyHTMLParser()
parser.feed(msg_content)
parlist = parser.list
emailtext = ''.join(parlist)

这样就把全部的文本内容获取出来了。

自认为一个安静的美男子,这么丑的东西我是不会拿出去给人看的。

这么看就似乎完美了,我们再来搞一下微信机器人。

0x05 属于我的微信机器人

Itchat是一个比较强大的第三方库,用来模拟微信的web登录,可以用它来做好多有意思的东西,比如可以接入小黄鸡聊天的api让他做一个痞痞的聊天机器人,或者可以通过天气的api变成天气预报小管家,甚至可以做防撤回等。

pip install itchat

安装之后导入itchat模块,并且使用auto_login()方法登录。

itchat.auto_login()

从好友列表里找到叫大叔的男人,并且把大叔设置为接受报警信息的对象。

admin = itchat.search_friends(name=u'大叔')
admin = admin[0]['UserName']

注册消息,只要给微信机器人发送报警邮件,机器人就可以自动返回报警的信息。

@itchat.msg_register(itchat.content.TEXT)
def reply_text(msg):
    if u'报警邮件' in msg['Text']:
        itchat.send_msg(alarmInfo, msg['FromUserName'])

最后的结果

另外如果觉得每次都需要主动获取报警信息太过麻烦,可以让它按照定时发送报警邮件信息。

代码我上传到了github上,需要的可以去下载。如果有什么好的建议和想法欢迎一切讨论。

0x06 相关资料

http://itchat.readthedocs.io/zh/latest/

https://docs.python.org/2/library/imaplib.html#module-imaplib

https://docs.python.org/2/library/email.html#module-email

https://docs.python.org/2/library/htmlparser.html#module-HTMLParser

https://github.com/AI-Uncle/WXBOT/blob/master/itchatemail.py

本站所有文章均为原创,转载请注明出处

更多技术文章,敬请关注猎户安全实验室微信公众号:

发表评论

电子邮件地址不会被公开。 必填项已用*标注