Zabbix配置动作执行远程命令和发送邮件

2019-07-27 20:05:49 浏览数 (1)

凡百元首,承天景命。善始者实繁,克终者盖寡。 ——《谏太宗十思疏》

当zabbix有事件发生,我们可以根据事件来执行相应的动作,根据事件来源可以分为触发器动作,自动发现动作,自动注册动作,内部事件动作,自动发现动作在之前的自动发现那里讲过了,这里介绍一下触发器动作,当触发器事件达到执行动作的必要条件,会执行相应的动作。

配置邮件告警动作

首先创建一个触发器动作,触发报警会发送邮件

定义动作触发条件

定义动作执行的操作,这里是执行发送消息的操作,步骤1-5表示会发送5次消息,默认每次的间隔是30分钟

这里我们定义了1-5步执行的操作,就是每隔30分钟,将消息通过‘zabbix_send.py’这个脚本发送给Admin用户

如果问题两个小时之内没有确认,则会将在两个小时之后每隔十五分钟一次通知zabbix管理组,共发送两次消息

这里看到两个操作的步骤五重叠了,这里较短的自定义步骤持续时间为10分钟的会覆盖较长的步骤持续时间,也就是说第二个操作的5步骤会覆盖第一个操作的5步骤

定义恢复操作,问题解决之后会发送消息给Admin用户

定义更新操作,当其他用户更新问题时收到通知,比如问题被关闭,或者问题严重程度发生变化

到这里动作部分就完成了,如果要让其成功发送邮件,还需要配置用户和报警媒介

配置用户

配置用户报警媒介

配置用户的收件人等信息

创建报警媒介类型

配置报警媒介类型,传入的三个参数分别为收件人,邮件主题,邮件内容

zabbix邮件报警的web界面配置完成了,还需要修改zabbix_server的配置文件,来支持使用脚本 vim/etc/zabbix/zabbix_server.conf

AlertScriptsPath=/usr/lib/zabbix/alertscripts

修改完成后重启zabbix-server 在/usr/lib/zabbix/alertscripts目录下添加要使用的报警脚本 并给邮件授予执行权限 chmod xzabbix_send.py

创建一个graph目录,并授予权限 mkdir graphchmod 777 -R graph

邮件内容及详细注释如下:

代码语言:javascript复制
#!/usr/bin/python#coding=utf-8from email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom email.mime.image import MIMEImageimport smtplib,sys,os,time,re,requestsfrom smtplib import SMTP

user='Admin'    #定义zabbix用户名password='zabbix'    #定义zabbix用户密码graph_path='/usr/lib/zabbix/alertscripts/graph'   #定义图片存储路径graph_url='http://192.168.179.132/chart.php'     #定义图表的url#api_url ="http://10.127.0.119/api_jsonrpc.php"    #定义api的url#header = {"Content-Type":"application/json" }     #定义api的headersloginurl="http://192.168.179.132/index.php"          #定义登录的urlhost='192.168.179.132'to_email=sys.argv[1]    #传入的第一个参数为收件人邮箱subject=sys.argv[2]  #传入的第二个参数为邮件主题  subject=subject.decode('utf-8')
smtp_host = 'smtp.163.com'  #定义smtp主机地址from_email = 'wanger@163.com'     #定义发件人地址mail_pass = 'asd1234'       #发件人邮箱校验码def get_itemid():
   #获取报警的itemid
   itemid=re.search(r'ITEM ID:(d )',sys.argv[3]).group(1)   return itemiddef get_graph(itemid):
   #获取报警的图表并保存
   session=requests.Session()   #创建一个session会话
   try:
       loginheaders={            
       "Host":host,            
       "Accept":"text/html,application/xhtml xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
       }       #定义请求消息头

       payload = {            
       "name":user,       "password":password,  
       "autologin":"1",            
       "enter":"Sign in",
       }       #定义传入的data
       login=session.post(url=loginurl,headers=loginheaders,data=payload)       #进行登录
       graph_params={           "from" :"now-10m",            "to" : "now",          
           "itemids" : itemid,                      
           "width" : "400",
       }       #定义获取图片的参数
       graph_req=session.get(url=graph_url,params=graph_params)       #发送get请求获取图片数据
       time_tag=time.strftime("%Y%m%d%H%M%S", time.localtime())
       graph_name='baojing_' time_tag '.png'
       #用报警时间来作为图片名进行保存
       graph_name = os.path.join(graph_path, graph_name)       #使用绝对路径保存图片
       with open(graph_name,'wb') as f:
           f.write(graph_req.content)           #将获取到的图片数据写入到文件中去
       return graph_name   except Exception as e:        
       print e        
       return Falsedef text_to_html(text):
   #将邮件内容text字段转换成HTML格式
   d=text.splitlines()  
   #将邮件内容以每行作为一个列表元素存储在列表中
   html_text=''
   for i in d:
       i=''   i   '<br>'
       html_text =i   'n'
   #为列表的每个元素后加上html的换行标签
   return html_textdef send_mail(graph_name):
   #将html和图片封装成邮件进行发送
   msg = MIMEMultipart('related')  #创建内嵌资源的实例

   with open(graph_name,'rb') as f:       #读取图片文件
       graph=MIMEImage(f.read())  #读取图片赋值一个图片对象
   graph.add_header('Content-ID','imgid1')  #为图片对象添加标题字段和值
   text=text_to_html(sys.argv[3])
   html="""
   <html>
     <body>
     %s  <br><img src="cid:imgid1">
     </body>
   </html>
   """ % text
   html=MIMEText(html,'html','utf-8')  #创建HTML格式的邮件体
   msg.attach(html)   #使用attach方法将HTML添加到msg实例中
   msg.attach(graph)  #使用attach方法将图片添加到msg实例中
   msg['Subject'] = subject
   msg['From'] = from_email   try:
       server=SMTP(smtp_host,"25")   #创建一个smtp对象
       server.starttls()    #启用安全传输模式
       server.login(from_email,mail_pass)  #邮箱账号登录
       server.sendmail(from_email,to_email,msg.as_string())  #发送邮件  
       server.quit()   #断开smtp连接
   except smtplib.SMTPException as a:       print adef run():
   itemid=get_itemid()
   graph_name=get_graph(itemid)
   send_mail(graph_name)if __name__ =='__main__':
   run()

配置执行远程命令的动作

当触发器达到阈值报警时,我们可以根据相关的报警来执行相关的命令使故障达到自我恢复的效果 这里我举一个ssh端口关闭并执行重启ssh的例子

在系统上配置

在zabbix客户端配置文件中取消注释下面语句,以支持zabbix客户端执行远程命令 vim /etc/zabbix/zabbix_agentd.conf EnableRemoteCommands=1 zabbix执行远程命令使用的是zabbix用户,确保’zabbix’用户具有已配置命令的执行权限。 vim/etc/sudoers

Defaults !requiretty #不需要提示终端登录

zabbix ALL=(ALL) NOPASSWD: ALL #允许'zabbix'用户在没有密码的情况下运行所有命令。

配置完成后,使用zabbix-get测试是否可以运行远程命令,如果返回数据,则表示远程命令可用

代码语言:javascript复制
zabbix_get -s 192.168.179.132 -k "system.run[sudo df -h]"
配置脚本

vim /restart_ssh.sh

代码语言:javascript复制
#/bin/bash
systemctl restart sshd

对脚本授予可执行权限 chmod x /restart_sshd.sh

创建ssh的监控项
创建触发器
配置动作

创建动作

配置动作触发条件

配置动作执行的命令,这里为了方便查看效果,延迟两分钟执行

触发报警

这里关闭ssh服务,使报警触发 systemctlstop sshd

报警触发,两分钟后执行脚本

这里可以使用zabbix-get来获取监控的值。来查看是否成功执行命令

代码语言:javascript复制
zabbix_get-s 192.168.179.132 -k net.tcp.port[192.168.179.132,22]

可以看到,zabbix已经成功执行脚本,重启ssh

0 人点赞