
Un sniffer OpenFlow para ayudar en la resolución de problemas de red en redes de producción.
OFP_Sniffer es un sniffer de OpenFlow diseñado para fines de solución de problemas y aprendizaje.
Actualmente en la versión 1.2, disecciona todos los mensajes de OpenFlow 1.0, funciona con InfluxDB, Grafana y Slack. OpenFlow 1.3 estará disponible en la versión 1.3 de OFP_Sniffer (próximamente).
Funciona directamente en la shell de Linux y disecciona todos los mensajes de OpenFlow en la red o desde archivos libpcap. Usando OFP_Sniffer, puedes rastrear fácilmente mensajes de OpenFlow y sus errores asociados (si los hay) sin abrir X11 o Wireshark. OFP_Sniffer fue escrito en Python 3.6 para soportar el despliegue SDN de AmLight (www.sdn.amlight.net). AmLight SDN usa Internet2 FlowSpace Firewall, OESS y On.Lab ONOS, y estas aplicaciones fueron probadas y son totalmente compatibles.
Como herramienta de interfaz de línea de comandos, tiene algunos parámetros de entrada:
# ./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
A partir de la versión 1.0, se admiten aplicaciones para manejar necesidades específicas, como rastrear mensajes de OESS FVD o crear estadísticas vía REST e integrarse con NMS (p. ej., Zabbix).
More info: https://amlight.net/wp-content/uploads/2015/03/wpeif-2016-ofpsniffer.pdf
##################### Instalación ######################
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
##################### Ejemplos #########################
A continuación se muestran ejemplos:
---------------------- -------------------------
| 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
Usando Filtros:
Al usar la opción -F ./filters.json tendrás algunas opciones:
"rejected_of_types" : se usa para seleccionar qué tipos de mensajes OpenFlow NO deseas ver. Puedes definir diferentes filtros según la versión de OpenFlow.
Filtros por Ethertype:
Si buscas un Ethertype específico transportado por mensajes PacketOut o PacketIn, puedes rechazar todos los demás, lo que facilita la visualización.
Ejemplo:
"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"
}
}
}
En la sección de ethertype, 1 significa filtrar, 0 significa imprimirlo. En el ejemplo proporcionado, los mensajes ARP no se verán, mientras que OESS FVD y LLDP sí. Puedes agregar el número hexadecimal del Ethertype (sin el 0x) en la sección "others", agregando comas (",").
"packetIn_filter": se usa para definir qué mensajes PacketIn + LLDP deseas ver. Puedes definirlo por switch y/o por puerto. Para el switch, debes usar el datapath_id tal como lo ve la aplicación que estás usando. Por ejemplo, algunas aplicaciones llenan el campo c_id con of:dpid_id, otras con dpid:dpid_id. Para los puertos, usa el OpenFlow port_id, no el nombre del puerto. Por ejemplo, en Brocade, eth1/1 == 1. Así que usa 1 en lugar de eth1/1.
"packetOut_filter": se usa para definir qué mensajes PacketOut + LLDP deseas ver. Puedes definirlo por switch y/o por puerto. Para el switch, debes usar el datapath_id tal como lo ve la aplicación que estás usando. Por ejemplo, algunas aplicaciones llenan el campo c_id con of:dpid_id, otras con dpid:dpid_id. Para los puertos, usa el OpenFlow port_id, no el nombre del puerto. Por ejemplo, en Brocade, eth1/1 == 1. Así que usa 1 en lugar de eth1/1.
Soporte para proxies de OpenFlow:
Al usar un proxy de OpenFlow, dependiendo de la interfaz que selecciones para sniffear, verás una de las dos posibilidades:
IP_Controller <-> IP_Proxy IP_Proxy <-> IP_Switch