├── dingding.conf ├── zabbix_dingding.py ├── zabbix_dingding_sign.py └── README.md /dingding.conf: -------------------------------------------------------------------------------- 1 | [config] 2 | # 此文件注意权限 3 | # windows 路径示例: d:/zabbix_log/ 4 | log_dir=/data/logs/zabbix/ 5 | log_file=zabbix_dingding.log 6 | #配置图片实例,https://img.alicdn.com/top/i1/LB1lIUlPFXXXXbGXFXXXXXXXXXX 7 | webhook= 8 | # 安全设置 -- 加签 9 | secret= 10 | -------------------------------------------------------------------------------- /zabbix_dingding.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # My blog https://www.aityp.com 4 | 5 | import requests 6 | import json 7 | import sys 8 | import os 9 | import time 10 | import configparser 11 | 12 | headers = {'Content-Type': 'application/json'} 13 | time=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 14 | 15 | config=configparser.ConfigParser() 16 | config.read('/etc/zabbix/dingding.conf',encoding='utf-8') 17 | log_dir = config.get('config','log_dir') 18 | log_file = config.get('config','log_file') 19 | api_url = config.get('config','webhook') 20 | 21 | def log(info): 22 | #注意权限,否则写不进去日志 23 | file_path=log_dir + log_file 24 | if os.path.isdir(log_dir) == False: 25 | os.makedirs(log_dir) 26 | elif os.path.isfile(file_path) == False: 27 | f = open(file_path, 'a+') 28 | f = open(file_path,'a+') 29 | f.write(info) 30 | f.close() 31 | 32 | def msg(text,user): 33 | json_text= {"msgtype": "text","text": {"content": text},"at": {"atMobiles": [user],"isAtAll": False}} 34 | r=requests.post(api_url,data=json.dumps(json_text),headers=headers).json() 35 | code = r["errcode"] 36 | if code == 0: 37 | log(time + ":消息发送成功 返回码:" + str(code) + "\n") 38 | else: 39 | log(time + ":消息发送失败 返回码:" + str(code) + "\n") 40 | exit(3) 41 | 42 | if __name__ == '__main__': 43 | text = sys.argv[3] 44 | user = sys.argv[1] 45 | msg(text,user) -------------------------------------------------------------------------------- /zabbix_dingding_sign.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # My blog https://www.aityp.com 4 | # 此版本需要配置签名验证,只支持python3.x 5 | 6 | import requests 7 | import json 8 | import sys 9 | import os 10 | import time 11 | import hmac 12 | import hashlib 13 | import base64 14 | import urllib.parse 15 | import configparser 16 | 17 | headers = {'Content-Type': 'application/json'} 18 | log_time=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 19 | config=configparser.ConfigParser() 20 | config.read('/etc/zabbix/dingding.conf',encoding='utf-8') 21 | log_dir = config.get('config','log_dir') 22 | log_file = config.get('config','log_file') 23 | webhook = config.get('config','webhook') 24 | secret = config.get('config','secret') 25 | 26 | def log(info): 27 | #注意权限,否则写不进去日志 28 | file_path=log_dir + log_file 29 | if os.path.isdir(log_dir) == False: 30 | os.makedirs(log_dir) 31 | elif os.path.isfile(file_path) == False: 32 | f = open(file_path, 'a+') 33 | f = open(file_path,'a+') 34 | f.write(info) 35 | f.close() 36 | 37 | def msg(text,user): 38 | timestamp = int(round(time.time() * 1000)) 39 | secret_enc = secret.encode('utf-8') 40 | string_to_sign = '{}\n{}'.format(timestamp, secret) 41 | string_to_sign_enc = string_to_sign.encode('utf-8') 42 | hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest() 43 | sign = urllib.parse.quote_plus(base64.b64encode(hmac_code)) 44 | json_text= {"msgtype": "text","text": {"content": text},"at": {"atMobiles": [user],"isAtAll": False}} 45 | api_url = "%s×tamp=%s&sign=%s" % (webhook.strip('\''),str(timestamp),sign) 46 | r=requests.post(api_url,data=json.dumps(json_text),headers=headers).json() 47 | code = r["errcode"] 48 | errmsg = r["errmsg"] 49 | if code == 0: 50 | log(log_time + ":消息发送成功 返回数据:%s %s\n" % (code,errmsg)) 51 | else: 52 | log(log_time + ":消息发送失败 返回数据:%s %s\n" % (code,errmsg)) 53 | print(log_time + ":消息发送失败 返回数据:%s %s\n" % (code,errmsg)) 54 | exit(3) 55 | 56 | if __name__ == '__main__': 57 | text = sys.argv[3] 58 | user = sys.argv[1] 59 | msg(text,user) 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 环境要求 2 | 3 | #### python2.x python3.x zabbix 2.x 版本以上 dingding 4 | ##### 我刚刚学习python没多久,写的不是很好大神勿喷 😶😶😶 5 | ### 个人博客 6 | https://www.aityp.com 7 | 8 | --- 9 | ### 效果图🐐 10 | 11 | ![image](https://typ.oss-cn-shanghai.aliyuncs.com/markdown/2017/10/29/1.png) 12 | 13 | ### 版本选择 14 | |文件|说明 15 | |---|---| 16 | |zabbix_dingding.py| 机器人安全配置为网段 17 | |zabbix_dingding_sign.py|机器人安全配置为加签(推荐) 使用python3 18 | 推荐使用签名验证版本,更安全 19 | ### python配置 20 | 你的python3最好在`/usr/bin`下面,否则会找不到 21 | ``` 22 | ln -s python3 /usr/bin/python3 23 | ``` 24 | ### 安装configparser requests模块(需要PIP没有可以看下面安装) 25 | ``` 26 | #python2.x 27 | pip install configparser 28 | pip install requests 29 | 30 | #python3.x 31 | pip3 install configparser 32 | pip3 install requests 33 | ``` 34 | ### 安装pip 35 | ``` 36 | cd pip_install 37 | python get-pip.py 38 | ``` 39 | ### 钉钉配置 40 | 需要新建一个钉钉群,群里面添加一个机器人即可。 41 | #### 点击加入一个机器人 42 | ![image](https://typ.oss-cn-shanghai.aliyuncs.com/markdown/2017/10/29/11.png) 43 | 44 | #### 添加自定义机器人 45 | ![image](https://typ.oss-cn-shanghai.aliyuncs.com/markdown/2017/10/29/3.png) 46 | #### 设置机器人,记住`webhook`后面会用到 47 | ![image](https://typ.oss-cn-shanghai.aliyuncs.com/markdown/2017/10/29/4.png) 48 | #### webhook后面配置文件会用到! ! ! 安全配置选择加签 49 | ![](https://ddn-md.oss-cn-beijing.aliyuncs.com/images/md/2019/12/27/20191227163140.png) 50 | ---- 51 | 52 | #### pull代码 53 | ``` 54 | git clone git@github.com:typ431127/zabbix_dingding.git 55 | ``` 56 | 57 | #### 配置报警配置文件 58 | ``` 59 | cd zabbix_dingding 60 | mkdir -p /etc/zabbix/ 61 | mv dingding.conf /etc/zabbix/ 62 | ``` 63 | #### 编辑配置文件 64 | `/etc/zabbix/dingding.conf` 65 | ![](https://ddn-md.oss-cn-beijing.aliyuncs.com/images/md/2019/12/27/20191227165920.png) 66 | ``` 67 | [config] 68 | #此文件注意权限 69 | log_dir=/data/logs/zabbix/ 70 | log_file=zabbix_dingding.log 71 | #配置图片实例,https://img.alicdn.com/top/i1/LB1lIUlPFXXXXbGXFXXXXXXXXXX 72 | webhook=https://oapi.dingtalk.com/robot/send?access_token= 73 | secret= 74 | ``` 75 | - `webhook`是你新建机器人webhook,复制粘贴即可,这一步很重要. 76 | - `secret`是安全设置里面加签的key,复制粘贴即可 77 | 78 | #### 配置报警脚本 79 | 把`zabbix_dingding.py`放到你`zabbix_server`的`scripts`目录下面即可. 80 | 81 | #### 配置权限 82 | ``` 83 | chown zabbix:zabbix zabbix_dingding.py 84 | chmod +x zabbix_dingding.py 85 | touch /tmp/zabbix_dingding.log 86 | chown zabbix:zabbix /tmp/zabbix_dingding.log 87 | ``` 88 | 89 | ### zabbix web配置 90 | `管理`---`报警媒介类型`---`创建媒体类型` 91 | **配置如下** 92 | ![image](https://typ.oss-cn-shanghai.aliyuncs.com/markdown/2017/10/29/6.png) 93 | #### 用户添加报警媒介---`添加` 94 | ![image](http://typ.oss-cn-shanghai.aliyuncs.com/markdown/2017/10/29/7.png) 95 | 96 | **收件人是你的钉钉手机号** 97 | ![image](http://typ.oss-cn-shanghai.aliyuncs.com/markdown/2017/10/29/8.png) 98 | **动作配置** 99 | ![image](http://typ.oss-cn-shanghai.aliyuncs.com/markdown/2017/10/29/9.png) 100 | 101 | ### 手动触发报警 102 | ![image](http://typ.oss-cn-shanghai.aliyuncs.com/markdown/2017/10/29/10.png) 103 | 104 | ### 日志调试 105 | ``` 106 | cat /data/logs/zabbix/zabbix_dingding.log 107 | ``` 108 | ![](https://ddn-md.oss-cn-beijing.aliyuncs.com/images/md/2019/12/27/20191227170123.png) 109 | 图中所示错误为签名验证key错误,这个时候自行检查dingding.conf中secret配置是否与钉钉机器人中的key一样。 110 | 111 | ### QQ:1500698928 112 | ### 个人微信 113 | ![image](https://typ.oss-cn-shanghai.aliyuncs.com/markdown/2017/10/14.jpg?x-oss-process=image/resize,h_600) 114 | 115 | ### 问题调试方法 116 | 如果你的钉钉收不到消息可以使用以下方法进行调试 117 | 命令行调试脚本 118 | ``` 119 | python3 zabbix_dingding.py 1 2 3 120 | ``` 121 | --------------------------------------------------------------------------------