Archivo de la categoría: Diario de traballo

Hemos sufrido un ataque de fuerza bruta en WordPress

wordpress-265132_1280Ayer algunos habéis notado que los dominios proxectos.citius.usc.es, demos.citius.usc.es y persoal.citius.usc.es no funcionaban, y eso fue debido a que recibimos el aviso de que el servidor estaba infectado con un botnet.

Ya hemos sufrido algo parecido en el pasado en ese mismo servidor. En esta ocasión, no ha sido por una vulnerabilidad sino por un ataque de fuerza bruta en uno de los WordPress instalados en el servidor para un proyecto.

Tras comprobar los logs y restaurar una copia de seguridad previa al desastre, hemos comprobado que las medidas que tomamos en febrero mitigaron los efectos (el bot no era capaz de lanzarse a sí mismo y requería una petición HTTP para lanzarse cada poco tiempo), pero aún así no se pudo prevenir la infección ni su funcionamiento por completo.

Qué ha pasado

El 4 de noviembre, a las 6 de la madrugada, recibimos durante 4 horas un total de 2411 peticiones de intento de identificación en uno de los blogs, hasta que finalmente el robot pudo entrar, cambiar las contraseñas de dicho WordPress y modificar un tema usando el editor incorporado, cambiando archivos legítimos por otros que permitían a su vez infectar la máquina con más malware.

Actualización: Es cierto que con tan solo 2411 peticiones es difícil hacer un ataque de fuerza bruta, a no ser que la contraseña sea muy débil. Por desgracia, no guardamos información del tamaño de los bytes enviados ni recibidos para poder detectar si se trata de un ataque tipo BREACH o similar, aunque también es posible.

Qué podemos hacer para evitarlo

Hay varias recomendaciones que los usuarios de WordPress pueden seguir para evitar estos ataques de fuerza bruta. Hemos recomendado a todos ellos que las apliquen.

No obstante, también hemos implementado medidas adicionales de seguridad:

Hemos habilitado, en ese servidor, una revisión constante de ClamAV, un antivirus que es capaz de detectar este tipo de exploits, para que nos informe en cuanto detecte algún archivo sospechoso. En esta ocasión, ClamAV ha sido capaz de detectar los archivos, y de haber estado funcionando este sistema, lo habríamos detectado mucho antes.

También hemos instalado fail2ban, una solución que gestiona una lista negra del sistema (el archivo deny.hosts) en base a determinadas reglas que se pueden definir arbitrariamente. Por ejemplo, se puede hacer que compruebe intentos de conexión a logins de WordPress reiterados. Una vez en la lista negra en la que se mantendrá durante un tiempo prudencial, el servidor web rechazará cualquier conexión desde esa IP. Hasta ahora utilizábamos otras soluciones que no permitían definir este tipo de reglas y tan solo eran capaces de bloquear intentos de login fallidos en servicios conocidos.

Actualización: No lo comentamos originalmente, pero también aplicamos algunas medidas de seguridad adicionales. Desde luego, es cierto que parece una posibilidad que esto no se trate de un simple ataque de fuerza bruta, sino de un ataque tipo BREACH (u otros derivados de técnicas de compresión y SSL), por lo que hemos tomado también las medidas recomendadas para mitigar dichos ataques. En cualquier caso, bloqueando peticiones reiteradas a páginas de login, este tipo de ataques tampoco serían posibles.

Con estas mejoras, esperamos poder mitigar este tipo de ataques y poder responder más rápido ante posibles problemas de este tipo en un futuro.

Todo era alegría en Bash hasta que Shellshock

El jueves de la semana pasada salió a la luz un fallo de seguridad que afecta a Bash, el intérprete de comandos detrás de muchos sistemas con Linux y Mac OS X.

El bug se produce porque, a la hora de definir variables de entorno, utilizando una sintaxis determinada se consigue ejecutar código que a su vez se almacena dentro de la variable, algo que lógicamente no debería estar permitido. Veamos un ejemplo:

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

Con este comando se ejecuta una nueva shell de Bash, pasándole una definición de una variable que contiene un método que no hace nada y un comando justo después de la definición, que se ejecuta justo cuando la variable se define.

Algunas televisiones partidarias de shells alternativas piensan que Bash es un bug en sí mismo

Algunas televisiones partidarias de shells alternativas piensan que Bash es un bug en sí mismo. Fuente: @crazybob

Este bug permite realizar varios ataques ya probados: escalada de privilegios de un usuario normal, ejecución de comandos en shells de SSH restringidas… ¿Un user agent de un navegador llamado () { :;}; rm -rf /? ¿Por qué no?. Las consecuencias podrían ser desastrosas.

Como pasó en la época del Heartbleed y OpenSSL, mucha gente ha centrado ahora su mirada en Bash y se han encontrado nuevos fallos de seguridad relacionados y no relacionados. En los servidores (y equipos de escritorio que administramos) del centro, Bash se actualiza regularmente con las actualizaciones de seguridad de las distribuciones, que ya han publicado varias versiones nuevas que van corrigiendo todos estos fallos.

En la Wikipedia van sintetizando toda la nueva información que va surgiendo, con enlaces a las fuentes interesantes, así que recomendamos echar un vistazo a su artículo si queréis más información sobre este tema. La página ShellShocker.net también resume toda la información y ofrece recursos para probar los sistemas y parchear Bash de forma manual, muy útil para sistemas antiguos.

Actualización del cloud IaaS a Cloudstack 4.3

La semana pasada actualizamos el cloud a Cloudstack 4.3, que soluciona muchos problemas que teníamos con la versión 4.1 que lanzamos como servicio el año pasado.

cloudmonkey-fp

  • Ahora es posible cambiar la cuenta de las máquinas virtuales desde la interfaz, así que se pueden asignar a un proyecto o a otro usuario después de crearse.
  • Además de añadir más discos secundarios para datos, se puede ampliar el tamaño de los discos de datos existentes (pero no del principal).
  • Las plantillas se asocian correctamente a las cuentas de los proyectos, así que ya no es necesario que sean públicas para poder utilizarlas, o borrarlas.
  • Ahora es posible añadir varias IPs a una misma interfaz de red y asignar varias redes a una misma máquina virtual.

Se pueden consultar las notas de la versión 4.2.0 y la versión 4.3.0, aunque están dirigidas a administradores.

Además, hemos ampliado el almacenamiento secundario, que es el espacio en el que se guardan las plantillas y las ISOs, con 2TB más, para evitar los problemas de escasez que había hasta ahora.

Servidor comprometido no centro

Este luns recibimos unha chamada da Área TIC da Universidade, xa que detectaran ataques de forza bruta contra sitios web WordPress de Internet dirixidos dende un dos nosos servidores.

A IP correspondía non cun servidor, senon cunha rede virtual na que hai dez servidores, que son os que proven servizos web, así que houbo que identificar a máquina pola nosa parte. Tampouco foi moito problema, xa que tiñamos sospeitas de onde podía estar o problema: no servidor virtual onde se atopan as páxinas persoais, de proxectos e de eventos.

Efectivamente, despois de apagar esa máquina os ataques cesaron por completo, polo que procedemos a illala da rede para analizar o que estaba pasando.

Seguindo as mesmas sospeitas que nos levaron a apagar a máquina, comezamos por analizar os logs de acceso de Apache, para localizar execucións de scripts que non deberan estar aí.

10.1.98.xxx - - [16/Feb/2014:22:44:22 +0100] "POST /xxx/wp-content/themes/project-ar2-master/stylegreen.php HTTP/1.0" 200 5551 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100102 Firefox/16.0"
10.1.98.xxx - - [16/Feb/2014:22:44:22 +0100] "POST /xxx/wp-content/themes/project-ar2-master/stylegreen.php HTTP/1.0" 200 5551 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100102 Firefox/16.0"
10.1.98.xxx - - [16/Feb/2014:22:44:23 +0100] "POST /xxx/wp-content/themes/project-ar2-master/stylegreen.php HTTP/1.0" 200 8422 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100102 Firefox/16.0"
10.1.98.xxx - - [16/Feb/2014:23:18:50 +0100] "GET /xxx/wp-content/themes/project-ar2-master/flotch-style.php HTTP/1.0" 200 324 "http://pinglard.com/pinglord/lordos.php?t=4" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
10.1.98.xxx - - [16/Feb/2014:23:41:24 +0100] "GET /xxx/wp-content/uploads/function_php.php HTTP/1.0" 500 642 "http://hennexxx.com/the-henxxx/hennexxxtuff.php?t=4" "Opera/9.80 (Windows NT 6.1; WOW64; U; ru) Presto/2.10.289 Version/12.00"

Aclaramos que as xxx varias son para tapar as vergoñas. En calquera caso vemos como, tras executar peticións POST a un script pertencente a un tema de WordPress chamado Project-Ar2, fai unha chamada a un arquivo chamado /xxx/wp-content/uploads/function_php.php que, loxicamente, non debera estar aí.

Este arquivo tratábase dun botnet, moi similar ó que denuncian nesta bitácora. Só que en lugar de tratarse dun plugin falso, o script subiuse usando un exploit dun tema de WordPress.

Esquema que ilustra o funcionamento dun botnet, pertencente á Wikipedia (cc-by-sa Tom-b)

Esquema que ilustra o funcionamento dun botnet, pertencente á Wikipedia (cc-by-sa Tom-b)

Ó citado botnet non lle basta con executarse subindo un código PHP ó servidor, xa que normalmente estes scripts execútanse nun entorno no que están moi limitados en tempo de execución e en permisos. O script en si o que fai é intentar saír deste entorno. No noso caso conseguiuno, engadíndose ó crontab do usuario que executaba PHP. Unha vez executado, o primeiro que fai é borrarse do crontab para non deixar rastro.

Aínda así, executar un binario tampouco é doado, porque é habitual que as particións onde pode escribir ese usuario non teñan permisos de execución, así que o que fixo foi escribir unha biblioteca compartida que reimplementaba algunha función elemental co código malicioso, e executar calquera binario do sistema usando a técnica do LD_PRELOAD.

Determinar que fixo exactamente no sistema non é doado, pero todos os indicios apuntan a que non conseguiu gañar acceso de superusuario, e que de feito parece que nin sequera o chegou a intentar.

Tras pedir as pertinentes desculpas e rematar o análise, volvimos a poñer o servidor en marcha.

Este problema podería haberse evitado, por suposto. Bastaría con ter deshabilitado o cron nos usuarios que executan PHP, ou non permitir o uso de funcións de PHP coma system ou shell_exec, ou usar open_basedir para negar a PHP abrir ou executar arquivos fora da ruta que sirve os arquivos PHP.

Por suposto, aplicamos inmediatamente todas as recomendacións que nos fixemos a nos mesmos, que se unen ó uso do módulo suphp e outras boas prácticas máis básicas que xa viñamos empregando.

Como curiosidade, moitos de vos notastes este luns coma Google pedía un captcha ó utilizar os seus servizos dende o centro. Efectivamente, foi por culpa disto.

Firefox y los certificados expedidos por RedIRIS

Tanto la Universidad como el CiTIUS utilizan el Servicio de Certificados de RedIRIS para servidores, que les provee certificados de forma gratuíta expedidos por TERENA a través del TERENA Certificate System.

TERENA es una organización europea cuyo objetivo es el desarrollo de infraestructuras en educación e investigación. En cuanto a su servicio, es una autoridad certificadora intermedia que obtiene los certificados de Comodo, una autoridad certificadora que sí es de primer nivel.

Aunque la mayoría de los navegadores contienen los certificados de las autoridades Comodo y TERENA, hay un navegador ampliamente utilizado que se resiste a incluír el certificado intermedio de Terena, Firefox.

Todo esto se resume en que al entrar con Firefox en una página segura que utilice un certificado expedido por RedIRIS, aparecerá una advertencia porque el navegador desconoce el certificado de TERENA, y por lo tanto no puede validar el certificado del servidor.

Firefox 26 mostrando una advertencia de certificado en la página web del CiTIUS

Afortunadamente, este problema se puede solventar incluyendo junto al certificado del servidor, el certificado de la propia autoridad intermedia, algo que ya se hacía para la página de la USC y ahora también para la del CiTIUS.

¿Por qué ocurre esto?

Comprobar la identidad de un sitio web es fundamental en una conexión segura, y para ello los servidores envían un certificado firmado por una autoridad certificadora. Los navegadores, habitualmente conocen y confían en estas autoridades.

Firefox, al no incluír a TERENA entre las autoridades certificadoras confiables, no puede verificar la identidad de los sitios web que envíen certificados expedidos por ellos.

Sin embargo, TERENA es una autoridad certificadora de segundo nivel, lo que significa que ejerce de intermediaria entre los usuarios finales de los certificados (o incluso autoridades de nivel inferior) y una autoridad certificadora de primer nivel, en este caso Comodo. Firefox sí incluye el certificado a Comodo entre las autoridades certificadoras confiables.

Al configurar el servidor para que envíe el certificado emitido por TERENA, más el certificado que identifica a la propia TERENA, Firefox puede identificar a TERENA como autoridad certificadora confiable, y a su vez comprobar la identidad del certificado emitido.

Preparándose para el invierno más frío

Dice la prensa que este será el invierno más frío de los últimos 100 años, o de los últimos 60 años dependiendo de la fuente. En cualquier caso, parece que este será un invierno complicado.

Este fin de semana hemos sufrido una caída del servicio por culpa del frío –la primera de este año. Concretamente, -1,5ºC de frío según el histórico de Meteogalicia.

Mientras esperamos que se arreglen ciertos problemas burocráticos para la instalación de una solución definitiva, hacemos lo que podemos. El año pasado comenzamos tapando la ventilación manualmente en las zonas más afectadas como primera medida, y más tarde acordamos con los servicios de la universidad un apagado automático de la ventilación por la noche.

Este año todavía no nos hemos atrevido a solicitar ese apagado automático, porque si bien a los servidores no les hace ningún bien escupirles aire a -1,5ºC, dejarlos sin ningún tipo de ventilación puede ser también peligroso, por lo que tenemos que asegurarnos que el invierno ha llegado de verdad.

Vale, y a estas alturas creo que todos estamos de acuerdo en que ha llegado.

Por supuesto, sabiendo que este problema existía, este año nos hemos preparado replicando los servicios más esenciales en servidores que están situados más lejos de la ventilación.

Como curiosidad, esta es una lectura de la temperatura del aire de una sonda situada en la entrada de aire de uno de los servidores afectados, durante los dos últimos meses.

Lectura de temperaturas de los 2 últimos meses

Menudo mes de noviembre. En la lectura de la última semana puede verse mucho mejor el problema de este fin de semana. Al bajar de 4º, el servidor en cuestión se apaga (y como ese, muchos otros).

Lectura de temperaturas de última semana

Alternative PHP Cache

Alternative PHP Code es un módulo de PHP que almacena la salida del compilador de bytecode de PHP en memoria compartida, de forma que reduce el tiempo de análisis y acceso a disco de cargas posteriores.

Este módulo convierte a PHP en algo similar a lo que hacen los intérpretes de otros lenguajes como Python por ejemplo. Python guarda este bytecode en archivos con la extensión pyc para luego reutilizarlo, en lugar de analizar y compilar cada archivo de código fuente cada vez.

Los tiempos de carga de aplicaciones como Drupal se mejoran considerablemente, algo que ya se puede notar ahora mismo en la página web del centro.

Para probarlo, hemos utilizado ab, una herramienta de benchmarking incluída con el paquete apache2-utils.

grafica_php-apc_1

Esta prueba muestra el tiempo medio de la petición del documento principal de tres páginas interiores diferentes del CiTIUS desde la red interna del centro. Se han hecho un total de 100 peticiones por prueba.

El tiempo de carga incluye todo el intervalo de tiempo desde que se solicita el documento hasta que se recibe completo. En los tres casos se aprecia una mejora notable usando PHP con el módulo de APC, con tiempos que en ningún caso alcanzan los 60ms, comparado con PHP sin el módulo, con tiempos que no bajan nunca de los 120ms.

grafica_php-apc_2

Haciendo la misma prueba desde un servidor localizado en otro país, estas diferencias no son tan notables porque APC solo influye en el tiempo en que PHP tarda en compilar el documento, y en este caso aparecen otros tiempos más constantes entre ambas pruebas, causados por la conexión en si. Con todo ello, se aprecian claramente las mejoras de velocidad, que rondan el 30%.

Sistemas de archivos de disco compartido

Introducción

A la hora de diseñar e implementar un servicio como el Cloud o el cluster de computación del Citius hay que incluir una solución para el almacenamiento que tenga las características requeridas. En este caso el requisito más relevante es que el servicio lo componen un número variable de servidores físicos que deben poder acceder a la vez al mismo almacenamiento. Esto permite, por ejemplo, que en el caso del Cloud si un servidor físico se cae otro pueda levantar las máquinas virtuales que estaban en funcionamiento en él ya que puede acceder a sus ficheros de manera inmediata. En el caso del cluster de computación, todos los nodos de computación tienen acceso a los mismos datos, incluso aunque cada nodo los vaya actualizando con el resultado de sus cálculos.

Hay varias aproximaciones posibles a este problema; es posible por ejemplo usar DRBD , o también podría resolverse mediante un servidor NFS que ofreciera el almacenamiento a través de la red local. Otra posibilidad sería implementar una SAN que permita a los servidores conectarse al almacenamiento a través de una red dedicada.

La solución de DRBD escala mal a medida que aumenta el número de servidores y añade mucha sobrecarga en la red y NFS no obtiene el mismo rendimiento que un disco conectado localmente, por lo que optamos por la SAN.

Una vez decidido que el almacenamiento consistirá en una cabina de discos accesible a través de una red SAN queda la elección del sistema de ficheros. El problema consiste en que necesitamos un sistema de ficheros que permita montarlo simultáneamente desde varios servidores para realizar lecturas y escrituras concurrentes, es decir, necesitamos un sistema de ficheros de disco compartido.

De entre todos los sistemas de ficheros de este tipo vamos a centrarnos en dos que son libres:

  • GFS2 (Global File System 2) desarrollado por RedHat
  • OCFS2 (Oracle Cluster File System 2) desarrollado por Oracle.

Antes de elegir uno de los dos  hemos realizado unas pruebas de rendimiento “informales” para ver si alguno de los dos destaca en ese aspecto.

Las pruebas

Descripción del sistema

Damos como referencia las características del sistema en el que se ha hecho el benchmark:

La cabina es una HP P2000 G3 accedida por iSCSI 1Gb desde 2 Broadcom NetXtreme II BCM57810 10Gb con driver bnx2X v1.70.30-0. La Lun ofrecida desde la cabina está formada por 6 discos de 2TB de 7.2k rpm en RAID 6.

En el caso de OCFS2 el sistema operativo es Ubuntu 12.04 con un kernel 3.20-45-generic con open-iscsi 2.0.871-0ubuntu9.12.04.2 y multipath-tools 0.4.9-3ubuntu5.

En el caso de GFS2 el sistema operativo es CentOS 6.4  con un kernel  2.6.32-358.14.1.el6.x86_64 con iscsi-initiator-utils 6.2.0.873-2.el6.x86_64 y device-mapper-multipath-0.4.9-64.el6_4.1.x86_64. Se ha usado CentOS porque los paquetes de GFS2 de Debian/Ubuntu estan marcados como “experimental, no usar en producción”.

Hay que aclarar que el objetivo de las pruebas no es obtener una medida real sobre las capacidades de entrada/salida del conjunto del sistema sino simplemente poder comparar las diferencias de rendimiento entre los sistemas de ficheros de modo que tengamos un nuevo elemento de juicio antes de elegir uno. Para conocer las complicaciones de realizar un benchmark “serio” recomiendo la lectura de este post.

Copia de un fichero con dd

Como primera prueba realizamos la copia de un archivo con el comando dd. Con esta prueba medimos la velocidad de lectura y escritura secuencial en el disco. Hay que resaltar que las conexiones iSCSI de 1Gb nos fijan un máximo teórico de transferencia de unos 125 MB/s.
Los parámetros son los siguientes:

  • if define el dispositivo de origen, para la prueba de escritura usamos /dev/zero que es un dispositivo especial que devuelve tantos ceros como caracteres se intenten leer de él. Para la prueba de lectura el origen es el fichero creado en la prueba anterior.
  • of define el dispositivo de destino, en la prueba de escritura es un fichero en el almacenamiento remoto, en la prueba de lectura es /dev/null que es un dispositivo especial que descarta lo que se escribe en él pero informando de una escritura correcta.
  • bs número de bytes que se escriben o leen en un bloque.
  • count número de bloques que se leen o escriben en total.
  • conv=fsync (solo para la escritura) hace que se escriban físicamente los datos y metadatos en disco antes de terminar. Si no se usa esta opción hay un pequeñio desfase de  tiempo ya que dd da por terminada la escritura en cuanto los últimos datos entran en la cache, y no cuando se escriben físicamente en el disco.

La elección del tamaño del fichero (que sale de multiplicar bs * count) no es trivial, ya que si se escoge un tamaño menor que la memoria RAM del equipo, lo que medimos es el rendimiento de lectura o escritura a la caché del sistema, no al disco. Eligiendo un tamaño el doble de la RAM del equipo nos aseguramos de saturar la cache y que deje de ser un factor.

Escritura:

dd if=/dev/zero of=/mnt/secundario/kk2.img bs=1k count=128000000 conv=fsync

Lectura:

dd if=/mnt/secundario/kk2.img of=/dev/null bs=1k count=128000000

Para tener una referencia se ha realizado la misma prueba con el sistema de ficheros ext4 montado localmente y como curiosidad también servido mediante NFS con las opciones de montaje por defecto.
Los resultados fueron:

  • ext4:

Lectura: 80,1 MB/s
Escritura: 129,6 MB/s

  • OCFS2:

Lectura:  79,6 MB/s
Escritura:  85,2 MB/s

  • GFS2:

Lectura: 82,5 MB/s
Escritura:  73,4 MB/s

  • NFS

Lectura: ~5 MB/s
Escritura:  ~5 MB/s

Se observa en principio que ext4 es sensiblemente más rápido que los otros escribiendo, que entre OCFS2 y GFS2 el rendimiento es parecido y que NFS da valores anormalmente bajos muy probablemente por las opciones de montaje.

Benchmarking con Bonnie++

Para hacer una prueba un poco más seria hemos usado el programa de benchmark Bonnie++, en su versión 1.96. El comando es:

bonnie++ -d /mnt -n 128 -s 128g

donde:

  • -d indica el directorio de trabajo
  • -n el numero de ficheros múltiplo de 1024 que se usaran en las pruebas de creación de ficheros.
  • -s el tamaño de fichero que se usará en las pruebas de lectura/escritura. De nuevo el doble que la RAM.

Bonnie da los resultados en forma de tabla. He resaltado en rojo los dos resultados más relevantes para nuestra comparación, que son las velocidades de lectura/escritura secuencial:

Ext4

Version 1.96 Sequential Output Sequential Input Random
Seeks
Sequential Create Random Create
Size Per Char Block Rewrite Per Char Block Num Files Create Read Delete Create Read Delete
K/sec % CPU K/sec % CPU K/sec % CPU K/sec % CPU K/sec % CPU /sec % CPU /sec % CPU /sec % CPU /sec % CPU /sec % CPU /sec % CPU /sec % CPU
ctusercld02 126G 678 99 125342 44 52368 19 2558 98 115157 24 980.9 16 128 38900 66 +++++ +++ 10706 17 35788 67 +++++ +++ 12181 21
Latency 21643us 10012ms 9435ms 17472us 10342ms 1059ms Latency 307ms 808us 4626ms 317ms 36us 1738ms

GFS2

Version 1.96 Sequential Output Sequential Input Random
Seeks
Sequential Create Random Create
Size Per Char Block Rewrite Per Char Block Num Files Create Read Delete Create Read Delete
K/sec % CPU K/sec % CPU K/sec % CPU K/sec % CPU K/sec % CPU /sec % CPU /sec % CPU /sec % CPU /sec % CPU /sec % CPU /sec % CPU /sec % CPU
ctusercld01.user.cloud.citius 126G 324 98 104253 32 46590 27 656 28 65339 9 744.2 20 128 1474 55 150173 99 6754 62 1287 71 160639 99 7433 65
Latency 156ms 78807ms 23230ms 1652ms 768ms 1585ms Latency 3175ms 561us 508ms 1239ms 133us 79623us

OCFS2

Version 1.96 Sequential Output Sequential Input Random
Seeks
Sequential Create Random Create
Size Per Char Block Rewrite Per Char Block Num Files Create Read Delete Create Read Delete
K/sec % CPU K/sec % CPU K/sec % CPU K/sec % CPU K/sec % CPU /sec % CPU /sec % CPU /sec % CPU /sec % CPU /sec % CPU /sec % CPU /sec % CPU
ctusercld02 126G 354 99 128296 65 55756 31 1323 99 99257 21 919.9 16 128 306 97 +++++ +++ 6960 44 322 97 +++++ +++ 737 59
Latency 46812us 31391ms 1173ms 20976us 78835us 976ms Latency 480ms 45us 1229ms 383ms 128us 11242ms

Una breve explicación de lo que significa cada valor de la tabla:

Para las pruebas de lectura/escritura Bonnie usa tantos ficheros de hasta 1GB como sean necesarios para llegar al valor indicado por el parámetro -s, en este caso 126. Para las pruebas de creación de ficheros Bonnie usa tantos ficheros como se le indica en el parámetro -n multiplicado por 1024.

Para cada prueba Bonnie informa del uso de CPU (el valor %CPU) . Si algún valor es demasiado pequeño como para medirlo con exactitud, Bonnie muestra ++++ .

  • El sequential output per char escribe un byte cada vez usando la macro stdio putc(). La CPU debe ejecutar el código y asignar el espacio de archivo.
  • El sequential output block escribe el fichero usando invocaciones a write() más eficientes porque son a nivel de bloque. Aquí la CPU sólo asigna el espacio de archivo.
  • El sequential output rewrite  lee los metadatos del fichero, los modifica y los reescribe físicamente de modo que se requiera una operación lseek.filesystem cache and the speed of data transfer. LA CPU no realiza asignación de espacio de archivo en esta prueba, por lo que se mide la efectividad de la caché del sistema de archivos y la velocidad de transferencia.
  • El sequential input per char es igual que el output pero en lectura.
  • El sequential input block es igual que el output pero en lectura.
  • Random seeks realiza más de 8000 llamadas lseek() aleatorias para hacer un read() del resultado, y en un 10% de los casos además un write(). El resultado está fuertemente influenciado por el número de discos presentes en un RAID.
  • Sequential y random create crean y luego borran el número de ficheros designado de forma secuencial y aleatoria respectivamente.

Los resultados ordenados de mayor a menor  en lectura secuencial:

  • Ext4:  115 MB/s
  • OCFS2:  99 MB/s
  • GFS2:   65  MB/s

Se observa claramente el mejor comportamiento del sistema de archivos no compartido frente a los compartidos, y especialmente frente a GFS2, que ofrece un rendimiento especialmente pobre.

Los resultados ordenados de mayor a menor  en escritura secuencial (aquí hay que hacer notar el límite máximo impuesto por la conexión iSCSI de 125MB/s) :

  • OCFS2:  128 MB/s
  • Ext4 :  125 MB/s
  • GFS2:   103  MB/s

En este caso hay un empate virtual entre OCFS2 y ext4 que no es posible deshacer porque en el entorno de los 125 MB/s el cuello de botella pasa a ser la conexión iSCSI. En todo caso mencionar el buen rendimiento de todos los sistemas de ficheros aunque de nuevo GFS2 queda un poco por detrás.

Los resultados ordenados de mayor a menor de la re-escritura:

  • OCFS2:  55,7 MB/s
  • Ext4:  52,3 MB/s
  • GFS2:   46,6  MB/s

De nuevo un rendimiento parecido aunque otra vez GFS2 queda por detrás.

Conclusiones

Para obtener unos resultados realmente fiables y precisos sería necesario cambiar la metodología del benchmarking repitiendo las pruebas más veces, variando los parámetros y asegurándose de limpiar las cachés entre cada una. Cada prueba de Bonnie o de dd tarda en torno a las dos horas, así que teniendo en cuenta que el objetivo solo era tener un elemento de decisión entre GFS2 y OCFS2 estas pruebas sencillas nos bastan.

El benchmark indica que OCFS2 ofrece un rendimiento mayor que GFS2. Este resultado coincide con las pocas informaciones al respecto que pueden encontrarse en internet, por lo que finalmente escogimos OCFS2 como sistema de archivos.

Sin embargo, en la práctica resulto que OCFS2 es un sistema de archivos menos estable que GFS2, sobre todo cuando hay “movimiento” de nodos. Esto ocurría por ejemplo en el cluster de computación, donde los nodos se apagan y se encienden en función de la carga del sistema. Es por eso que poco a poco lo estamos sustituyendo por GFS2 donde es posible (ya que lo hemos probado y efectivamente en debian/ubuntu es muy inestable aún).

Hardware para GPU computing

Hace unos días considerábamos la posibilidad de ampliar las capacidades de GPU computing del CITIUS, que en este momento consisten en dos servidores dedicados: ctgpgpu1 y ctgpgpu2.

El primero es un Supermicro X8DTG-D con 2 procesadores de 4 cores ,10 GB de RAM y 2 slots PCIe x16 Gen 2.0 con dos tarjetas gráficas: una NVidia Tesla S2050 [GF100] en PCIe y una Matrox MGA G200eW WPCM450 integrada.

El segundo es un Dell Precision Workstation R5400 con 2 procesadores de 4 cores, 8 GB de RAM y 2 slots PCIe x16 Gen 1.0 con una GeForce 8500 GT [G86] y una GTX 680  (GK104).

Aunque ambos servidores siguen funcionando bien y las tarjetas se renuevan con cierta frecuencia, el problema que tienen es que el bus PCIe de sus placas base es antiguo y empieza a ser un cuello de botella. En el caso de ctgpgpu2 es de primera generación (PCIe v1.0) y proporciona un máximo teórico de 4 GB/s (en slot 16x). En el caso de ctgpgpu1 es segunda generación (PCIe v2.0) y el máximo teórico es de 8 GB/s.

La tercera generación de PCIe (v3.0) se hizo pública en noviembre de 2011 y la cuarta generación (v4.0) se espera que salga en 2014 o 2015. Proporcionan máximos teóricos de 16 y 32 GB/s respectivamente. La razón por la que la adopción de la v3.0 está siendo lenta es porque para las tarjetas de consumo el ancho de banda proporcionado por la v2.0 aún es suficiente y el hardware resulta más barato.

Otros factores muy relacionados entre sí a tener en cuenta son el consumo y el calor. A medida que las GPU aumentan su nivel de integración y se hacen más potentes cada vez consumen más electricidad y en consecuencia generan más calor. Esto hace que los disipadores/ventiladores cada vez sean más grandes y las tarjetas ocupen más. Si el tamaño puede ser un problema en un equipo de escritorio, lo es aún más cuando hablamos de servidores en formato rack que tienen que ocupar el menor espacio posible.

Todos estos factores hacen que la oferta de servidores para GPU computing sea bastante limitada, y en general poco flexible. Es por eso que empezamos a buscar alguna solución que se saliera un poco de lo habitual y encontramos el concepto de “caja externa para GPU”.

La idea es tener las tarjetas gráficas en una caja externa e independiente, con su propia alimentación y conectada al bus PCIe del servidor que se quiera mediante un conector de tipo External PCI Express. Al estar en su propia caja es más fácil ventilarlas ya que no hay más componentes produciendo calor, tienen alimentación dedicada y lo más importante, no tienen que compartir el espacio de la caja con nada más.

Por ejemplo, de este tipo de solución Dell tiene el PowerEdge c410x, con espacio para un total de 16 tarjetas de modo que se pueden conectar 4 servidores con hasta 4 tarjetas cada uno.

c410xSin embargo el tamaño reservado para cada tarjeta es bastante limitado, y como es un producto un tanto antiguo todavía usa PCIe v2.0.

La oferta entre los fabricantes más importantes para este tipo de productos es muy escasa o nula, así que buscamos entre fabricantes no tan conocidos y encontramos el Netstor NA255A, una caja externa con PCIe v3.0 y espacio suficiente para 4 tarjetas grandes. Además hay una review del producto en Tom’s Hardware en la que sale muy bien parada. (Para los que no lo sepan, Tom’s Hardware es una de las páginas de reviews y benchmarking de hardware más antiguas y con mejor reputación de internet).

Turbobox-interior

Y encima hay una versión de la caja en formato enrackable con fuentes de alimentación redundantes, la NA265A.

na265Cualquiera de estos dos modelos se conecta al slot PCIe v3.0 de un ordenador mediante una tarjeta y un par de cables External  PCIe que vienen incluidos, de forma que lo que el usuario ve es que el ordenador tiene hasta cuatro tarjetas gráficas como si las tuviera directamente conectadas en la placa base.

La pega es que al ser un producto de un fabricante pequeño su distribución es “pobre” por decirlo suavemente y puede resultar complicado conseguirlo, pero lo estamos intentando.

Una duda que nos surgió a la hora de pensar en preparar este setup es ¿cual es el número máximo de GPU que admite un único ordenador?

Evidentemente está el número de slots PCIe disponibles para enchufarlas, el espacio físico donde colocarlas, una fuente de alimentación lo bastante potente como para hacerlas funcionar y la refrigeración necesaria, pero si solucionas todos esos inconvenientes, ¿cuantas GPUS como mucho puedes hacer funcionar en un PC?

Buscando información sobre esta cuestión descubrimos un proyecto del Vision Lab de la Universidad de Antwerp llamado Fastra II. En este proyecto montaron un PC con 13 GPUS tras conseguir una BIOS modificada del fabricante de la placa y hacer un parche para kernel. El problema reside en que las BIOS son de 32 bits y por lo tanto solo direccionan memoria por debajo de los 4 GB. Cada GPU requiere mapear unos 300 MB de memoria para inicializarse, y el resto del sistema también tiene sus requisitos. Esto hace que en la práctica un sistema no arranque con más de 8 o 9 GPUS. Este límite probablemente desaparecerá con los arranques de tipo UEFI.

Una vez solucionado el problema de la bios está el tema de los límites que te pueda imponer la combinación de controlador/sistema operativo, pero eso ya es un problema particular de cada fabricante y desarrollador.

Cuando las cosas van mal

El pasado miércoles programamos una parada de mantenimiento y como dice el título, las cosas fueron mal hasta el punto en que todavía estamos recuperándonos de un pequeño desastre.

Habíamos planeado dos cambios. El primero, migrar un único disco bastante crítico a un RAID-1. Aunque el proceso fue algo más lento de lo esperado, pudimos completarlo sin complicaciones demasiado serias. Tuvimos que hacer cosas que no estaban planeadas, pero supimos resolver los problemas bastante bien.

El segundo cambio consistía en actualizar CloudStack 2.2.13 a 2.2.14, que precisamente tenía máquinas virtuales funcionando en ese disco que migramos, por lo que ya empezamos con algo de retraso.

La actualización no era un capricho (estaríamos migrando ya a CloudStack 4.1 gustosamente), sino que era necesaria para poder realizar copias de seguridad de las máquinas virtuales sin necesidad de detenerlas. Este cloud aloja máquinas virtuales con servicios que ofrecemos en el centro, como la página web o la mensajería, y aunque se realizan copias de seguridad de los datos, que se pudiesen realizar también copias de seguridad de las máquinas virtuales sin necesidad de detenerlas sería un puntazo.

El desastre

Salió mal. Y cuando algo sale mal, seguimos la siguiente línea lógica de acciones:

  • Intentar identificar rápidamente el problema para intentar solucionarlo, repasando todo el proceso concienzudamente.
  • Si se ha seguido el proceso concienzudamente y no se puede identificar el problema, volver atrás.

Tuvimos que volver atrás, pero nos topamos con que el problema persistía. Todo apuntaba a que no habíamos planificado bien la vuelta atrás, que se nos escapaba algo. Es algo sobre lo que todavía tendremos que reflexionar, pero mientras tanto seguimos el siguiente paso:

  • Dedicar más tiempo a intentar identificar y comprender el problema, para poder evitarlo si es posible y documentarlo adecuadamente para que no moleste en el futuro.

Ese proceso duró casi tres días, hasta el punto en que ahora ya hemos verificado que, efectivamente, somos capaces de reproducir el problema. Lo estamos documentando y por suerte podremos convivir con él.

El mayor desafío ha sido tener que experimentar con esta infraestructura en producción, pensando en todo momento en mantenerla funcionando. Cuando todos los servicios dependen de ella, tienes que andar con pies de plomo. Hubo varias pequeñas caídas el viernes por la mañana por culpa de pequeños fallos haciendo estas pruebas, debido al cansancio acumulado.

El problema en detalle

CloudStack se actualizó aparentemente sin mayor problema, pero después de un rato nos dimos cuenta de que algunas máquinas virtuales no funcionaban, entre ellas la del servidor web principal.

Identificamos las máquinas e intentamos buscar puntos en común. El más evidente, todas las máquinas afectadas utilizaban más de dos discos duros.

Comenzamos a realizar pruebas con ello en mente y sacamos conclusiones precipitadas. Durante el día de ayer pensábamos que el problema era otro y menuda sorpresa que nos llevamos esta mañana cuando nos dimos cuenta de que no era así. Hoy por fin hemos sido capaces de reproducir el problema de forma controlada y podemos decir con toda certeza que lo hemos identificado.

El problema surge cuando una máquina virtual tiene dos o más discos duros. Si los discos no se insertan en esa máquina en el mismo orden en el que se crearon, se produce el problema. Es decir, si tenemos discos con identificadores 11, 14, 18, deben introducirse siempre por ese orden.

El agente de CloudStack suelta un NullPointerException y no da mayor información en caso de error, la máquina no llega a arrancar. El por qué se disparó este problema con la actualización sigue siendo un misterio. No hemos seguido investigando el motivo por ahora.

Dado que CloudStack 2.2 ya no se mantiene (por a la migración a Apache), intentaremos reproducir el problema también en CloudStack 4.1 para reportar el problema debidamente, si fuera necesario.

Ahora mismo el cloud está vivo, funciona y se comporta bien. El único problema es que en el proceso nos hemos quedado con un único host donde poder ejecutar las máquinas virtuales, por lo que todavía estaremos unos días con algunos servicios menores caídos mientras reinstalamos el resto. Todos los servicios de uso común funcionan, al menos.

Nota: Nos tomaremos un descanso del blog durante el mes de agosto y volveremos en septiembre. ¡Felices vacaciones, el que las tenga!