對線上服務器進行端口掃描是一件頗有用的事,能夠驗證你的防火牆規則,避免暴漏不須要的服務。也能夠知道你機器上開了哪些服務,不用等烏雲爆出來了才知道,有人黑進內網玩了好幾個月。哈哈,真事,服務器被經過zabbix黑進來,開了一個socket5的進程,自由進出。反正,這玩意頗有用,本着奉獻精神,把代碼放出來,共同窗習。
html
功能很簡單,對服務器進行掃描,生成html格式的掃描結果,對掃描結果發郵件。格式方面作了點處理,定義端口白名單,正常端口顯示綠色,異常端口顯示紅色。算是一種告警。對服務器進行全端口掃描是很耗時的一件事,每臺6萬多個端口,並且還取決於掃描機器到目標機的網絡鏈接狀況。受不了這個蝸牛速度,開發了初版的單線程版本後,又實現了一個多進程的版本,果真爽了好多。整我的都好了……python
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 + "<h2>ip地址:%s 主機名:[%s] ...... %s</h2><hr>" %(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 = '<strong><font color=red>Alert:非預期端口</font><strong> ' else: info = '<strong><font color=green>Info:正常開放端口</font><strong> ' portinfo = "%s <strong>port</strong> : %s <strong>state</strong> : %s <strong>product<strong/> : %s <br>" %(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 = ['gccmx@163.com','gccmx@qq.com'] subject = '服務器端口掃描' smtpserver = 'smtp.exmail.qq.com' smtpuser = 'gaochenchao@huoqiu.cn' smtppass = 'gccmx163' 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 + "<h2>ip地址:%s 主機名:[%s] ...... %s</h2><hr>" %(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 = '<strong><font color=red>Alert:非預期端口</font><strong> ' else: info = '<strong><font color=green>Info:正常開放端口</font><strong> ' portinfo = "%s <strong>port</strong> : %s <strong>state</strong> : %s <strong>product<strong/> : %s <br>" %(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 = 'gccmx@163.com' receiver = ['gccmx@qq.com',] subject = '服務器端口掃描' smtpserver = 'smtp.exmail.qq.com' smtpuser = 'gccmx@163.com' smtppass = 'gccmx163' mailcontent = '<br>'.join(results) tool.sendemail(sender,receiver,subject,mailcontent,smtpserver,smtpuser,smtppass)
掃描結果:馬賽克阻礙了人類文明的進步,尤爲是在欣賞島國動做片的時候,可是,親,我不能把俺們的服務器給你看的,你懂的!app