
مستنشق OpenFlow للمساعدة في استكشاف أخطاء الشبكة في شبكات الإنتاج.
OFP_Sniffer هو أداة استشعار لـ OpenFlow تُستخدم لأغراض استكشاف الأخطاء وإصلاحها والتعلم.
حاليًا في الإصدار 1.2، يقوم بتفكيك جميع رسائل OpenFlow 1.0، ويعمل مع InfluxDB وGrafana وSlack. سيكون OpenFlow 1.3 متاحًا في إصدار OFP_Sniffer 1.3 (سيتم إصداره قريبًا).
يعمل مباشرة على شل لينكس ويقوم بتفكيك جميع رسائل OpenFlow على الشبكة أو من ملفات libpcap. باستخدام OFP_Sniffer، يمكنك تتبع رسائل OpenFlow والأخطاء المرتبطة بها (إن وجدت) بسهولة دون فتح X11 أو Wireshark. تم كتابة OFP_Sniffer بلغة Python 3.6 لدعم نشر AmLight SDN (www.sdn.amlight.net). يستخدم AmLight SDN جدار حماية Internet2 FlowSpace وOESS وOn.Lab ONOS، وقد تم اختبار هذه التطبيقات وهي مدعومة بالكامل.
كأداة واجهة سطر أوامر، تحتوي على بعض معلمات الإدخال:
# ./ofp_sniffer.py -h
Usage:
./ofp_sniffer.py [-p min|full] [-f pcap_filter] [-F filter_file] [-i dev] [-r pcap_file]
-p : print all TCP/IP headers. Default: min
-f pcap_filter or --pcap-filter=pcap_filter: add a libpcap filter
-F filters_file.json or --filters-file=filters.json
-i interface or --interface=interface. Default: eth0
-r captured.pcap or --src-file=captured.pcap
-T topology.json or --topology-file=topology.json
-w file or --save-to-file=file: save output to file provided
-o or --print-ovs : print using ovs-ofctl format
-h or --help : prints this help
-c or --no-colors: removes colors
-v or --version : prints version
-O WARN:CRIT or --oess-fvd=WARN:CRIT: monitor OESS FVD status
-N or --notify-via-slack: send notifications via Slack. Param is the Slack channel
-S or --enable-statistics: creates statistics
بدءًا من الإصدار 1.0، يتم دعم التطبيقات لتلبية احتياجات محددة، مثل تتبع رسائل OESS FVD أو إنشاء إحصائيات عبر REST ودمجها مع أنظمة إدارة الشبكات (مثل Zabbix).
مزيد من المعلومات: https://amlight.net/wp-content/uploads/2015/03/wpeif-2016-ofpsniffer.pdf
##################### التثبيت ######################
Requires Python 3.6
git clone https://github.com/amlight/ofp_sniffer.git
cd ofp_sniffer
pip3.6 install -r docs/requirements.txt
sudo ./ofp_sniffer.py
##################### أمثلة #########################
الأمثلة موضحة أدناه:
---------------------- -------------------------
| Mininet | | OVS-OFCTL 2.3.0 |
| 192.168.56.101:6634| <-------> | eth1 - 192.168.56.102 |
---------------------- -------------------------
# ovs-ofctl dump-flows tcp:192.168.56.101:6634
cookie=0x0, duration=2183.377s, table=0, n_packets=0, n_bytes=0, idle_age=2183, in_port=1,dl_vlan=2 actions=output:2
# ./ofp_sniffer.py -i eth1 -f " or port 6634"
Sniffing device eth1
2015-09-13 11:47:38.655503 192.168.56.102:37450 -> 192.168.56.101:6634 Size: 74
OpenFlow Version: 1.0(1) Type: Hello(0) Length: 8 XID: 1
1 OpenFlow Hello
2015-09-13 11:47:38.656964 192.168.56.101:6634 -> 192.168.56.102:37450 Size: 74
OpenFlow Version: 1.0(1) Type: Hello(0) Length: 8 XID: 174
174 OpenFlow Hello
2015-09-13 11:47:38.657638 192.168.56.102:37450 -> 192.168.56.101:6634 Size: 86
OpenFlow Version: 1.0(1) Type: Vendor(4) Length: 20 XID: 2
2 OpenFlow Vendor : NICIRA(0x2320)
2 OpenFlow Vendor Data: 12 2
2015-09-13 11:47:38.657870 192.168.56.102:37450 -> 192.168.56.101:6634 Size: 74
OpenFlow Version: 1.0(1) Type: BarrierReq(18) Length: 8 XID: 3
3 OpenFlow Barrier Request
2015-09-13 11:47:38.659270 192.168.56.101:6634 -> 192.168.56.102:37450 Size: 74
OpenFlow Version: 1.0(1) Type: BarrierRes(19) Length: 8 XID: 3
3 OpenFlow Barrier Reply
# ovs-ofctl add-flow tcp:192.168.56.101:6634 "dl_dst=10:00:00:01:20:00,dl_type=0x88bc actions=mod_vlan_vid:14,output:2"
# ./ofp_sniffer.py -i eth1 -f " or port 6634"
2015-09-13 11:49:08.171463 192.168.56.102:37451 -> 192.168.56.101:6634 Size: 154
OpenFlow Version: 1.0(1) Type: FlowMod(14) Length: 88 XID: 2
2 OpenFlow Match - wildcards: 3678439 dl_type: 0x88bc dl_dst: 10:00:00:01:20:00
2 OpenFlow Body - Cookie: 0x00 Command: Add(0) Idle/Hard Timeouts: 0/0 Priority: 32768 Buffer ID: 0xffffffff Out Port: 65535 Flags: Unknown Flag(0)
2 OpenFlow Action - Type: SetVLANID Length: 8 VLAN ID: 14 Pad: 0
2 OpenFlow Action - Type: OUTPUT Length: 8 Port: 2 Max Length: 0
# ovs-ofctl del-flows tcp:192.168.56.101:6634 "dl_type=0x88bc,dl_dst=10:00:00:01:20:00, "
2015-09-13 11:50:43.636925 192.168.56.102:37454 -> 192.168.56.101:6634 Size: 138
OpenFlow Version: 1.0(1) Type: FlowMod(14) Length: 72 XID: 2
2 OpenFlow Match - wildcards: 3678439 dl_type: 0x88bc dl_dst: 10:00:00:01:20:00
2 OpenFlow Body - Cookie: 0x00 Command: Delete(3) Idle/Hard Timeouts: 0/0 Priority: 32768 Buffer ID: 0xffffffff Out Port: 65535 Flags: Unknown Flag(0)
# ovs-ofctl add-flow tcp:192.168.56.101:6634 "dl_dst=10:00:00:01:20:00,dl_type=0x88bc actions=mod_vlan_vid:14,output:2"
2015-09-13 11:52:58.563737 192.168.56.102:37455 -> 192.168.56.101:6634 Size: 154
OpenFlow Version: 1.0(1) Type: FlowMod(14) Length: 88 XID: 2
2 OpenFlow Match - wildcards: 3678439 dl_type: 0x88bc dl_dst: 10:00:00:01:20:00
2 OpenFlow Body - Cookie: 0x00 Command: Add(0) Idle/Hard Timeouts: 0/0 Priority: 32768 Buffer ID: 0xffffffff Out Port: 65535 Flags: Unknown Flag(0)
2 OpenFlow Action - Type: SetVLANID Length: 8 VLAN ID: 14 Pad: 0
2 OpenFlow Action - Type: OUTPUT Length: 8 Port: 2 Max Length: 0
استخدام المرشحات:
عند استخدام الخيار -F ./filters.json ستحصل على بعض الخيارات:
"rejected_of_types" : يُستخدم لتحديد أنواع رسائل OpenFlow التي لا تريد رؤيتها. يمكنك تعريف مرشحات مختلفة حسب إصدار OpenFlow.
مرشحات حسب نوع الإيثرنت:
إذا كنت تبحث عن نوع إيثرنت محدد يتم نقله عبر رسائل PacketOut أو PacketIn، يمكنك رفض جميع الأنواع الأخرى، مما يمنحك تصورًا سهلًا.
مثال:
"filters":{
"ethertypes": {
"lldp" : 0,
"fvd" : 0,
"arp" : 1,
"others": [ "88b5" ]
},
"packetIn_filter": {
"switch_dpid": "any",
"in_port": "any"
},
"packetOut_filter": {
"switch_dpid": "any",
"out_port": "any"
}
}
}
في قسم ethertype، 1 يعني تصفية، 0 يعني طباعته. في المثال المقدم، لن تظهر رسائل ARP بينما ستظهر رسائل OESS FVD وLLDP. يمكنك إضافة الرقم الست عشري لنوع الإيثرنت (بدون 0x) في قسم "others"، فقط بإضافة الفواصل (",").
"packetIn_filter": يُستخدم لتحديد رسائل PacketIn + LLDP التي تريد رؤيتها. يمكنك التعريف لكل محول و/أو لكل منفذ. بالنسبة للمحول، تحتاج إلى استخدام datapath_id كما هو موضح في التطبيق الذي تستخدمه. على سبيل المثال، بعض التطبيقات تملأ الحقل c_id بـ of:dpid_id والبعض الآخر بـ dpid:dpid_id. بالنسبة للمنافذ، استخدم OpenFlow port_id وليس اسم المنفذ. على سبيل المثال، على Brocade، eth1/1 == 1. لذا استخدم 1 بدلاً من eth1/1.
"packetOut_filter": يُستخدم لتحديد رسائل PacketOut + LLDP التي تريد رؤيتها. يمكنك التعريف لكل محول و/أو لكل منفذ. بالنسبة للمحول، تحتاج إلى استخدام datapath_id كما هو موضح في التطبيق الذي تستخدمه. على سبيل المثال، بعض التطبيقات تملأ الحقل c_id بـ of:dpid_id والبعض الآخر بـ dpid:dpid_id. بالنسبة للمنافذ، استخدم OpenFlow port_id وليس اسم المنفذ. على سبيل المثال، على Brocade، eth1/1 == 1. لذا استخدم 1 بدلاً من eth1/1.
دعم بروكسيات OpenFlow:
عند استخدام بروكسي OpenFlow، اعتمادًا على الواجهة التي تختارها للاستشعار، سترى واحدًا من الاحتمالين:
IP_Controller <-> IP_Proxy IP_Proxy <-> IP_Switch
من الصعب ربط وحدات التحكم بالمفاتيح. لتسهيل استكشاف الأخطاء، يقوم مستشعر OpenFlow تلقائيًا بمراقبة جميع رسائل PacketOut + LLDP لإنشاء قاموس {(IP, port): name_switch}. إذا كانت هذه حالتك، قم بتغيير ملف docs/topology.json. في المرة التالية التي تقوم فيها بتشغيل المستشعر، سترى عنوان IP وبين الأقواس الجهاز خلف البروكسي. مثال:
2015-12-16 15:37:41.563621 200.0.207.79(andes1):7801 -> 190.103.184.135:6633 Size: 157 Bytes
OpenFlow Version: 1.0(1) Type: PacketIn(10) Length: 103 XID: 0
0 PacketIn: buffer_id: 0xffffffff total_len: 85 in_port: 49 reason: OFPR_NO_MATCH(0) pad: 0
0 Ethernet: Destination MAC: ff:ff:ff:ff:ff:ff Source MAC: de:ad:be:ef:ba:11 Protocol: 0x8100
0 Ethernet: Prio: 0 CFI: 0 VID: 3720
0 LLDP: Chassis Type(1) Length: 7 SubType: 4 ID: of:cc4e249102000000
0 LLDP: Port Type(2) Length: 5 SubType: 2 ID: 2
0 LLDP: TTL(3) Length: 2 Seconds: 120
0 LLDP: END(0) Length: 0
2015-12-16 15:37:41.564414 190.103.184.133(andes1):56132 -> 190.103.187.72:6633 Size: 165 Bytes
OpenFlow Version: 1.0(1) Type: PacketIn(10) Length: 99 XID: 0
0 PacketIn: buffer_id: 0xffffffff total_len: 81 in_port: 49 reason: OFPR_NO_MATCH(0) pad: 0
0 Ethernet: Destination MAC: ff:ff:ff:ff:ff:ff Source MAC: de:ad:be:ef:ba:11 Protocol: 0x8942
0 LLDP: Chassis Type(1) Length: 7 SubType: 4 ID: of:cc4e249102000000
0 LLDP: Port Type(2) Length: 5 SubType: 2 ID: 2
0 LLDP: TTL(3) Length: 2 Seconds: 120
0 LLDP: END(0) Length: 0
الاسم (andes1) يمثل محولًا يُسمى "andes1" مع DPID cc4e249126000000. لاحظ أن DPID الموضح في المثال ليس هو نفسه، لأن رسالة PacketIn تُستخدم كمثال. تُظهر PacketIn DPID لجيران "andes1".
آمل أن يساعدك هذا الكود.
أسئلة/اقتراحات: فريق تطوير AmLight [email protected]