Siguiendo con la serie de posts sobre OpenvSwitch y OpenNebula en los que vamos viendo la integración de OpenNebula con Open vSwitch a través del driver, vamos a ver en esta entrega cómo poder aplicar firewalling con OpenNebula al driver de OpenvSwitch.
Para empezar, vamos a ver como se configura el firewalling en general con OpenNebula, en este enlace podemos ver mas detalles. OpenNebula tiene cinco campos especiales a la hora de crear una màquina/template que són:

  • WHITE_PORTS_TCP: Se filtran todos los puertos tcp menos los especificados por el parámetro, para especificarlo se hace con “:” para rangos de puertos y con “,” para puertos especificos. Así pues si queremos filtrar todos los puertos menos el 22, el 80 i del 2000 al 3000  se pasaria la variable de la siguiente forma: WHITE_PORTS_TCP = 22,80,2000:3000  
  • BLACK_PORTS_TCP: Se filtran sólo los puertos tcp especificados, para especificar los puertos a filtrar se hace de la misma forma que con el WHITE_PORTS_TCP, però en este caso el funcionamiento es el inverso, és decir se filtran todos los puertos especificados y el resto se dejan abiertos. En caso de especificar tanto el WHITE_PORTS_TCP cómo el BLACK_PORTS_TCP, entonces se aplican sólo los WHITE_PORTS_TCP. Si quisieramos filtrar todos los puertos menos el 22, 80 i del 2000 al 3000, en este caso se especificaria de la siguiente forma:  BLACK_PORTS_UDP = 1:21,23:79,81:1999,3001:65535
  • WHITE_PORTS_UDP: En este caso el funcionamiento és idéntico al TCP pero con tráfico UDP.
  • BLACK_PORTS_UDP: También este caso es idéntico al TCP pero con UDP.
  • ICMP: En el caso de ICMP podemos optar por filtrar todo el tráfico o no, si queremos filtrarlo, lo especificaremos de la siguiente forma: ICMP = drop

Para la implementación de esta funcionalidad con Open vSwitch, en el driver actual de OpenNebula no se pueden especificar rangos de puertos, se tienen que hacer uno a uno. Se ha provado i si se crean máquinas virtuales con muchos puertos filtrados, tarda muchas horas en crear la máquina virtual y añade mucha carga adicional al nodo físico. Para solventarlo tendremos que actualizar la versión de open vSwitch a la 1.6 o superior, ya que a partir de esta se pueden especificar los puertos con mascaras. Con las mascaras podemos especificar un puerto y la mascara asociada, la cual cosa nos permitirá filtrar todo el rango de puertos a los que se llegue con esta. Si por ejemplo quisieramos filtrar del puerto 32768 al 65535, podriamos hacerlo especificanod el puerto y la mascara de la siguiente forma (en hexadecimal): 0x8000/0x8000. Aqui podemos ver como el numero 32768 equivale a 0x8000 (el primero) y el rango de puertos que estaremos filtrando irá del 0x8000 (1000 0000 0000 0000) al 0xFFFF (1111 1111 1111 1111)  és decir el 65535 después de aplicarle la mascara.
Vemos pero que si queremos aplicar un filtro que vaya del puerto 32769 al 65535 la cosa no es tan evidente, ya que tenemos que hacer un filtro que para el 32769/0xFFFF, otro para el 32770/0xFFFE, otro para el 32772/0xFFFC y asi sucesivamente.
Así pues el algoritmo para el filtrado con rangos de puertos será:
Para todos los puertos p:

  1. Calculamos la máscara máxima para no filtrar algun puerto ya filtrado o que no se tenga que filtrar
  2. Calculamos la máscara máxima para los puertos que se tendrán que filtrar a continuación, hasta encontrar alguno que no sea consecutivo
  3. Aplicamos la mascara más pequeña entre 1 y 2.
  4. Aplicamos el filtro con la máscara escogida
  5. p= maximo puerto filtrado en 4 (aplicando mascara) + 1

En el ejemplo de que quisieramos filtrar todos los puertos menos el 22,80 y del 2000 al 3000, las reglas correspondientes quedarian de la siguiente forma:

0x1/0xffff, 0x2/0xfffe, 0x4/0xfffc, 0x8/0xfff8, 0x10/0xfffc, 0x14/0xfffe,
0x17/0xffff, 0x18/0xfff8, 0x20/0xffe0, 0x40/0xfff0, 0x51/0xffff, 0x52/0xfffe,
0x54/0xfffc, 0x58/0xfff8, 0x60/0xffe0, 0x80/0xff80, 0x100/0xff00, 0x200/0xfe00,
 0x400/0xfe00, 0x600/0xff00, 0x700/0xff80, 0x780/0xffc0, 0x7c0/0xfff0,
0x7d1/0xffff, 0x7d2/0xfffe, 0x7d4/0xfffc, 0x7d8/0xfff8, 0x7e0/0xffe0,
0x800/0xfe00, 0xa00/0xff00, 0xb00/0xff80, 0xb80/0xffe0, 0xba0/0xfff0,
0xbb0/0xfff8, 0xbb9/0xffff, 0xbba/0xfffe, 0xbbc/0xfffc, 0xbc0/0xffc0,
0xc00/0xfc00, 0x1000/0xf000, 0x2000/0xe000, 0x4000/0xc000, 0x8000/0x8000

Así pues, vemos que con este ejemplo pasariamos de 64532 reglas para aplicar a 43 gracias a las mascaras.

Actualización del driver de OpenNebula

Una vez visto que es lo que tenemos que hacer para que nos funcionen los drivers para OpenvSwitch con mascaras vamos a ver las modificaciones que se tienen que hacer en el driver de OpenNebula para Open vSwitch. El fichero en cuestión se encuentra en /var/lib/one/remotes/vnm/ovswitch/OpenvSwitch.rb. Aqui podeis encontrar el fichero con las modificaciones que se han explicado en el post.
Para modificar el driver, lo único que tenemos que hacer és sobreescribir el fichero y ejecutar:

onehost sync

Una vez ejecutado el comando ya podremos crear máquinas virtuales pasandoles los parametros de filtraje como con el driver por defecto.
Oriol Marti
www.cloudadmins.org