Saltar al contenido

Comprensión de Ryu OpenFlow Controller, mininet, WireShark y tcpdump

Solución:

Esta es probablemente una de las publicaciones más largas que he escrito en Stack Overflow. He estado aprendiendo sobre OpenFlow, SDN y Ryu y me gustaría documentar mis conocimientos para principiantes aquí. Corrija / edite mi publicación si es necesario.

Esta breve guía asume que ya tiene conocimientos de redes informáticas y los principales protocolos de red. Esta guía lo ayudará a comenzar con OpenFlow desde la configuración del sistema.

1. ¿Qué es OpenFlow y SDN?

Lea SDN / OpenFlow | Flowgrammable.

Lectura adicional: El futuro de las redes y el pasado de los protocolos de Scott Shenker y las redes definidas por software, IEEE INFOCOM 2009.

Antes de que empieces:

La capa de infraestructura incluye los enrutadores y conmutadores dentro del núcleo de la red.

La capa de Control incluye la PC que ejecuta un controlador OpenFlow junto con el controlador mismo.

La capa de aplicación incluye las aplicaciones que se ejecutan sobre ese controlador. En Ryu, estas aplicaciones están escritas en Python.

OpenFlow es un protocolo mediante el cual interactúan la infraestructura y la capa de control. OpenFlow no proporciona una API por sí mismo. Es un protocolo de código abierto que utilizan los proveedores que desarrollan conmutadores compatibles con OpenFlow y los desarrolladores que escriben los controladores, como Ryu. La API la proporciona el controlador.

2. Configuración del controlador Ryu OpenFlow en Debian 8

Prerrequisitos

Necesita acceso a Internet. Si está ejecutando Debian dentro de una máquina virtual, emita el siguiente comando para configurar automáticamente su interfaz Ethernet a través de NAT:

su  
dhclient eth0

Habilitar sudo

Debian no viene con sudo por defecto. Algunas aplicaciones de Ryu que usará más adelante requieren sudo. Puede instalar sudo y agregarse a la lista de sudo’ers de la siguiente manera:

su
apt-get install sudo # you might need to do apt-get update first!
nano /etc/sudoers

Busque la línea que dice% sudo ALL = (ALL: ALL) ALL y agregue una entrada inmediatamente debajo de ella:

yourusername ALL=(ALL:ALL) ALL

Presione CTRL + X y luego presione Y para guardar los cambios en el archivo sudoers. Ahora puede cerrar la sesión como root para volver a su propio shell

exit

Habilitar la resolución de pantalla óptima (solo VM)

Si está ejecutando Debian en Virtual Box, la instalación predeterminada no habilita el soporte de resolución de pantalla completa para Virtual Box. Necesitará una pantalla más grande más adelante en la sección 3. Es una buena idea habilitarla ahora.

En la ventana de la máquina virtual, haga clic en Dispositivos> Insertar imagen de CD de adiciones de invitados …

Luego cd al directorio que contiene los archivos

cd /media/cdrom

Debian no le permitirá ejecutar el script debido a problemas de permisos. Copie los archivos en su directorio de inicio, cambie los permisos y luego ejecútelo:

mkdir ~/VBOXGUEST  
cp * ~/VBOXGUEST  
cd ~/VBOXGUEST  
chmod 755 *  
sudo ./VBoxLinuxAdditions.run

Reiniciar

sudo shutdown -r now

Instalar Git

sudo apt-get install git

Instalar Mininet

Mininet le permite emular virtualmente varias interfaces de red en su computadora portátil / PC. Instálelo usando Git:

cd ~  # if you are in some other directory
git clone git://github.com/mininet/mininet
cd mininet
git tag  # this will list available versions
git checkout -b 2.2.1 2.2.1  # replace 2.2.1 with the version you wish to install
cd ..
mininet/util/install.sh -a  # default installation, includes all components, recommended

Te recomiendo que instales OpenFlow Wireshark Dissector. Más tarde, puede instalar Wireshark para analizar paquetes. OpenFlow Wireshark Dissector ayuda a Wireshark a obtener tanta información de los paquetes OpenFlow como sea posible.

mininet/util/install.sh -h

Ejecute el siguiente comando para verificar la instalación de su mininet:

sudo mn --test pingall

Instalar Ryu OpenFlow Controller

Un controlador OpenFlow se comunica entre la capa de control y la capa de infraestructura mediante el protocolo OpenFlow. Además, es el controlador el que proporciona una API para desarrollar aplicaciones SDN que se ejecutan en la capa de aplicación (en la parte superior de la capa de control). Existen numerosos controladores OpenFlow. El controlador Ryu OpenFlow es uno que usa scripts de Python como aplicaciones. Nuevamente, instálelo usando Git:

cd ~
git clone git://github.com/osrg/ryu.git

Instalar Wireshark

sudo apt-get install wireshark

Instale los módulos de Python compatibles

Debian 8.3 viene con Python 2.7 y 3.4 instalados de forma predeterminada. Sin embargo, debe instalar algunos módulos de Python que utilizan las aplicaciones de Ryu (scripts de Python). Puede instalar módulos de Python usando pip:

cd ~/ryu  
sudo apt-get install python-dev python-pip python-setuptools  
sudo pip install .

lo anterior ejecutará automáticamente setup.py ubicado en este directorio y buscará los módulos de Python que faltan del índice de paquetes de Python. El script instalará automáticamente todos los módulos relevantes. Sin embargo, ejecute lo siguiente para asegurarse de que no le falte ningún módulo más adelante:

sudo pip install webob  
sudo pip install eventlet  
sudo pip install paramiko  
sudo pip install routes  

Empezando

Inicie mininet para emular 3 hosts y un conmutador con el siguiente comando:

sudo mn --topo single,3 --mac --switch ovsk --controller remote

Verá un indicador de mininet. Este mensaje se puede utilizar para hacer ping a los hosts, enviar paquetes entre ellos, etc.

Abre otra ventana de terminal para ejecutar Ryu. En este ejemplo, ejecutaremos una aplicación (simple_switch_13.py) que emulará un simple conmutador de capa 2 que reenviará todos los paquetes recibidos a todos los puertos excepto el recibido en.

cd ~/ryu  
PYTHONPATH=. ./bin/ryu-manager ryu/app/simple_switch_13.py

Asegúrese de estar en su directorio de inicio cuando ejecute esto.

Estas listo. Para hacer ping a los hosts y analizar las transmisiones de paquetes, pase a la siguiente sección.

3. Experimentar con Wireshark y tcpdump

En esta sección, dispararemos paquetes de un host a otro usando mininet y analizaremos las transmisiones resultantes usando tcpdump y Wireshark.

La forma en que se transmiten los paquetes es exactamente lo que podemos controlar en redes definidas por software. Hacemos esto escribiendo diferentes aplicaciones que se ejecutan en la parte superior del controlador. Estas aplicaciones forman la capa de aplicación del plano de control SDN.

Configure la topología y ejecute la aplicación de control

Nota: En la sección anterior, creó una topología con mininet e inició una aplicación Ryu para controlar las transmisiones. En caso de que haya reiniciado o salido de alguno de ellos, repito los comandos para crear la topología e iniciar la aplicación Ryu aquí:

cd ~
sudo mn --topo single,3 --mac --switch ovsk --controller remote

y en una ventana de terminal separada:

cd ~/ryu
PYTHONPATH=. ./bin/ryu-manager ryu/app/simple_switch_13.py

Juega con paquetes

En el indicador de mininet, emita lo siguiente para abrir una ventana de consola para cada uno de los tres hosts en la topología que creó:

mininet> xterm h1 h2 h3

¡Apila estas consolas para que puedas verlas todas simultáneamente! Luego, en los xterms para h2 y h3, ejecute tcpdump, una utilidad para imprimir los paquetes vistos por un host:

tcpdump -XX -n -i h2-eth0  
tcpdump -XX -n -i h3-eth0

Nota: Si ha utilizado Wireshark anteriormente, es como capturar paquetes en la interfaz eth0 de estos dos hosts respectivamente.

Al crear la topología, mininet asignó las siguientes direcciones IP a los tres hosts:

h1: 10.0.0.1  
h2: 10.0.0.2  
h3: 10.0.0.3

Desde el shell del host 1, haga ping al host 2 y al host 3 y observe el efecto en las otras dos consolas después de cada comando:

ping 10.0.0.2  
ping 10.0.0.3

Intente hacer ping a un host inalcanzable (host inexistente) y vea el efecto en las consolas:

ping 10.0.0.7

¡Debería haber observado los protocolos ICMP (ping) y ARP (quién tiene esta dirección IP) en vivo en esta sección! También puede hacer lo anterior usando Wireshark en lugar de tcpdump. Esa es una alternativa gráfica a tcpdump.

Nota: La forma en que se envían TODOS los paquetes depende de la aplicación que se ejecute sobre Ryu. Podría escribir una aplicación para eliminar todos los paquetes. En ese caso, sus pings no producirían ningún efecto en las otras dos consolas.

4. Comprensión de la aplicación básica del conmutador de capa 2

En esta sección, analizamos el funcionamiento de una versión simplificada de una aplicación Switch de capa 2 que controlaba las transmisiones de paquetes en la sección 3.

Funcionamiento de un puente de aprendizaje (o un conmutador de capa 2)

Mencioné anteriormente que si está leyendo esta guía, supongo que ya tiene conocimiento de los protocolos de red básicos (¡que incluye el funcionamiento de un conmutador de capa 2, un puente de aprendizaje o un conmutador Ethernet!). Lo resumiré en algunas líneas más abajo independientemente.

Un puente de “aprendizaje” almacena una base de datos de los hosts a los que está conectado, contra sus puertos. Los hosts se identifican por la dirección MAC de su tarjeta de red, que se ve así: ab:cd:ef:12:34:56 (está en hexadecimal). Los puertos se identifican simplemente por su número. Por ejemplo, un conmutador con 4 puertos tiene los puertos 1, 2, 3 y 4.

Si un switch recibe un paquete en su puerto 2, buscará la dirección MAC de destino (a qué host está destinado) de ese paquete. Luego busca en su base de datos para ver si sabe a qué puerto está conectado ese host. Si lo descubre, reenvía ese paquete ÚNICAMENTE a ese puerto específico. Pero si aún no tiene una entrada en su base de datos, inunda ese paquete a TODOS los puertos, y los hosts pueden verificar por sí mismos si el paquete estaba destinado a ellos.

Al mismo tiempo, el interruptor mira el fuente Dirección MAC de ese paquete, e inmediatamente sabe que el host X está ubicado en el puerto 2. Almacena esa entrada en esa base de datos. Entonces, ahora sabe que si el host de destino responde al host de origen, ¡el switch no tendrá que inundar el paquete de respuesta!

Introducción al código Python de la API de Ryu

En lugar de ir directamente a simple_switch_13.py, elija un programa muy simple que no tenga capacidad de “aprendizaje”. Por ahora, no existe una base de datos de reenvío. El siguiente programa es solo un simple conmutador de capa 2 que transmite un paquete recibido a todos los puertos (inunda el paquete):

    from ryu.base import app_manager
    from ryu.controller import ofp_event
    from ryu.controller.handler import MAIN_DISPATCHER
    from ryu.controller.handler import set_ev_cls

    class L2Switch(app_manager.RyuApp):
        def __init__(self, *args, **kwargs):
            super(L2Switch, self).__init__(*args, **kwargs)

        @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
        def packet_in_handler(self, ev):
            msg = ev.msg
            dp = msg.datapath
            ofp = dp.ofproto
            ofp_parser = dp.ofproto_parser

            actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD)]
            out = ofp_parser.OFPPacketOut(
                datapath=dp, buffer_id=msg.buffer_id, in_port=msg.in_port,
                actions=actions)
            dp.send_msg(out)

Las importaciones

No profundizaré en las declaraciones de importación todavía. Discutiremos las importaciones individualmente mientras analizamos el código que las usa.

El esqueleto de la aplicación básica

El siguiente código es una aplicación Ryu perfectamente completa. De hecho, ¡tú también puedes ejecutarlo! Sin embargo, no hará nada:

    from ryu.base import app_manager

    class L2Switch(app_manager.RyuApp):
        def __init__(self, *args, **kwargs):
            super(L2Switch, self).__init__(*args, **kwargs)

Como argumento para la clase, pasamos ryu.base.app_manager.RyuApp import (importado en la primera línea). Del manual de la API de Ryu, app_manager clase es la gestión central de las aplicaciones Ryu. Carga aplicaciones Ryu, les proporciona contextos y enruta mensajes entre aplicaciones Ryu.

El evento EventOFPPacketIn

Un nuevo método packet_in_handler se agrega a L2Switch clase. Esto se llama cuando Ryu recibe un OpenFlow packet_in mensaje. Cuando Ryu recibe un packet_in mensaje, un ofp_event.EventOFPPacketIn se plantea el evento. los set_ev_cls decorador le dice a Ryu cuando la función asociada, packet_in_handler debería ser llamado.

El primer argumento de la set_ev_cls decorador indica un evento que hace que la función sea llamada. Como es de esperar, cada vez que un ofp_event.EventOFPPacketIn se genera el evento, se llama a esta función.

El segundo argumento indica el estado del conmutador cuando desea permitir que Ryu maneje un evento. Probablemente quieras ignorar OpenFlow packet_in mensajes antes de que termine el apretón de manos entre Ryu y el interruptor. Utilizando MAIN_DISPATCHER ya que el segundo argumento significa que esta función se llama solo después de que se completa la negociación. MAIN_DISPATCHER denota el estado normal del interruptor. Durante la etapa de inicialización, el interruptor está en HANDSHAKE_DISPATCHER ¡estado!

Ahora veamos el cuerpo de la función. Lo dividiremos en dos partes.

    msg = ev.msg  
    dp = msg.datapath  
    ofp = dp.ofproto  
    ofp_parser = dp.ofproto_parser

ev.msg es una estructura de datos que contiene el paquete recibido.

msg.dp es un objeto dentro de esa estructura de datos que representa una ruta de datos (conmutador).

dp.ofproto y dp.ofproto_parser son objetos que representan el protocolo OpenFlow que Ryu y el conmutador negociaron.

    actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD)]  
    out = ofp_parser.OFPPacketOut(  
        datapath=dp, buffer_id=msg.buffer_id, in_port=msg.in_port,  
        actions=actions)  
    dp.send_msg(out)

OFPActionOutput la clase se usa con un packet_out mensaje para especificar un puerto de conmutador desde el que desea enviar el paquete. Dado que no hay una base de datos de reenvío en esta aplicación simplificada, inundamos el paquete a todos los puertos, por lo que la constante OFPP_FLOOD se utiliza.

OFPPacketOut la clase se usa para construir un packet_out mensaje.

Mediante el uso datapath clase send_msg , puede enviar un objeto de mensaje OpenFlow a los puertos definidos en la variable de acciones. Repito, en este caso, las acciones se construyen de manera que el destino incluya TODOS los puertos.

Eventos

Viste repetidamente el término evento en el código anterior. En la programación impulsada por eventos, el flujo de El programa está controlado por eventos, que son provocados por mensajes recibidos por el sistema (p. ej. EventOFPPacketIn se levanta cuando el packet_in se recibe el mensaje por Ryu de el interruptor (OpenFlow habilitado)). Anteriormente discutimos que OpenFlow es un protocolo mediante el cual el controlador (Ryu, PC) y la infraestructura (o conmutador) se comunican. Mensajes como packet_in son exactamente como se ve la comunicación entre los dos usando el protocolo OpenFlow!

Próximos pasos

Es posible que desee seguir adelante y crear sus propias aplicaciones Ryu. Aprender la API de Ryu (o el lenguaje Python, si aún no está familiarizado con él) podría ser un buen punto de partida. ¡Buena suerte!

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *