python 监控服务端口并发送钉钉和邮件v1.0
基本逻辑
- 把ip+ports定义到json文件
- 加载json文件
- 循环json文件里面定义的多主机端口
- 开启socket线程监测端口是否监听
- 异常时直接通知钉钉同时把异常ip+port写入文件
- 邮件附件发送异常文件
说明
本脚本只是能监测服务端口是否开启,无法监测服务是否健康。只能做个简单的监控。
文件目录介绍
目录/opt/tools/monitoring/
[root@localhost rc]# tree -L 1
.
├── crontab.sh #定时任务脚本
├── ip_port.json # 定义主机和端口(多台服务器)
├── jk002.py #python 脚本
└── temp # 异常端口和ip写入temp目录下的文件,邮件附件发送
1 directory, 3 files
[root@localhost rc]#
crontab.sh 源码
#!/bin/bash
cd /opt/tools/monitoring/
python jk002.py
ip_ports.json 文件定义
{
"rlszw_dev": {
"10.21.22.102": {
"ssh": 22,
"mysql": 3306,
"show": 8099,
"appInterface": 8098,
"mis": 8097,
"ass": 8096,
"share": 8095,
"ddm": 8094,
"dctrl": 8093,
"cas_server": 8092,
"integration": 8091,
"lszw_nginx": 8180,
"cas_nginx": 8181,
"dcmqttd": 18700,
"acadgrpc": 18600
}
}
jk002.py源码
# -*- coding:utf8 -*-
import socket
import time
import os
import thread
import json
import urllib2
import sys
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
reload(sys)
sys.setdefaultencoding('utf-8')
socket.setdefaulttimeout(1)
date = time.strftime("%Y%d%m%H%M")
file = './temp/'+date+'result.'+'txt'
def dingding(tokenid, subject, message):
url = "https://oapi.dingtalk.com/robot/send?access_token=" + tokenid
header = {
"Content-Type": "application/json",
"charset": "utf-8"
}
data = {
"msgtype": "text",
"text": {
"content": subject + '\n' + message
},
"at": {
"atMobiles": [
"1518*****"
# "1352*****"
# "1519*****",
# "1510*****",
# "1833*****"
],
"isAtAll": False
}
}
sendData = json.dumps(data)
request = urllib2.Request(url, data=sendData, headers=header)
urlopen = urllib2.urlopen(request)
return urlopen.read()
def socket_port(ip, port):
"""
输入IP和端口号,扫描判断端口是否开放
"""
try:
if port >= 65535:
print u'端口扫描结束'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = s.connect_ex((ip, port))
message = str(port)
if result == 0:
lock.acquire()
print ip, u':', port, u'端口开放'
# write_result(ip.encode("utf-8")+':'+message+'端口开放')
lock.release()
else:
lock.acquire()
print ip, u':', port, u'端口异常,开始发送钉钉通知'
tokenid = "************" #钉钉机器人tokenid
subject = ip.encode('utf-8')+'主机'
message = str(port).encode('utf-8')+'端口异常'
dingding(tokenid, subject, message)
write_result(ip.encode("utf-8")+':'+message+'端口异常')
lock.release()
s.close()
except Exception, e:
print str(e)
def ip_scan(ip, ports):
"""
输入IP,扫描IP的0-65534端口情况
"""
try:
print u'开始扫描 %s' % ip
start_time = time.time()
for i in ports:
# print i
# print type(i)
thread.start_new_thread(socket_port, (ip, i))
time.sleep(2)
print u'扫描端口完成,总共用时 :%.2f' % (time.time() - start_time)
# raw_input("Press Enter to Exit")
except Exception, e:
print str(e)
def send_mail():
# 第三方 SMTP 服务
mail_host = "smtp.163.com" # 设置服务器
mail_user = "******@163.com" # 用户名
mail_pass = "**********" # 口令
sender = '*************@163.com'
receivers = ['********@qq.com','*******@qq.com'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱
message = MIMEMultipart()
# message = MIMEText('我们的工作基本一致', 'plain', 'utf-8')
message.attach(MIMEText('服务端口监控', 'plain', 'utf-8'))
message['From'] = sender
message['To'] = ','.join(receivers)
subject = '服务端口监控'
message['Subject'] = Header(subject, 'utf-8')
# 附件
# 构造附件1,传送当前目录下的 test.txt 文件
att1 = MIMEText(open(file, 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
# 这里的filename可以任意写,写什么名字,邮件中显示什么名字
att1["Content-Disposition"] = 'attachment; filename="result.txt"'
message.attach(att1)
# # 构造附件2,传送当前目录下的 runoob.txt 文件
# att2 = MIMEText(open('runoob.txt', 'rb').read(), 'base64', 'utf-8')
# att2["Content-Type"] = 'application/octet-stream'
# att2["Content-Disposition"] = 'attachment; filename="runoob.txt"'
# message.attach(att2)
try:
smtpObj = smtplib.SMTP()
smtpObj.connect(mail_host, 25) # 25 为 SMTP 端口号
smtpObj.login(mail_user, mail_pass)
smtpObj.sendmail(sender, receivers, message.as_string())
print "邮件发送成功"
except Exception, e:
print str(e)
def write_result(result):
# print file
with open(file, 'a') as f:
f.write(result+'\n')
if __name__ == '__main__':
# url = raw_input('Input the ip you want to scan:\n')
lock = thread.allocate_lock()
# port = [3389, 22, 43, 135, 137]
# ip = "127.0.0.1"
with open("./ip_port.json", 'r') as f:
data = json.load(f)
for env_key in data:
for ip_key in data[env_key]:
ip = ip_key
ports = data[env_key][ip_key]
key_list = list(ports.keys())
val_list = list(ports.values())
ip_scan(ip, val_list)
if os.path.exists(file):
send_mail()
#
维护定时任务
crontab -e
输入 0 */1 * * * sh /opt/monitoring/crontab.sh
阿里云ecs服务器需要修改mail发送端口为ssl类型
采用vpc网络时,默认防火墙禁止25端口通信
try:
# smtpObj = smtplib.SMTP()
smtpObj=smtplib.SMTP_SSL(mail_host, 994)
# smtpObj.connect(mail_host, 25) # 25 为 SMTP 端口号
smtpObj.login(mail_user, mail_pass)
smtpObj.sendmail(sender, receivers, message.as_string())
print "邮件发送成功"
smtpObj.quit()
except Exception, e:
print "邮件发送失败"
print str(e)