packet - 使用 ML 检测 DDoS 后如何在 ryu 控制器中丢弃数据包
问题描述
嗨,我正在研究使用机加工学习检测和缓解 sdn 上的 ddos 的项目。仿真由 ryu 控制器和 mininet 完成。我的问题是我能够检测到 attck 但我真的在努力缓解我想在检测到这是一次 ddos 攻击后丢弃数据包我尝试了一些解决方案但它对我不起作用所以这里的任何人都可以帮忙我在检测到 DDoS 后丢弃这些数据包,对此我将不胜感激。
这是我的应用程序:
'''
def __init__(self, *args, **kwargs):
super(SimpleMonitor13, self).__init__(*args, **kwargs)
self.datapaths = {}
self.monitor_thread = hub.spawn(self._monitor)
start = datetime.now()
self.flow_training()
end = datetime.now()
print("Training time: ", (end-start))
@set_ev_cls(ofp_event.EventOFPStateChange,
[MAIN_DISPATCHER, DEAD_DISPATCHER])
def _state_change_handler(self, ev):
datapath = ev.datapath
if ev.state == MAIN_DISPATCHER:
if datapath.id not in self.datapaths:
self.logger.debug('register datapath: %016x', datapath.id)
self.datapaths[datapath.id] = datapath
elif ev.state == DEAD_DISPATCHER:
if datapath.id in self.datapaths:
self.logger.debug('unregister datapath: %016x', datapath.id)
del self.datapaths[datapath.id]
def _monitor(self):
while True:
for dp in self.datapaths.values():
self._request_stats(dp)
hub.sleep(5)
self.flow_predict()
def _request_stats(self, datapath):
self.logger.debug('send stats request: %016x', datapath.id)
parser = datapath.ofproto_parser
req = parser.OFPFlowStatsRequest(datapath)
datapath.send_msg(req)
@set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER)
def _flow_stats_reply_handler(self, ev):
file0 = open("Prediction.csv", "w")
file0.write('timestamp,datapath_id,flow_id,ip_src,tp_src,ip_dst,tp_dst,ip_proto,icmp_code, icmp_type,flow_duration_sec,flow_duration_nsec,idle_timeout,hard_timeout,flags, packet_count,byte_count,packet_count_per_second,packet_count_per_nsecond,byte_count_per_second,byte_count_per_nsecond\n')
body = ev.msg.body
timestamp = datetime.now()
timestamp = timestamp.timestamp()
icmp_code = -1
icmp_type = -1
tp_src = 0
tp_dst = 0
body = ev.msg.body
for stat in sorted([flow for flow in body if (flow.priority == 1)], key=lambda flow:
(flow.match['eth_type'], flow.match['ipv4_src'], flow.match['ipv4_dst'], flow.match['ip_proto'])):
ip_src = stat.match['ipv4_src']
ip_dst = stat.match['ipv4_dst']
ip_proto = stat.match['ip_proto']
if stat.match['ip_proto'] == 1:
icmp_code = stat.match['icmpv4_code']
icmp_type = stat.match['icmpv4_type']
elif stat.match['ip_proto'] == 6:
tp_src = stat.match['tcp_src']
tp_dst = stat.match['tcp_dst']
elif stat.match['ip_proto'] == 17:
tp_src = stat.match['udp_src']
tp_dst = stat.match['udp_dst']
flow_id = str(ip_src) + str(tp_src) + str(ip_dst) + \
str(tp_dst) + str(ip_proto)
try:
packet_count_per_second = stat.packet_count/stat.duration_sec
packet_count_per_nsecond = stat.packet_count/stat.duration_nsec
except:
packet_count_per_second = 0
packet_count_per_nsecond = 0
try:
byte_count_per_second = stat.byte_count/stat.duration_sec
byte_count_per_nsecond = stat.byte_count/stat.duration_nsec
except:
byte_count_per_second = 0
byte_count_per_nsecond = 0
file0.write("{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}\n"
.format(timestamp, ev.msg.datapath.id, flow_id, ip_src, tp_src,ip_dst, tp_dst,
stat.match['ip_proto'],icmp_code,icmp_type,
stat.duration_sec, stat.duration_nsec,
stat.idle_timeout, stat.hard_timeout,
stat.flags, stat.packet_count,stat.byte_count,
packet_count_per_second,packet_count_per_nsecond,
byte_count_per_second,byte_count_per_nsecond))
file0.close()
def flow_training(self):
self.logger.info("Flow Training ...")
flow_dataset = pd.read_csv('Dataset.csv')
flow_dataset.iloc[:, 2] = flow_dataset.iloc[:, 2].str.replace('.', '')
flow_dataset.iloc[:, 3] = flow_dataset.iloc[:, 3].str.replace('.', '')
flow_dataset.iloc[:, 5] = flow_dataset.iloc[:, 5].str.replace('.', '')
X_flow = flow_dataset.iloc[:, :-1].values
X_flow = X_flow.astype('float64')
y_flow = flow_dataset.iloc[:, -1].values
X_flow_train, X_flow_test, y_flow_train, y_flow_test = train_test_split(
X_flow, y_flow, test_size=0.25, random_state=0)
classifier = DecisionTreeClassifier(
criterion='entropy', random_state=0)
self.flow_model = classifier.fit(X_flow_train, y_flow_train)
y_flow_pred = self.flow_model.predict(X_flow_test)
self.logger.info("------------------------------------------------------------------------------")
self.logger.info("confusion matrix")
cm = confusion_matrix(y_flow_test, y_flow_pred)
self.logger.info(cm)
acc = accuracy_score(y_flow_test, y_flow_pred)
self.logger.info("succes accuracy = {0:.2f} %".format(acc*100))
fail = 1.0 - acc
self.logger.info("fail accuracy = {0:.2f} %".format(fail*100))
self.logger.info("------------------------------------------------------------------------------")
def flow_predict(self):
try:
predict_flow_dataset = pd.read_csv('Prediction.csv')
predict_flow_dataset.iloc[:, 2] = predict_flow_dataset.iloc[:, 2].str.replace(
'.', '')
predict_flow_dataset.iloc[:, 3] = predict_flow_dataset.iloc[:, 3].str.replace(
'.', '')
predict_flow_dataset.iloc[:, 5] = predict_flow_dataset.iloc[:, 5].str.replace(
'.', '')
X_predict_flow = predict_flow_dataset.iloc[:, :].values
X_predict_flow = X_predict_flow.astype('float64')
y_flow_pred = self.flow_model.predict(X_predict_flow)
legitimate_trafic = 0
ddos_trafic = 0
for i in y_flow_pred:
if i == 0:
legitimate_trafic = legitimate_trafic + 1
else:
ddos_trafic = ddos_trafic + 1
victim = int(predict_flow_dataset.iloc[i, 5]) % 20
self.logger.info("------------------------------------------------------------------------------")
if (legitimate_trafic/len(y_flow_pred)*100) > 80:
self.logger.info("legitimate trafic ...")
else:
self.logger.info("ddos trafic ...")
self.logger.info("victim is host: h{}".format(victim))
self.logger.info("------------------------------------------------------------------------------")
file0 = open("Prediction.csv", "w")
file0.write('timestamp,datapath_id,flow_id,ip_src,tp_src,ip_dst,tp_dst,ip_proto,icmp_code, icmp_type,flow_duration_sec,flow_duration_nsec,idle_timeout,hard_timeout,flags, packet_count,byte_count,packet_count_per_second,packet_count_per_nsecond,byte_count_per_second,byte_count_per_nsecond\n')
file0.close()
except:
pass
'''
解决方案
您需要将 eth_src 添加到您的预测数据集然后,执行提取受害者主机的相同步骤以提取攻击者主机(如果 I==1):victim = ,attacker_eth=
获得以太网 src 后,您可以使用 add_flow() 函数将块添加到流表中。如果您需要更多详细信息,请告诉我
推荐阅读
- system-verilog - systemverilog:tri0 vs pulldown - 有什么区别吗?
- ios - 快速关闭的通用 UIView 初始化程序
- javascript - 如何根据月份显示api结果
- angular - 为什么 TypeScript 会抛出错误:TS2339:“EventTarget”类型上不存在属性“错误”
- angular - 如何在此路由路径上进行路由?
- python - 看不懂《TensorFlow 中的卷积神经网络》课程第 1 周的这段代码
- c++ - C++程序中的内存泄漏
- python - 如何获取用户定义的方法名称?
- java - 使用 org.json 将 JsonOjbect 转换为 java 中的 Arraylist
- php - 如何在从html表单到txt文件的特定行之后添加特定文本(实际上是html)