功能很简单,对服务器进行扫描,生成html格式的扫描结果,对扫描结果发邮件。格式方面做了点处理,定义端口白名单,正常端口显示绿色,异常端口显示红色。算是一种告警。对服务器进行全端口扫描是很耗时的一件事,每台6万多个端口,而且还取决于扫描机器到目标机的网络连接情况。受不了这个蜗牛速度,开发了第一版的单线程版本后,又实现了一个多进程的版本,果然爽了好多。整个人都好了……
mytools.py 这是定义的一个函数库,截取了用到的一个函数,这个sendemail的发邮件的函数,当然当前场景可以定义的一个文件中,不过,对程序按模块拆分是个好的习惯。哈哈,我有点pythonic了。
#-*- coding:utf-8 -*-
import smtplib
from email.mime.text import MIMEText
from email.header import Header
def sendemail(sender,receiver,subject,content,smtpserver,smtpuser,smtppass):
msg = MIMEText(content,'html','utf-8')#中文需参数‘utf-8',单字节字符不需要
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = '<%s>' % sender
msg['To'] = ";".join(receiver)
try:
smtp = smtplib.SMTP()
smtp.connect(smtpserver)
smtp.login(smtpuser, smtppass)
smtp.sendmail(sender, receiver, msg.as_string())
smtp.quit()
except Exception,e:
print e
nmscan.py 实现端口扫描的程序,单线程版本,代码有点长,慎入
#!/usr/bin/python
#-*- coding:utf-8 -*-
import nmap
import re
import mytools as tool
import sys
reload(sys)
sys.setdefaultencoding('utf8')
def nmScan(hostlist,portrange,whitelist):
p = re.compile("^(\d*)\-(\d*)$")
if type(hostlist) != list:
help()
portmatch = re.match(p,portrange)
if not portmatch:
help()
l = []
for host in hostlist:
result = ''
nm = nmap.PortScanner()
tmp = nm.scan(host,portrange)
result = result + "
ip地址:%s 主机名:[%s] ...... %s
" %(host,tmp['scan'][host]['hostname'],tmp['scan'][host]['status']['state'])
try:
ports = tmp['scan'][host]['tcp'].keys()
except KeyError,e:
if whitelist:
whitestr = ','.join(whitelist)
result = result + "未扫到开放端口!请检查%s端口对应的服务状态" %whitestr
else:
result = result + "扫描结果正常,无暴漏端口"
continue
for port in ports:
info = ''
if port not in whitelist:
info = 'Alert:非预期端口 '
else:
info = 'Info:正常开放端口 '
portinfo = "%s port : %s state : %s product : %s
" %(info,port,tmp['scan'][host]['tcp'][port]['state'],
tmp['scan'][host]['tcp'][port]['product'])
result = result + portinfo
l.append([host,str(result)])
return l
def help():
print "Usage: nmScan(['127.0.0.1',],'0-65535')"
if __name__ == "__main__":
hostlist = ['10.10.10.10','10.10.10.11']
portrange = '0-65535'
whitelist = [80,443]
l = nmScan(hostlist,portrange,whitelist)
sender = 'douniwan@qq.com'
receiver = ['linuxidc@163.com','linuxidc@qq.com']
subject = '服务器端口扫描'
smtpserver = 'smtp.exmail.qq.com'
smtpuser = 'gaochenchao@huoqiu.cn'
smtppass = 'linuxidc163'
mailcontent = ''
for i in range(len(l)):
mailcontent = mailcontent + l[i][1]
tool.sendemail(sender,receiver,subject,mailcontent,smtpserver,smtpuser,smtppass)
mutinmscan.py 端口扫描的多进程版本,比照单线程版本最大的一个变化是nmscan函数的实现上,单线程传递一个服务器列表,在函数内部循环该列表,读取扫描结果,生成报告邮件。mutinmscan版的函数是接受一个ip地址,循环这一部分使用了mutiprocess库的Pool,并使用其map函数实现对服务器ip列表的迭代。多线程,一节更比五节强……
#!/usr/bin/python
#-*- coding:utf-8 -*-
import nmap
import re
import mytools as tool
import sys
from multiprocessing import Pool
from functools import partial
reload(sys)
sys.setdefaultencoding('utf8')
def nmScan(host,portrange,whitelist):
p = re.compile("^(\d*)\-(\d*)$")
# if type(hostlist) != list:
# help()
portmatch = re.match(p,portrange)
if not portmatch:
help()
if host == '121.42.32.172':
whitelist = [25,]
result = ''
nm = nmap.PortScanner()
tmp = nm.scan(host,portrange)
result = result + "
ip地址:%s 主机名:[%s] ...... %s
" %(host,tmp['scan'][host]['hostname'],tmp['scan'][host]['status']['state'])
try:
ports = tmp['scan'][host]['tcp'].keys()
for port in ports:
info = ''
if port not in whitelist:
info = 'Alert:非预期端口 '
else:
info = 'Info:正常开放端口 '
portinfo = "%s port : %s state : %s product : %s
" %(info,port,tmp['scan'][host]['tcp'][port]['state'], tmp['scan'][host]['tcp'][port]['product'])
result = result + portinfo
except KeyError,e:
if whitelist:
whitestr = ','.join(whitelist)
result = result + "未扫到开放端口!请检查%s端口对应的服务状态" %whitestr
else:
result = result + "扫描结果正常,无暴漏端口"
return result
def help():
print "Usage: nmScan(['127.0.0.1',],'0-65535')"
return None
if __name__ == "__main__":
hostlist = ['10.10.10.1','10.10.10.2']
pool = Pool(5)
nmargu = partial(nmScan,portrange='0-65535',whitelist=[])
results = pool.map(nmargu,hostlist)
#send email
sender = 'linuxidc@163.com'
receiver = ['linuxidc@qq.com',]
subject = '服务器端口扫描'
smtpserver = 'smtp.exmail.qq.com'
smtpuser = 'linuxidc@163.com'
smtppass = 'linuxidc163'
mailcontent = '
'.join(results)
tool.sendemail(sender,receiver,subject,mailcontent,smtpserver,smtpuser,smtppass)
扫描结果:马赛克阻碍了人类文明的进步,尤其是在欣赏岛国动作片的时候,但是,亲,我不能把俺们的服务器给你看的,你懂的!
--------------------------------------分割线 --------------------------------------
Python 用socket模块实现检测端口和检测web服务
上源码安装Python3.4
《Python核心编程 第二版》.(Wesley J. Chun ).[高清PDF中文版]
《Python开发技术详解》.( 周伟,宗杰).[高清PDF扫描版+随书视频+代码]
Python脚本获取Linux系统信息
在下用Python搭建桌面算法交易研究环境
Python 语言的发展简史
Python 的详细介绍:
Python 的下载地址:
本文永久更新链接地址: