246 lines
8.5 KiB
Python
246 lines
8.5 KiB
Python
# !coding=utf-8
|
||
import datetime
|
||
import logging
|
||
import time
|
||
from concurrent import futures
|
||
import grpc
|
||
import pytz
|
||
from neomodel import db, StringProperty, DateTimeFormatProperty, RelationshipTo, StructuredRel, IntegerProperty, \
|
||
StructuredNode, config, BooleanProperty
|
||
|
||
import analyze_pb2
|
||
import analyze_pb2_grpc
|
||
import analyzedutil as aul
|
||
|
||
logging.basicConfig(level=logging.DEBUG,filename="./log/pythonrun.log",filemode="w",
|
||
format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
|
||
|
||
|
||
class node:
|
||
ip = ""
|
||
AS = ""
|
||
next = ""
|
||
isp = ""
|
||
cou = ""
|
||
couCode = ""
|
||
prov = ""
|
||
lat = ""
|
||
lng = ""
|
||
FindTime = ""
|
||
dataOK = ""
|
||
owner = ""
|
||
|
||
def __init__(self, ip):
|
||
self.ip = ip
|
||
record = aul.getrecord(ip)
|
||
if record == 1:
|
||
self.dataOK = False
|
||
return
|
||
self.dataOK = True
|
||
self.isp = aul.filterNull(record.get('isp', b'').decode("utf-8"))
|
||
self.lat = aul.filterNull(record.get('latwgs', b'').decode("utf-8"))
|
||
self.lng = aul.filterNull(record.get('lngwgs', b'').decode("utf-8"))
|
||
self.prov = aul.filterNull(record.get('province', b'').decode("utf-8"))
|
||
self.AS = aul.filterNull(record.get('asnumber', b'').decode("utf-8"))
|
||
self.couCode = aul.filterNull(record.get('areacode', b'').decode("utf-8"))
|
||
self.cou = aul.filterNull(record.get('country', b'').decode("utf-8"))
|
||
self.FindTime = datetime.datetime.now(pytz.UTC)
|
||
self.owner = aul.filterNull(record.get('owner', b'').decode("utf-8"))
|
||
|
||
|
||
# 与go之间的通信
|
||
|
||
class RequestServe(analyze_pb2_grpc.GrpcServiceServicer):
|
||
graph_conn = ""
|
||
|
||
def AnalyzeService(self, request, context):
|
||
'''
|
||
具体实现AnalyzeService服务方法
|
||
:param request:
|
||
:param context:
|
||
:return:
|
||
'''
|
||
r = request
|
||
if r.gtype == "neo4j":
|
||
if self.graph_conn == "":
|
||
url = str(r.guri).split("//")[0] + "//" + r.guser + ":" + r.gpass + "@" + str(r.guri).split("//")[1]
|
||
self.graph_conn = neo4j_connector(url)
|
||
logging.info("已连接到图数据库Neo4j:" + r.guri)
|
||
result = self.graph_conn.work_with_neoj_53(r.data)
|
||
return analyze_pb2.result(res=result)
|
||
return analyze_pb2.result(res="not support")
|
||
|
||
|
||
working_addr = "127.0.0.1"
|
||
working_port = "56789"
|
||
|
||
|
||
def serve():
|
||
# 启动 rpc 服务,这里可定义最大接收和发送大小(单位M),默认只有4M
|
||
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), options=[
|
||
('grpc.max_send_message_length', 100 * 1024 * 1024),
|
||
('grpc.max_receive_message_length', 100 * 1024 * 1024)])
|
||
|
||
analyze_pb2_grpc.add_GrpcServiceServicer_to_server(RequestServe(), server)
|
||
server.add_insecure_port(working_addr + ":" + working_port)
|
||
server.start()
|
||
logging.info("Python分析模块启动,工作在 " + working_addr + ":" + working_port)
|
||
try:
|
||
while True:
|
||
time.sleep(60 * 60 * 24) # one day in seconds
|
||
except KeyboardInterrupt:
|
||
server.stop(0)
|
||
|
||
|
||
class RelResolver53(StructuredRel):
|
||
W = IntegerProperty()
|
||
LTIME = DateTimeFormatProperty(default_now=True, format="%Y-%m-%d %H:%M:%S")
|
||
|
||
# 查询记录定义
|
||
class NodeResolverQuery(StructuredNode):
|
||
QNAME=StringProperty(required=True)
|
||
QTYPE=StringProperty()
|
||
# 解析器和查询记录的关系
|
||
class RelResolverQuery(StructuredRel):
|
||
W = IntegerProperty()
|
||
|
||
class NodeResolver53(StructuredNode):
|
||
IP = StringProperty(required=True, unique_index=True)
|
||
AS = StringProperty()
|
||
ISP = StringProperty()
|
||
COU = StringProperty()
|
||
CCODE = StringProperty()
|
||
PROV = StringProperty()
|
||
LAT = StringProperty()
|
||
LNG = StringProperty()
|
||
IPType = StringProperty()
|
||
FTIME = DateTimeFormatProperty(format="%Y-%m-%d %H:%M:%S")
|
||
LTIME = DateTimeFormatProperty(default_now=True, format="%Y-%m-%d %H:%M:%S")
|
||
W = IntegerProperty()
|
||
ISPUBLIC = BooleanProperty(default=False)
|
||
LINK = RelationshipTo("NodeResolver53", "IP_LINK", model=RelResolver53)
|
||
QLINK=RelationshipTo("NodeResolverQuery","Q_LINK",model=RelResolverQuery)
|
||
|
||
|
||
class neo4j_connector:
|
||
graph = ""
|
||
|
||
# nodematcher = ""
|
||
# relatmatcher = ""
|
||
|
||
def __init__(self, url):
|
||
# 连接neo4j
|
||
#config.ENCRYPTED = True
|
||
config.DATABASE_URL =url
|
||
db.set_connection(url)
|
||
# data=[ip1,ip2,ispublic,qname,qtype]
|
||
def work_with_neoj_53(self, data):
|
||
datastr=""
|
||
for d in data:
|
||
datastr=datastr+str(d)+" , "
|
||
logging.debug("处理数据:"+datastr+"")
|
||
############################################### 对解析器节点进行处理#####################################################
|
||
for d in range(len(data) - 3):
|
||
n = node(data[d])
|
||
if not n.dataOK:
|
||
return "node err because ip"
|
||
# 查询是否存在节点
|
||
nd, exist = self.checknode_neo4j(ip=n.ip)
|
||
# 不存在则新建
|
||
if not exist:
|
||
nd = NodeResolver53(AS=n.AS, COU=n.cou,
|
||
CCODE=n.couCode, LAT=n.lat, LNG=n.lng,
|
||
ISP=n.isp, IPType=aul.IP46(n.ip), PROV=n.prov, FTIME=n.FindTime,
|
||
LTIME=n.FindTime, IP=n.ip, W=1)
|
||
# IP1是开放解析器
|
||
if data[2] == "0" and d == 0:
|
||
nd.ISPUBLIC = True
|
||
nd.save()
|
||
# 存在则只修改时间
|
||
else:
|
||
# nd.LTIME = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
|
||
nd.LTIME = datetime.datetime.now(pytz.UTC)
|
||
if nd.W is not None:
|
||
nd.W += 1
|
||
else:
|
||
nd.W = 1
|
||
nd.save()
|
||
|
||
|
||
|
||
################################################ 对查询记录节点进行处理################################################
|
||
# 查询是否存在节点
|
||
# q,exist=self.checknode_neo4j(q=data[3],qtype=data[4])
|
||
# # 不存在则新建
|
||
# if not exist:
|
||
# q = NodeResolverQuery(QNAME=data[3],QTYPE=data[4])
|
||
# q.save()
|
||
# 存在则不做处理
|
||
|
||
|
||
############################################ 查询解析器是否存在关系#############################################
|
||
L, lexist = self.checklink_neo4j(data[0], data[1])
|
||
# 数据存在问题则退出
|
||
if L == "Err":
|
||
return "node err when link"
|
||
# 不存在则建立关联
|
||
if not lexist:
|
||
L[0].LINK.connect(L[1], {'W': 1, 'LTIME': datetime.datetime.now(pytz.UTC)}).save()
|
||
# 存在则修改权重
|
||
else:
|
||
L.W += 1
|
||
L.LTIME = datetime.datetime.now(pytz.UTC)
|
||
L.save()
|
||
# 提交链接
|
||
|
||
############################################查询解析器和记录间的关系#########################################
|
||
# QL, lexist = self.checkquerylink(data[1], data[3],data[4])
|
||
# # 数据存在问题则退出
|
||
# if QL == "Err":
|
||
# return "node err when link"
|
||
# # 不存在则建立关联
|
||
# if not lexist:
|
||
# QL[0].QLINK.connect(QL[1], {'W': 1}).save()
|
||
# # 存在则修改权重
|
||
# else:
|
||
# QL.W += 1
|
||
# QL.save()
|
||
|
||
# 完成处理,返回
|
||
logging.debug("完成处理数据:{"+datastr+"}")
|
||
return "success"
|
||
|
||
def checknode_neo4j(self, ip=None,q=None,qtype=None):
|
||
# 查询IP
|
||
if ip!=None:
|
||
a = NodeResolver53.nodes.get_or_none(IP=ip)
|
||
# 查询记录
|
||
else:
|
||
a=NodeResolverQuery.nodes.get_or_none(QNAME=q,QTYPE=qtype)
|
||
if a is not None:
|
||
return a, True
|
||
return None, False
|
||
|
||
def checklink_neo4j(self, ip_from, ip_to):
|
||
f = NodeResolver53.nodes.get_or_none(IP=ip_from)
|
||
t = NodeResolver53.nodes.get_or_none(IP=ip_to)
|
||
if f is None or t is None:
|
||
return "Err", False
|
||
rel = f.LINK.relationship(t)
|
||
if rel is not None:
|
||
return rel, True
|
||
return [f, t], False
|
||
|
||
def checkquerylink(self,ip,qname,qtype):
|
||
r=NodeResolver53.nodes.get_or_none(IP=ip)
|
||
q=NodeResolverQuery.nodes.get_or_none(QNAME=qname,QTYPE=qtype)
|
||
if r is None or q is None:
|
||
return "Err", False
|
||
rel=r.QLINK.relationship(q)
|
||
if rel is not None:
|
||
return rel, True
|
||
return [r, q], False
|
||
|
||
if __name__ == '__main__':
|
||
serve()
|