微信报警

微信报警原理流程

注册微信企业号,通过企业号提供的信息ID、以及获取微信的API接口,就可以将服务器的报警数据,发给API,发给微信,发给关注这个公众号的所有用户。
​
url 访问,拿人家这个url数据,是什么http method? ------get
bilibili.com/login
给这个url发请求,切提交你的账户密码http method---post
​
如何把你的zabbix数据,提交到微信这里
API(应用程序的接口)
(微信会提供一个URL给你,往这个URL发送http请求,post类型的请求,提交你的zabbix采集到的数据)
微信的服务器收到了你的请求,且,你这个请求,包含了如下内容
- 发给谁,具体的企业微信ID号3
- 发送的标题,正文等数据  
​
待会来看,如何发请求,且构造这些数据,
微信这里再把这些数据,发送你们的微信工作组(企业ID号)
​
3.以及获取微信的API接口,就可以将服务器的报警数据,发给API
​
4.发给微信,发给关注这个公众号的所有用户、这个组内的成员都收到消息了
​
微信中创建的zabbix应用的secret密钥
你注册的企业微信的id

注册企业微信

https://work.weixin.qq.com/wework_admin/frame

修改通讯录组名

image-20241002150501095

创建自定义zabbix应用

img

.查看企业ID

image-20241002150802332

微信报警架构图逻辑图

image-20241002150932049

添加通信群组成员

想让其他人也加入到这个组,便于接收消息,因此需要邀请加入组。
扫码加入企业
加入监控小分队即可。

image-20241002151041613

image-20241002151145635

分组的组ID

image-20241002152422785

关注监控公众号(无须下载企业微信了)

img

至此,微信的设置就结束了

刚才已经完成了,创建企业微信的账号,获取了企业号的id,以及创建了企业微信的一个zabbix小程序,获取了程序的id,和密钥

image-20241002151729345

接下来就是zabbix客户端的事了

下一步就来看,python,和bash两个风格的脚本,发请求。

推送报警信息(python)

[root@zabbix-server-71 /usr/lib/zabbix/alertscripts]# vim weixin_zabbix.py
#!/usr/bin/env python3
# Author: www.haloyang.top
​
import requests
import sys
import os
import json
import logging
​
# 日志格式构造
logging.basicConfig(level = logging.DEBUG, format = '%(asctime)s, %(filename)s, %(levelname)s, %(message)s',
                datefmt = '%a, %d %b %Y %H:%M:%S',
                filename = os.path.join('/tmp','weixin_python.log'),
                filemode = 'a')
# 企业ID
corpid='ww76b67c7e3bea'
​
# 应用秘钥
appsecret='Z2LpWY2H15svWZXuXAzyxqCuGUWrDPKhhHvvnY'
​
# 应用id
agentid=1000002
​
# 获取身份令牌,用于和微信通信的认证
# 参考企业微信API文档https://developer.work.weixin.qq.com/document/path/90487
token_url='https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=' + corpid +'&corpsecret=' + appsecret
req=requests.get(token_url)
accesstoken=req.json()['access_token']
msgsend_url='https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=' + accesstoken
​
# 构造消息体
#touser=sys.argv[1]
toparty=sys.argv[1]
subject=sys.argv[2]
​
# 发送微信消息的数据格式
message=sys.argv[2] + "\n\n" +sys.argv[3]
​
params={
        #"touser": touser,
        "toparty": toparty,
        "msgtype": "text",
        "agentid": agentid,
        "text": {
            "content": message
            },
    "safe":0
    }
​
# 最终发请求
req=requests.post(msgsend_url, data=json.dumps(params))
# 调试请求发送结果
print(req.content)
# 记录日志
logging.info('sendto:' + toparty + ';;subject:' + subject + ';;message:' + message)

测试发微信(python)

# 参数1是发给哪个部门
# 参数2是主题
# 参数3是消息正文
​
# 装好所需模块
[root@zabbix-server-71 ~]##yum install python3 python3-devel python3-pip 
[root@zabbix-server-71 ~]##pip3 install requests 
​
# 发给部门消息
[root@zabbix-server-71 ~]##python3 weixin_zabbix.py 2 "zabbix微信报警测试" "当前使用python脚本发送,发送人www.haloyang.top"

坑记录,添加ip白名单

# 踩坑了,tmd,需要加入自建应用的ip白名单
# https://open.work.weixin.qq.com/devtool/query?e=60020

image-20241002154800187

python3版本的坑

#!/usr/bin/env python3
别忘记,修改脚本的python解释器!!

推送报警信息(bash)

[root@zabbix-server-71 /usr/lib/zabbix/alertscripts]# vim weixin_zabbix.sh
#!/bin/bash
# Authror: www.haloyang.top
#需要将下列信息修改为自己注册的企业微信信息 #应用ID
agentid='1000002'
​
#secretID
corpsecret='Z2LpWYv2tswSWZXuXAzyxqCuGUWrDPKhhHvvnY' 
​
#企业ID 
corpid='ww76b673e3bea'
​
#接受者的账户,由zabbix传入 
#user=$1
​
#报警邮件标题,由zabbix传入 
title=$2 
​
#报警邮件内容,由zabbix传入 
message=$3
​
#接收信息的组
# 消息发给哪个组
# linux0224小分队,组id是1
group=$1 
​
#获取token信息,需要在链接里带入ID
​
# 如下2段代码,需要结合着跑
# -s 安静执行
# -X GET 制定GET请求访问
# "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${corpid}&corpsecret=${corpsecret}"
# 这就是一个url,但是url是变量替换的一个字符串
# 你发送你的企业id号,和应用id号,发给微信的服务器,微信服务器会返回给你一个身份令牌字符串
# 下一步,你就可以用这个字符串代表你的身份,是有权限和微信的公众号通信了
​
#这段代码是获取身份校验值,代表这个客户端是有权限和微信API通信的
token=$(curl -s -X GET "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${corpid}&corpsecret=${corpsecret}"|awk -F \" '{print $10}')
​
#构造语句执行发送动作,发送http请求
# 这个curl的作用详解
# 1.发送json类型的一堆数据
# 2.传入 部门id得值,脚本的第一个参数
# 3. 传入微信创建的应用的id
# 4. 传入text,消息数据体,分别是  title 和俩换行 和 message数据体
# 5.最终你运行这个脚本的方式是 
# bash  zabbix.sh 1  "牛逼"  "今天正式玩一玩,生产级别的消息发送脚本"
​
curl -s -H "Content-Type: application/json" -X POST "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${token}" -d' {
   "toparty" : "'"${group}"'",
   "msgtype" : "text",
   "agentid" : "'"${agentid}"'",
   "text" : {
       "content" : "'"${title}\n\n${message}"'"
   },
   "safe":0
}' >> /tmp/weixin_bash.log
​
#将报警信息写入日志文件
echo -e "\n报警时间:$(date +%F-%H:%M)\n报警标题:${title}\n报警内容:${message}" >> /tmp/weixin_bash.log

详细解bash脚本

image-20220708151759855

手工拆解代码执行

[root@zabbix-server-71 ~]#corpid='ww76b67c7a9e3e3bea'
[root@zabbix-server-71 ~]#agentid='1000003'
[root@zabbix-server-71 ~]#corpsecret='mrZiPnSDsod_DPVcF-TTyCtz6BCwKGSPX8ksb4nw-KY' 
​
客户端发出了请求,获取token值
微信的服务器,返回了一串json数据给你
​
[root@zabbix-server-71 ~]#curl -s -X GET "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${corpid}&corpsecret=${corpsecret}"
​
{"errcode":0,"errmsg":"ok","access_token":"E9DzfQc-QTREb33YGcJVvm6e9PKFZo-75PF_UW5fNcCdP9_XNbpczHgtT9Cqjlt4FGIXCCgsXRegMeNpYhk3Z4Vj6-njUMR-FCm2XEess3_pH9VYq557cj6cG4yL0vByyoQ9NY56s-LJzP7bZViZigPT8HN1pDK3WU69ALMwpiCJ3y8DgK2fW2SNi3f4h1vPKS87Xo_iT6iUZYuF7Zry1Q","expires_in":7200}
​
awk提取token字符串值
​
[root@zabbix-server-71 ~]#curl -s -X GET "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${corpid}&corpsecret=${corpsecret}"  |   awk -F \"   '{print $10}'
​
E9DzfQc-QTREb33YGcJVvm6e9PKFZo-75PF_UW5fNcCdP9_XNbpczHgtT9Cqjlt4FGIXCCgsXRegMeNpYhk3Z4Vj6-njUMR-FCm2XEess3_pH9VYq557cj6cG4yL0vByyoQ9NY56s-LJzP7bZViZigPT8HN1pDK3WU69ALMwpiCJ3y8DgK2fW2SNi3f4h1vPKS87Xo_iT6iUZYuF7Zry1Q

image-20241002155319014

image-20241002155304053

bash发报警测试

[root@zabbix-server-71 ~]##bash weixin.sh 2 "bash还是不如python美丽啊" "bash发送报警了!!"

注意:记得添加企业微信ip白名单

最终微信效果

img

zabbix页面配置微信报警

脚本发送报警信息,调试通过后,最终还是希望zabbix实现报警触发。

添加报警媒介类型

管理 > 报警媒介类型 > 创建媒体类型

添加报警参数,参考zabbix官网文档
https://www.zabbix.com/documentation/3.4/zh/manual/config/notifications/media/script
宏参数查询
https://www.zabbix.com/documentation/3.4/zh/manual/appendix/macros/supported_by_location

zabbix配置文件设置目录

需要告诉zabbix,你自定义的脚本在什么目录

1. 需要设置zabbix-server的配置文件,在/etc/zabbix/zabbix_server.conf文件追加一条定义脚本存储的文件夹AlertScriptsPath=/usr/lib/zabbix/alertscripts,这样zabbix才能去这里去找到脚本且执行。
​
[root@zabbix-server-71 ~]#grep  '^AlertScriptsPath' /etc/zabbix/zabbix_server.conf 
AlertScriptsPath=/usr/lib/zabbix/alertscripts
​
[root@zabbix-server-71 /usr/lib/zabbix/alertscripts]#ls
weixin_zabbix.sh  weixin_zabbix.py
​
2. bash py的脚本放入该目录即可,还得注意权限。。。太坑了。
[root@zabbix-server-71 /usr/lib/zabbix/alertscripts]#chown zabbix.zabbix weixin_zabbix.py 
[root@zabbix-server-71 /usr/lib/zabbix/alertscripts]#chown zabbix.zabbix weixin_zabbix.sh
[root@zabbix-server-71 /usr/lib/zabbix/alertscripts]#chmod +x weixin_zabbix.py
[root@zabbix-server-71 /usr/lib/zabbix/alertscripts]#chmod +x weixin_zabbix.sh
#提醒,少一步都是坑,哈哈哈,辛酸;特别是设置文件的权限
[root@zabbix-server-71 /usr/lib/zabbix/alertscripts]#ll
total 8
-rwxr-xr-x 1 zabbix zabbix 1510 Oct  2 18:50 weixin_zabbix.py
-rwxr-xr-x 1 zabbix zabbix 2147 Oct  2 18:49 weixin_zabbix.sh
​
3. 去zabbix-UI界面添加即可。

用户设置报警媒介

请注意,这里的收件人,是指微信的组,或者微信的联系人!
传入的参数,我这里是传入的1,是zabbix监控小组的ID。
脚本参数:
{ALERT.SENDTO}
{ALERT.SUBJECT}
{ALERT.MESSAGE}

image-20241002190956443

image-20241002191601050

完结收工(测测微信有报警吗)

[root@zabbix-server-71 ~]#ab -c 100 -n 100000 http://10.0.0.7/
​
可以检测日志
tail -f /tmp/weixin.log 
​
Sat, 02 Oct 2024 22:16:45, connectionpool.py, DEBUG, Starting new HTTPS connection (1): qyapi.weixin.qq.com:443
Sat, 02 Oct 2024 22:16:45, connectionpool.py, DEBUG, https://qyapi.weixin.qq.com:443 "GET /cgi-bin/gettoken?corpid=ww76b67c7a9e3e3bea&corpsecret=Z2LpWY2H15sv2tswSWZXuXAzyxqCuGUWrDPKhhHvvnY HTTP/1.1" 200 277
Sat, 02 Oct 2024 22:16:45, connectionpool.py, DEBUG, Starting new HTTPS connection (1): qyapi.weixin.qq.com:443
Sat, 02 Oct 2024 22:16:46, connectionpool.py, DEBUG, https://qyapi.weixin.qq.com:443 "POST /cgi-bin/message/send?access_token=_tIBkDweSW5UD0RoNnkuNQp0hmBe8ILlEUb6l3gdZuLVOArculwDJRiXy02chWt7VgQNHi6KFhU7Vu16lwwMqnEvRYL0n-ttIy33PmUt0ohiV5tUXc6rBOWCT1ZKH6TDHZAlospAUzVtVCdmcGxahiNLherauix-wX4K8gLYnsWdu50QxMA-ksViff-qDI4nc0ISrSxBgOa_338Pf_Ss_A HTTP/1.1" 200 124
Sat, 02 Oct 2024 22:16:46, weixin_zabbix.py, INFO, sendto:2;;subject:恢复OK, 服务器:web7: TIME_WAIT连接数太多已恢复!;;message:恢复OK, 服务器:web7: TIME_WAIT连接数太多已恢复!
​
Author: www.haloyang.top
告警主机:web7
告警时间:2024.10.02 22:15:42
告警等级:Warning
告警信息: TIME_WAIT连接数太多
告警项目:tcp_status[TIME_WAIT]
问题详情:TIME_WAIT监控:64
当前状态:OK:64
事件ID:94


钉钉报警

钉钉报警原理流程

和微信报警类似,发送指定的数据到钉钉官方提供的API接口,钉钉会将报警信息,发送到指定的钉钉群聊,提醒所有的群成员查看,实现告警通知。

img

具体操作流程

  • 创建钉钉群聊

  • 创建自定义机器人

  • 创建报警关键词

  • 生成webhook认证信息

  • 开发报警脚本

  • 填写zabbix-UI界面的配置

  • 测试钉钉报警通知

什么是API,以及什么叫给API发请求

image-20241002195511766

API会返回给你什么

image-20220711102728337

API 会返回什么给你,请看

  1. 可能返回一个html给你,zabbix是返回的字符串,html

  2. 可能返回一个json数据(字符串)给你,微信,钉钉API就是这么玩的。

先看微信API,返回的json数据

# 吧报警数据,发到微信,发到你的微信小组
#就是这一段代码
curl -s -H "Content-Type: application/json" -X POST "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${token}" -d' {
   "toparty" : "'"${group}"'",
   "msgtype" : "text",
   "agentid" : "'"${agentid}"'",
   "text" : {
       "content" : "'"${title}\n\n${message}"'"
   },
   "safe":0
}'
​
发出get类型的请求,看看是什么结果
2个方式
给这个API,发出get类型的请求
curl 访问 ,方式1
用浏览器直接访问,方式,get类型
​
https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${token}

再看zabbix的API,返回的结果

image-20220711102948634

image-20220711103851469

image-20241002201618852

纠正,form-data和json数据提交,是两种数据构造类型

1. zabbix的登录页面,登录请求,发出http请求,看响应结果
携带着数据提交的get请求,form-data类型
​
2. 微信的API,发出http请求,看响应结果
携带着数据提交的get请求
(微信这个,的确是,请求传入的数据,就是json类型的字符串,响应的数据,也是json类型的数据)
json是一个网络中传输数据的,数据结构类型

form-data zabbix用的是这个类型,表单数据提交,账户密码,也依然是key:value类型

form-data类型的数据提交,如图

zabbix的登录页面

image-20220711110415788

纯json的数据构造提交

你去理解,如何通过浏览器的抓包工具,分析请求的具体协议类型。

image-20220711110803985

创建群聊机器人

创建群聊自定义机器人

保存好你的webhook地址后面脚本中会用到

添加zabbix钉钉机器人

机器人文档 https://open.dingtalk.com/document/org/application-types 用户可以向这个webhook地址发起post请求,提交数据,也就是等于给钉钉发消息了,注意字符集编码

测试webhook地址

# 提交json类的数据,发给钉钉的API
​
[root@zabbix-server-71 ~]#curl  -H 'Content-Type: application/json' \
-d '{"msgtype": "text",  "text": {"content": "zabbix 报警测试,来自于www.haloyang.top"}}' \
'机器人的webhook地址'
​
# 拿到了结果
{"errcode":0,"errmsg":"ok"}

image-20241002204058832

支持更多功能参数,如圈某人看消息

# 参考钉钉机器人API的文档,支持哪些参数,参考用法如下
https://open.dingtalk.com/document/robots/custom-robot-access

img

# shell发请求 ,注意json数据格式,以及zabbix触发关键字
​
# 圈人语法,基于手机号
curl '机器人的webhook地址' \
-H 'Content-Type: application/json' \
-d  '{"at":{"atMobiles":["要@人的手机号"],"isAtAll":false},"text":{"content":"正在测试zabbix钉钉报警机器人!!"},"msgtype":"text"}'
​
# 圈人语法2,基于UserIds,员工ID,但是需要管理员查看,用户自己不好尝试了

image-20241002204627145

钉钉发消息脚本

python版

注意,该脚本是python3,你的目标机器,是否支持python3

yum install python3 python3-devel  python3-pip -y
​
pip3 install requests
#!/usr/bin/python3
# coding: utf-8
# about zabbix python script
# Author: www.haloyang.top
​
import requests,json,sys,os,datetime
# 钉钉机器人API
webhook_url="机器人的webhook地址"
​
# 给脚本参数手机号参数1
user_phone=sys.argv[1]
​
# 参数2,消息正文
text=sys.argv[2] + "\n\n" + sys.argv[3]
​
# 构造json数据体
data={
    "msgtype":"text",
    "text":{
        "content":text
    },
    "at":{
        "atMobiles":[user_phone],
        "isAtAll":False
    }
}
​
# 请求头,表明请求类型是json
headers={"Content-Type":"application/json"}
​
# 发HTTP请求,POST方式,传入数据与请求头
response=requests.post(url=webhook_url,data=json.dumps(data),headers=headers)
print(response.content.decode())
​
# 日志目录生成
if os.path.exists("/tmp/dingding.log"):
    with open("/tmp/dingding.log","a+") as f:
        print("该文件以存在,追加写入中")
        if response.json().get("errcode")==0:
            f.write("\n" + str(datetime.datetime.now()) + "    " + str(user_phone) + "    " + "发送成功" + "\n" + str(text) )
        else:
            f.write("\n" + str(datetime.datetime.now()) + "    " + str(user_phone) + "    " + "发送失败" + "\n" + str(text) )
else:
    with open("/tmp/dingding.log","w+") as f:
        print("该日志文件不存在,创建且写入中")
        if response.json().get("errcode")==0:
            f.write("\n" + str(datetime.datetime.now()) + "    " + str(user_phone) + "    " + "发送成功" + "\n" + str(text) )
        else:
            f.write("\n" + str(datetime.datetime.now()) + "    " + str(user_phone) + "    " + "发送失败" + "\n" + str(text) )

执行测试结果

[root@m-61 /tmp]#python3 ding.py 15210858004 "python测试钉钉机器人" "zabbix故障了!!抓紧起来修复啊!!火星撞地球了!!"
​
#拿到结果了
b'{"errcode":0,"errmsg":"ok"}'
该文件以存在,追加写入中
​
#错误结果
{"errcode":310000,"errmsg":"错误描述:关键词不匹配;解决方案:请联系群管理员查看此机器人的关键词,并在发送的信息中包含此关键词;"}

钉钉结果

image-20241002210856722

bash版

#!/bin/bash
# about zabbix bash script
# Author: www.haloyang.top
​
#webhook 地址 webhook=''
#接受者的手机号,由 zabbix 传入 
user=$1
#报警邮件标题,由 zabbix 传入 
title=$2
#报警邮件内容,由 zabbix 传入
message=$3
​
# 构造语句执行发送动作
# bash就是用curl 构造json数据发出去而已,注意引号的细节就好
# 通过API返回的数据,来确认是否发送正确
​
curl -s -H "Content-Type: application/json" -X POST "机器人的webhook地址" -d '{"msgtype":"text","text":{"content":"'"${title}\n\n${message}\n\nzabbix报警啦"'"},"at":{"atMobiles":["'"${user}"'"],"isAtAll":false}}' 
​
#将报警信息写入日志文件
echo -e "\n 报警时间:$(date +%F-%H:%M)\n 报警标题:${title}\n 报警内容:${message}" >> /tmp/ding_bash.log

测试运行

[root@zabbix-server-71 /usr/lib/zabbix/alertscripts]#bash ding_zabbix.sh 15210858004 'web-7 报警了!' 'nginx挂了!'
​
#拿到结果
{"errcode":0,"errmsg":"ok"}

钉钉结果

image-20241002212415845

zabbix-UI页面配置钉钉报警

脚本调通后,就可以去zabbix的UI页面配置参数,提供报警

思路依然是
创建报警媒介类型
↓
创建媒体类型
↓
钉钉报警创建
↓
用户选择报警媒介方式

创建媒体类型

脚本参数:
{ALERT.SENDTO}
{ALERT.SUBJECT}
{ALERT.MESSAGE}

image-20241002213555505

注意坑

1.脚本放入zabbix目录,采用python脚本,闲的更nb
​
2.脚本权限
[root@zabbix-server-71 /usr/lib/zabbix/alertscripts]#chown zabbix.zabbix ding_zabbix.py 
[root@zabbix-server-71 /usr/lib/zabbix/alertscripts]#chown zabbix.zabbix ding_zabbix.sh
[root@zabbix-server-71 /usr/lib/zabbix/alertscripts]#chmod +x ding_zabbix.py 
[root@zabbix-server-71 /usr/lib/zabbix/alertscripts]#chmod +x ding_zabbix.sh 
​
[root@zabbix-server-71 /usr/lib/zabbix/alertscripts]#ll
total 16
-rwxr-xr-x 1 zabbix zabbix 1747 Oct  2 21:07 ding_zabbix.py
-rwxr-xr-x 1 zabbix zabbix  887 Oct  2 21:19 ding_zabbix.sh
​
3.日志文件权限
[root@zabbix-server-71 /tmp]#rm -rf /tmp/*.log

用户选择报警媒介(钉钉)

image-20241002214604541

坑记录,最后一步zabbix调用python发报警,别忘记关键字

给zabbix中的动作,添加关键字即可,否则无法触发钉钉机器人

image-20241002214853725

image-20241002215052643

最后测试

报警通知

image-20241002215356824

问题修复通知

image-20241002215542143