Descarga la aplicación para disfrutar aún más
Vista previa del material en texto
Proyecto Fin de Grado Grado en Ingeniería de las Tecnologías de Telecomunicación Big Data, Hadoop y DataMining sobre eventos de seguridad Autor: Sergio Losada Rodríguez Tutor: Pablo Nebrera Herrera Departamento de Ingeniería Telemática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2014 Proyecto Fin de Grado Grado en Ingeniería de las Tecnologías de Telecomunicación Big Data, Hadoop y DataMining sobre eventos de seguridad Autor: Sergio Losada Rodríguez Tutor: Pablo Nebrera Herrera Profesor asociado Departamento de Ingeniería Telemática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2014 Proyecto Fin de Grado: Big Data, Hadoop y DataMining sobre eventos de seguridad Autor: Sergio Losada Rodríguez Tutor: Pablo Nebrera Herrera El tribunal nombrado para juzgar el Proyecto arriba indicado, compuesto por los siguientes miembros: Presidente: Vocales: Secretario: Acuerdan otorgarle la calificación de: Sevilla, 2014 El Secretario del Tribunal A mi familia A mis amigos A mis profesores i Agradecimientos Este proyecto marca el final de una de las etapas más intensas e inolvidables de mi vida como es la Universidad, pero el comienzo de todo un mundo de posibilidades, caminos y objetivos. Quiero agradecer haber podido llegar hasta aquí a cada uno de los miembros de mi familia, a los que están y los que estuvieron. Sobre todo a mis padres por el esfuerzo que realizan día a día para que yo haya podido tener la oportunidad de realizar estos estudios, ¡muchísimas gracias a los dos! Sin olvidarme de esos pequeños corazones que tengo como primas que solo pueden transmitir alegría y felicidad. Tampoco olvidaré todos los buenos ratos y estudios con “BLAAAS MIT”, ellos han sido los culpables de que estos cuatro años hayan sido una aventura que hemos podido vivir juntos. Agradecer también a Kannan Kalidasan por ayudarme en mis primeros pasos con Hadoop y siempre estar disponible para solucionar algún problema, y a cada persona que voluntaria o involuntariamente ha puesto un grano de arena en este proyecto. Por último, dar las gracias a mi tutor Pablo Nebrera y a la empresa ENEO Tecnología por permitirme realizar este proyecto con ellos, ser parte del equipo, y hacer que mi primera experiencia en una empresa sea inolvidable. iii Resumen Este proyecto realiza una inmersión en el tema de Big Data. Su objetivo es el almacenamiento de grandes cantidades de eventos de seguridad utilizando para ello una base de datos distribuida, para que posteriormente dicha información pueda ser filtrada y extraida realizando consultas a la misma. El estudio se centrará en la configuración e implantación de la arquitectura Big Data al proyecto redBorder Horama, y posteriormente, se realizará un estudio estadístico (DataMining) sobre los datos que sean consultados, en búsqueda de anomalías, agrupamientos o clasificaciones. Para ello se han utilizado distintas herramientas de Apache, como pueden ser Hadoop, para la base de datos; Ambari, encargada de instalaciones y monitorización; Pig, para las consultas a Hadoop; Kafka, para el sistema de mensajería y otras no pertenecientes a Apache como Snort, para la captura de los eventos o la librería WEKA, para el uso de funciones estadísticas en la parte del análisis y procesamiento de los datos. El proyecto ha sido una introducción al mundo de BigData, a los problemas que están resueltos y a todos aquellos que aún quedan por resolver, las distintas herramientas existentes y cómo cooperan entre ellas para resolver dichos problemas ante tales cantidades de eventos. Y, sobre todo, la importancia del análisis de datos en la actualidad con herramientas o funciones estadísticas para obtener una mejor comprensión de los mismos, útiles para empresas en cuestión de rendimiento, seguridad o marketing. v Abstract The overall objective of this project is to collect and store massive volume of security event logs in distributed system. Later the required information are retrieved by processing the data and filtered by consulting the database. Also this study will focus on configuration and integration of Big Data architecture into redBorder Horama platform. Finally statistical study of the data will be done by using Data Mining techniques like outlier detection, clustering or classifications. Highly scalable and most popular Big Data stacks are used for different purpose to achieve the project's goal. Hadoop as Distributed processing Software . On top of Hadoop layer, there are various integrated processing systems like Pig as consulting agent with database, Kafka used as messaging system , Snort as detection system of network intrusion. For data analysis and statistical modeling , Weka Libraries are used. This project leveraged and integrated the Big Data technologies with current system to solve the problems and provide real time solutions in network events based processing. Additionally, through data analytics functionalities , it helps to get better data insights about the events, which benefits the companies to find the hidden business opportunities in terms of performance, security and marketing. vii Índice Agradecimientos i Resumen iii Abstract v Índice vii Índice de Tablas ix Índice de Figuras xi 1 Introducción 1 1.1 Motivación 1 1.2 Objetivos 1 1.3 Metodología 1 2 Arquitectura 3 2.1 ZooKeeper 3 2.2 Apache Kafka 4 2.2.1 Introducción 4 2.2.2 Arquitectura y funcionamiento 4 2.3 Snort 7 2.3.1 Introducción 7 2.3.2 Arquitectura y funcionamiento 7 2.3.3 Alternativas 9 2.3.4 Uso en el proyecto 10 2.4 Camus 10 3 Hadoop 13 3.1 Introducción 13 3.2 HDFS 14 3.2.1 Diseño 14 3.2.2 Demonios 14 3.2.3 Leer y escribir datos 16 3.2.4 Alta disponibilidad 17 3.2.5 Herramientas de línea de comandos 19 3.3 MapReduce & YARN 20 3.3.1 Introducción 20 3.3.2 Fases MapReduce 20 3.3.3 Arquitectura y demonios 22 3.4 Puesta en marcha 23 3.4.1 Instalación 23 3.4.2 Configuración 24 3.4.3 Arranque 27 3.5 Hadoop Single Node & Hadoop Clúster 28 3.5.1 Single Node 28 3.5.2 Clúster mode 33 3.6 Mantenimiento del clúster 35 3.6.1 Añadir o dar de baja un DataNode 35 3.6.2 Comprobar la salud e integridad del Sistema de ficheros 35 3.6.3 Balanceo de bloques de datos en HDFS 36 3.7 Monitorización -‐ Ambari 37 3.8 Backup and Recovery 41 4 Pig 43 4.1 Introducción 43 4.2 Filosofía de PIG 43 4.3 Latin Pig 44 4.3.1 Alternativas 44 4.4 Objetivos e implementación 44 4.4.1 Script en Ruby 46 4.4.2 Ejecución 47 5 DataMining 49 5.1 Introducción DataMining 49 5.2 Objetivos 50 5.3 Clasificación 52 5.4 Clústerización 60 5.5 Outlier Detection 62 6 Presupuesto 63 7 Conclusiones 64 7.1 Conclusiones 64 7.2 Mejoras y líneas futuras 64 Referencias 67 AnexoA : Configuración de Hadoop 70 Anexo B : Script de Ruby 82 Anexo C : DataMining Code (Java) 86 Índice de Conceptos 111 ix ÍNDICE DE TABLAS Tabla 1: HDFS Daemons 14 Tabla 2: core-site.xml 24 Tabla 3: hdfs-site.xml 24 Tabla 4: mapred-site.xml 25 Tabla 5: yarn-site.xml 25 Tabla 6: Algoritmos de clasificación 52 Tabla 7: Algoritmos de agrupamiento 60 xi ÍNDICE DE FIGURAS Figura 1: Arquitectura del clúster ZooKeeper 3 Figura 2: Unión datos en un clúster Kafka 5 Figura 3: Topic Partition, Apache Kafka 5 Figura 4: Producers, brokers & consumers 7 Figura 5: Flujo de datos del decodificador 8 Figura 6: Arquitectura Snort 8 Figura 7: Snort, unified2 & Barnyard2 10 Figura 8: Arquitectura de los directorios de Hadoop 11 Figura 9: Paso de eventos: Kafka - Camus - HDFS 12 Figura 10: NameNode, SecondaryNN y DataNode 15 Figura 11: HDFS read path 16 Figura 12: HDFS write path 17 Figura 13: MetaData checkpoint process 18 Figura 14: HA NameNode 18 Figura 15: MapReduce process 21 Figura 16: Ejemplo MapReduce 22 Figura 17: YARN arquitecture 23 Figura 18: directorios dentro de Hadoop 24 Figura 19: Single node running 28 Figura 20: Interfaz Web NameNode (1) 29 Figura 21: Interfaz Web NameNode (2) 29 Figura 22: ficheros image y edits 30 Figura 23: (NameNode) Página DataNodes 30 Figura 24: (NameNode) Página de Snapshots 31 Figura 25: (NameNode) Proceso de arranque 31 Figura 26: (NameNode) Página de utilidades 31 Figura 27: (NameNode) Browse Directory 32 Figura 28: (NameNode) Logs 32 Figura 29: Información del DataNode 32 Figura 30: Interfaz web del ResourceManager 33 Figura 31: Interfaz web del JobHistory 33 Figura 32: Nodos en el clúster 34 Figura 33: Incremento de DataNodes 34 Figura 34: Incremento de NodeManagers 34 Figura 35: (Ambari) Opciones de instalación 38 Figura 36: (Ambari) Proceso de instalación de los nodos 1 38 Figura 37: (Ambari) Proceso de instalación de los nodos 2 39 Figura 38: Selección de demonios para cada nodo 39 Figura 39: Añadir propiedades 40 Figura 40: Resumen de la instalación 40 Figura 41: Proceso de instalación de demonios 40 Figura 42: Monitorización mediante Ambari 41 Figura 43: Datos, información y conocimiento 50 Figura 44: Formato JSON de los eventos 54 Figura 45: UI DataMining 54 Figura 46: Algoritmos de clasificación 54 Figura 47: Directorio de resultados de clasificación 55 Figura 48: J48 tree 56 Figura 49: Resumen de los resultados del J48 57 Figura 50: Todos los resultados de algoritmos de clasificación 57 Figura 51: resultado del análisis de clasificación 59 Figura 52: Mejores métodos de clasificación 58 Figura 53: Opciones de agrupamiento 59 Figura 54: Resultados agrupamiento (1 atributo) 61 Figura 55: Mejores resultados de agrupamiento 60 Figura 56: Partes de los mejores métodos por separado que después se sumarán 61 Figura 57: Mejores agrupadores para el DataSet completo 60 Figura 58: Resultado del análisis de detección de anomalías 62 Figura 59: Resumen del análisis de detección de anomalías 61 xiii 1 1 INTRODUCCIÓN 1.1 Motivación Desde hace unos años la cantidad de datos que se están generando ha incrementado exponencialmente, prediciéndose que el tráfico fluyendo a través de internet en 2014 alcanzará aproximadamente los 667 exabytes (106 TB). Gran parte de esa enorme cantidad de datos termina almacenándose en discos duros de hogares, bases de datos de empresas, etc. Este hecho dificulta el proceso de almacenamiento y procesamiento de los mismos. Por ejemplo Facebook debe procesar 300 millones de fotos al día y 2.7 billones de Likes lo que hace aproximadamente un total de 105 TB cada media hora. Aprovechando que el hardware también está mejorando sus prestaciones (procesadores, memorias…) hacen falta algoritmos y software que lo acompañen para ser capaz de procesar tales cantidades de información. Es lo que se conoce en la actualidad con el término Big Data. En este proyecto se aplicará dicho software y algoritmos a eventos de seguridad recibidos en una red, recogidos por un IPS, y se incorporarán al proyecto redBorder Horama, donde deberán trabajar conjuntamente con el resto de servicios del mismo. 1.2 Objetivos En primer lugar, el propósito general de este proyecto se puede dividir en tres partes: Almacenamiento, consultas y procesamiento de los datos. Debe abarcar desde que cientos, miles o millones de eventos que capture el IPS sean almacenados en una base de datos capaz de trabajar con tales cantidades de información. Que toda esa información se pueda extraer posteriormente de forma fácil y filtrándola según las necesidades del usuario como cualquier consulta a una base de datos. Y por último, ser capaz de procesar esos datos con una serie de algoritmos que muestren que información esconden miles o millones de eventos. 1.3 Metodología Antes de comenzar con el proyecto, el primer capítulo mostrarán los pilares sobre los que se sostiene el mismo, de dónde provienen esos datos, cómo han sido recogidos, y cómo se van encaminando hasta el corazón del proyecto, que será la base de datos distribuida Apache Hadoop (Capítulo 3). En Apache Hadoop será donde se almacenen todos los eventos de forma estructurada y distribuida en distintos nodos. Se abarcarán todos los posibles campos que implica trabajar con esta base de datos, como pueden ser Vacía el bolsillo en tu mente, y tu mente llenará el bolsillo - Benjamin Franklin - Introducción 2 instalación (tanto manualmente como a través de un wizard), escritura, lectura, distribución, copias de seguridad, monitorización… Una vez todos esos datos se encuentran correctamente almacenados se abarcará el proceso de extracción de los mismos, que se podrá ver en el Capítulo 4, en el que se utilizará una herramienta también de Apache que trabaja conjuntamentecon Hadoop denominada Pig. En el Capítulo 5 se mostrarán los distintos algoritmos y cómo se han implementado para procesar la información que se ha estado almacenando. Y por supuesto la utilidad de cada uno y que tipo de conocimiento aportan. Finalmente en el último Capítulo se mostrarán las conclusiones del proyecto y las futuras líneas de mejora para el mismo. 3 2 ARQUITECTURA ste capítulo se centrará en todos los componentes de la arquitectura del proyecto que son necesarios comprender para el posterior entendimiento del resto de los componentes fundamentales, como Hadoop o Pig. Las herramientas que se detallan a continuación, como ZooKeeper, Kafka, Snort o Camus son los pilares sobre los que se sostiene el proyecto. La buena configuración y que realicen correctamente las funciones que les corresponde es fundamental para conseguir trabajar con Hadoop (Capítulo 3). Se comenzará viendo una introducción a cada uno, las partes fundamentales del mismo y que funcionalidad cumple en este proyecto. 2.1 ZooKeeper ZooKeeper es un servicio de coordinación de alto rendimiento para aplicaciones distribuidas que permite mantener conexiones estables entre servidores con distintas tecnologías. Pertenece a Apache Software Foundation, aunque es un subproyecto de Hadoop. Provee un servicio de configuración centralizada y registro de nombres de código abierto para grandes Sistemas Distribuidosi, sincronización… todo ello en una interfaz simple. Empezó como parte de Hadoop pero el interés despertado y su uso general hizo que pasara a ser promovido por Apache Top Level Project. La arquitectura de ZooKeeper soporta alta disponibilidadii a través de servicios redundantes. Existen maestros y clientes. Se puede tener más de un maestro dando la opción a los clientes de acceder a la información en cualquiera de los mismos, aunque solo uno (leader) puede escribir en disco para guardar la información, como puede apreciarse en la Figura 1. Los nodos ZooKeeper guardan sus datos en un espacio de nombres jerárquico como hace un sistema de archivos. Los clientes pueden leer y escribir desde/a los nodos y de esta forma tienen un servicio de configuración compartido. Figura 1: Arquitectura del clúster ZooKeeper E Arquitectura 4 El motivo de esta breve introducción a ZooKeeper es porque se usa en bastantes sistemas distribuidos como Apache Kafka y Apache Hadoop, dos de los pilares de este proyecto. Hadoop ha incorporado ZooKeeper en su funcionamiento a partir de la versión 2.X (las cuales se verán en este proyecto). Hadoop eligió aprovechar la gestión de clústers de ZooKeeper para agrupar capacidades en vez de desarrollar la suya propia, por lo que en resumen, ZooKeeper proporciona servicios operacionales a los clústers de Hadoop. 2.2 Apache Kafka 2.2.1 Introducción Apache Kafka es un sistema de mensajería Publish-Suscribe distribuido y es capaz de ofrecer un alto rendimiento. En este proyecto se usa ya que es el lugar por el que Hadoop consigue toda la información con la que trabajará. Está diseñado con los siguientes objetivos: • Mensajería persistente que proporciona un rendimiento constante en el tiempo. • Alto rendimiento: Incluso con hardware modesto, un único broker puede manejar cientos de megabytes de lectura y escritura por segundo desde miles de clientes. • Soporte para la partición de mensajes a través de los servidores de Kafka y consumo distribuido en un clúster de máquinas consumidoras, manteniendo la ordenación por partición. • Soporte para la carga de datos en paralelo en Hadoop. • Distribuido: Los mensajes se conservan en el disco y se replican dentro del clúster para evitar la pérdida de datos. Cada broker puede manejar terabytes de mensajes sin impacto en el rendimiento. Kafka proporciona un mecanismo de carga paralela en Hadoop, así como la capacidad de partición en tiempo real del consumo en un clúster. 2.2.2 Arquitectura y funcionamiento La arquitectura de Kafka no pretende que un único clúster gestione varios data centers, sino ser capaz de soportar una topología multidatacenter. Esto permite una sincronización entre los clúster de forma sencilla, es decir, conseguir que un solo grupo pueda unir datos de muchos centros de datos en un solo lugar (Figura 2): 5 Big Data, Hadoop y DataMining sobre eventos de seguridad Figura 2: Unión datos en un clúster Kafka Utiliza ZooKeeper para el descubrimiento de nodos y sincronizar todo el clúster. Como se puede apreciar en la Figura anterior, se pueden distinguir distintos tipos de componentes además de otros que se explican a continuación: Ø Topic y Logs: Un topic es una categoría donde los mensajes son publicados. Para cada topic, el clúster de Kafka mantiene un log particionado como se puede apreciar en la Figura 3. Figura 3: Topic Partition, Apache Kafka Arquitectura 6 Cada partición es una secuencia ordenada e inmutable que se va indexando continuamente en un log. Los mensajes en las particiones tienen asignados cada uno un identificador denominado offset que identifica a los mensajes dentro de la partición. Este offset es controlado por el consumidor que irá avanzando su posición a medida que vaya leyendo los mensajes. De esta forma el consumidor puede mover el offset a su gusto y elegir el orden en el que desea leer los mensajes pudiendo, por ejemplo, resetear el offset si necesita reprocesar los datos. El clúster Kafka almacena todos los mensajes publicados – tanto si han sido consumidos o no – por un tiempo limitado y configurable. Tras ese tiempo los mensajes serán borrados liberando así la memoria que ocupaban. Además como se mencionó en las características de Kafka vistas anteriorment, el rendimiento es constante con respecto al tamaño de los datos, por lo que retener grandes cantidades de datos no es un problema. Es necesario señalar también que las particiones tienen muchos objetivos. El primero de ellos es permitir al registro escalar más allá de un tamaño que quepa en un único servidor. Cada partición individual debe ajustarse al servidor donde se aloja, pero un topic debe tener muchas particiones, por lo que, puede manejar cantidades arbitrarias de datos. El segundo de los objetivos es actuar como una unidad de paralelismo en un momento determinado. Las particiones de los logs son distribuidas sobre los servidores que conforman el clúster Kafka, con cada servidor manejando datos y peticiones por parte de las particiones. Cada partición es replicada a lo largo de un número configurable de servidores para poder ser tolerante a fallos. Además, cada partición tiene un servidor que actúa como leader, y uno o más servidores que actúan como followers. El líder se encarga de leer y escribir todas las peticiones para la partición mientras que los followers replican la información del líder de forma pasiva. De esta forma conseguimos tolerancia a fallos ya que si el líder falla, automáticamente un follower pasará a ser el nuevo líder. Ø Productores: Publican los mensajes a un determinado topic, es el responsable de elegir que mensaje asignar a cada partición dentro del topic. Este balanceo puede realizarse mediante un balanceo round-robin. Ø Consumidores: Kafka proporciona a los consumidores una abstracción que engloba los modelos de mensajería queuing y publish-subscribe, y se denomina el consumer group. Los consumidores se etiquetan con el nombre de un consumer group, y cada mensaje publicado en un topic se entrega a la instacia de un consumidor dentro de su consumer group. Dichas instancias pueden estar separadas en distintos procesos o máquinas. Si todas lasinstancias del consumidor pertenecen al mismo consumer group, entonces la cola trabaja como una cola que balancea carga a través de los consumidores. En cambio, si las instancias de los consumidores pertenecen a distintos grupos, la cola trabajará de la forma publish- subscribe y todos los mensajes serán transmitidos a todos los consumidores. De todas formas, para conseguir escalabilidad y alta disponibilidad cada grupo consta de múltiples instancias de consumidor. Como se dijo al explicar ZooKeeper, éste es usado por Apache Kafka, los consumidores lo usan para mantener la referencia del offset por el que van leyendo. Por ejemplo, como se puede apreciar en la Figura 4, disponemos de tres productores, dos brokers y dos consumidores, el primero con tres instancias y el segundo con dos instancias. 7 Big Data, Hadoop y DataMining sobre eventos de seguridad 2.3 Snort 2.3.1 Introducción Snort trabaja en un importante campo en el mundo de la seguirdad de la red, es multiplataforma y una herramienta ligera de detección de intrusiones de red que puede usarse para vigilar redes TCP/IP y detectar una amplia variedad de tráfico de red sospechoso, así como ataques. Snort también puede ser desplegado rápidamente para llenar agujeros portenciales en la cobertura de la seguridad de una red, como por ejemplo, cuando un nuevo ataque surge y los proveedores de seguridad comerciales son lentos para liberar nuevas firmas de reconocimiento a dicho ataque. Por tanto puede decirse que Snort es un sniffer y logger de paquetes basado en libpcapiii, que puede utilizarse como un sistema de detección de intrusos en una red (NIDS). Cuenta con normas utilizadas para realizar patrones de coincidencia de contenidos y detectar distintos tipos de ataques, tales como desbordamiento del buffer, escaneo de puertos, ataques CGIiv y muchos más. Snort tiene la capacidad de dar la alerta en tiempo real, con alertas que son enviadas a syslogv. Su motor de detección se programa usando un lenguaje simple que describe la pareja <tests de paquete, acción a realizar>. Su facilidad de uso simplifica y acelera el desarrollo de nuevas reglas de detección (llegando a obtener reglas de exploits en cuestión de horas). 2.3.2 Arquitectura y funcionamiento La arquitectura de Snort se centra en el rendimiento, simplicidad y flexibilidad. Los elementos que componen el esquema de su arquitectura (Figura 6) son los siguientes: • Módulo de captura del tráfico. Es el encargado de capturar todos los paquetes de la red utilizando la librería libpcap. • Decodificador. Se encarga de formar las estructuras de datos con los paquetes capturados e identificar Figura 4: Producers, brokers and consumers Arquitectura 8 los protocolos del enlace, de red, etc. Puede apreciarse en la Figura 5. • Preprocesadores. Permiten extender las funcionalidades preparando los datos para la detección. Existen diferentes tipos de preprocesadores dependiendo del tráfico que se quiera analizar. • Motor de detección. Analiza los paquetes en base a las reglas definidas para detectar los ataques. • Archivo de reglas. Definen el conjunto de reglas que regirán el análisis de los paquetes detectados. • Plugins de detección. Partes del software que son compilados con Snort y se usan para modificar el motor de detección. • Plugins de salida. Permiten definir qué, cómo y dónde se guardan las alertas y los correspondientes paquetes de red que las generaron. Pueden ser archivos de texto, bases de datos, servidor syslog, etc. Figura 5: Flujo de datos del decodificador Figura 6: Arquitectura Snort 9 Big Data, Hadoop y DataMining sobre eventos de seguridad 2.3.3 Alternativas Snort no es la única solución disponible en el mercado para los mismos fines. A continuación se verán algunos de los rivales que pueden encontrarse, con sus respectivas ventajas e inconvenientes. 2.3.3.1 tcpdump Snort es bastante similar a tcpdumpvi pero se centra más en aplicaciones de seguridad de rastreo de paquetes. La mayor de las características que Snort tiene, mientras que tcpdump no, es la inspección del paylaodvii. Snort decodifica la capa de aplicación de un paquete y aplica reglas que recogen el tráfico que tiene datos específicos contenidos dentro de dicha capa. Esto permite a Snort detectar muchos tipos de actividades hostiles contenidas en la carga útil del paquete. Otra ventaja es que la pantalla de salida decodificada de Snort es algo más fácil de usar que la salida de tcpdump. Snort se centra en la recogida de los paquetes tan pronto como sea posible y procesarlos en su motor de detección. Una de las características más importante que ambos comparten es la capacidad de filtrar el tráfico con comandos Berkeley Packet Filter (BPFviii). Esto permite que el tráfico sea recogido basándose en una variedad de campos específicos. Por ejemplo, mediante comandos BPF ambas herramientas pueden ser instruidas para procesar el tráfico TCP solamente. Mientras que tcpdump recogería todo el tráfico TCP, Snort puede utilizar sus reglas flexibles para realizar funciones adicionales, como buscar y guardar sólo aquellos paquetes que tienen en su campo TCP un determinado contenido o que contienen peticiones web que asciendan hasta una vulnerabildiad CGI. 2.3.3.2 NFR NFR es un IDS que da a los usuarios una herramienta de gran alcance para luchar contra el acceso ilegal a una red. Con la flexibilidad que aporta, el administrador de red puede saber un poco mejor acerca de quién tiene acceso a su red o qué tipo de tráfico generan sus empleados. Snort comparte algunos de los conceptos funcionales con NFR, pero NFR es una herramienta de análisis de red más flexible y completa. Consecuentemente implica más complejidad, por ejemplo, escribir una regla de Snort para detectar un nuevo ataque toma solo unos minutos una vez que se ha encontrado la firma del ataque, mientras que realizar lo mismo en NFR conlleva más tiempo, y en temas de seguridad la velocidad con la que frenar los ataques puede ser crucial. 2.3.3.3 Suricata Durante años, Snort ha sido el estándar para la detección en código abierto de sistemas de intrusión y prevención (IDS/IPS). Su motor combina los beneficios de las firmas, los protocolos y la inspección basada en anomalías y se ha convertido en una de las mayores implementaciones de IDS/IPS en el mundo. Suricata va por el mismo camino aunque se encuentra menos extendido. Fundado por la Open Information Security Foundation (OISF), también se basa en firmas pero integra algunas técnicas revolucionarias. Su motor de detección incorpora un normalizador y analizador http que proporciona un procesamiento muy avanzado de secuencias http, lo que permite la comprensión de tráfico en el séptimo nivel del modelo OSI. En pruebas de rendimiento realizadas por expertos se puede comprobar que aún hoy día Snort es más preciso y efectivo que Suricata aunque la evolución de este último esta convirtiéndole en un digno rival de Snort. Arquitectura 10 2.3.4 Uso en el proyecto En el proyecto Snort está configurado para que escriba en un fichero binario llamado “unified2”. Unified2 es un formato de eventos IDS, que procesos como Barnyard2 los parsean a otros formatos conocidos como los usados por Snort, MySQL, syslog… En entornos en los que Snort tiene que procesar una gran cantidad de tráfico es muy posible que su rendimiento se vea afectado y termine descartando paquetes. Esto se debe a que Snort no procesa el siguiente paquete hasta que no termina de escribir la alerta en la base de datos. Este proceso de escritura es lento si hablamos de que por cada alerta es necesaria una conexión TCP y un insert en la base de datos. La solución adoptada es configurar Snort para que escriba las alertas enun fichero local en lugar de hacerlo directamente en la base de datos. Al ser un fichero binario se almacenarán las alertas más rápidamente de lo que lo que se hacía antes. El formato, como ya se ha dicho anteriormente, es unified2. Pero ahora se tienen todas las alertas en un fichero local, por lo que, es necesario escribirlas en la base de datos. Para eso mismo se usa Barnyard2, un intérprete open Source. En este caso escribirá en la cola Kafka. Se hace de esta forma para desacoplar el envío de eventos con el procesamiento de paquetes de Snort. Así Snort escribirá lo más rápido que pueda y los eventos podrán ir enviándose poco a poco vaciando así la cola. De esta manera, Snort hace lo que tiene que hacer, es decir, procesar paquetes sin esperar a que Kafka esté caído o haya problemas de latencia de red. Toda la estructura puede observarse en la Figura 7. Figura 7: Snort, unified2 & Barnyard2 2.4 Camus Camus es una tubería entre la cola Kafka y HDFS (Hadoop Data File System). Sobre HDFS se hablará detalladamente en la parte de Hadoop, pero en resumen es el sistema de ficheros donde se quieren almacenar los eventos. Camus es una tarea MapReduce (Capítulo 3.3) que distribuye los datos que va obteniendo de la cola Kafka. Sus características son las siguientes: 11 Big Data, Hadoop y DataMining sobre eventos de seguridad • Descubrimiento de topics y particiones automático. • Busca los últimos offsets de los nodos de Kafka. • Usa Avroix por defecto, aunque se tiene la opción de utilizar otro Decoder. • Mueve los datos a los directorios HDFS según el timestamp. • Recuerda el último offset / topic. Es usado en LinkedIn donde procesa 10 billones de mensajes cada día, por lo que el rendimiento es muy bueno pese a que es un proyecto joven. Posteriormente en el apartado de HDFS (Capítulo 3.2) se detallarán los directorios que se van a crear y cómo va a organizarse la información, pero se puede adelantar que para la ejecución de Camus, utilizaremos Cron. Cron es un demonio que ejecuta comandos en unos intervalos determinados. En este proyecto se ha configurado Cron para que se ejecute de hora en hora, de manera que crea un árbol como el mostrado en la siguiente Figura, en la que los directorios se van ramificando hasta llegar a las horas, donde en su interior se encontrarán los eventos almacenados en formato .json.gz. Por ejemplo, listar el contenido de un directorio sería: hdfs dfs –ls /rb/raw/data/rb_event/2014/03/28/05 Figura 8: Arquitectura de los directorios en Hadoop Arquitectura 12 En la Figura 9 se puede apreciar un esquema de esta parte del camino que siguen los eventos. Cómo los eventos procedentes de Snort pasan por la cola Kafka, y camus los va recogiendo de hora en hora, e insertándolos en HDFS. Figura 9: Paso de eventos: Kafka - Camus - HDFS 13 3 HADOOP adoop es en la actualidad el software de código abierto más extendido en el mundo del Big Data que sirve para almacenar y analizar cantidades masivas de datos. En este capítulo se explotará este software desde distintos puntos de vista. Viendo sus partes, como se comunican entre ellas, su puesta en marcha, mantenimiento, monitorización, copias de seguridad y recuperación de las misma, etc. 3.1 Introducción En estos últimos años, ha habido una importante diferencia en el almacenamiento, manejo y procesamiento de los datos. Las compañías están almacenando más datos de más fuentes en más formatos con los que nunca antes habían trabajado. Con el análisis de esos datos se busca conocer más sobre lo que representan (ya pueden ser las personas, buscadores, logs, o cualquier cosa que sea relevante para una organización). El almacenamiento y procesamiento de esos datos no es un problema nuevo, el fraude en el comercio, detección de anomalías, análisis demográfico y muchas otras aplicaciones han tenido que tratar con estos problemas durante décadas. Apache Hadoop proporciona una infraestructura pragmática, rentable y escalable para construir muchos tipos de aplicaciones que resuelven diversos tipos de problemas de los que se ha hablado antes. Compuesto por un sistema de ficheros distribuido llamado Hadoop Distributed Filesystem y una capa de computación que implementa todo el procesamiento llamada MapReduce, Hadoop es un proyecto Open Source y un sistema capaz de procesar enormes cantidades de datos. Hadoop usa un clúster sin un hardware ni infraestructura de red en particular, funciona como una sola plataforma donde se desarrollan todos los procesos. La computación perteneciente a MapReduce está realizada en paralelo, para que proporcione a los desarrolladores un nivel de abstracción que les permita obviar temas de sincronización entre sus distintos nodos. El interés y la investigación que Hadoop ha levantado entre sus usuarios ha creado un ecosistema sobre este software, tanto de forma comercial como open Source. Algunos de los subproyectos que se han generado a raíz de Hadoop son: Hive, Pig, ZooKeeper o Ambari entre otros (algunos de ellos se verán en este proyecto). La primera de las características que identifican a este software es su sistema de ficheros de datos (HDFS) que se verá en el siguiente apartado. H 640 KBytes deben ser suficientes para cualquier persona. - Bill Gates - Hadoop 14 3.2 HDFS 3.2.1 Diseño HDFS sigue en muchos aspectos el diseño tradicional del sistema de archivos. Se almacenan como bloques y metadatos, y se guarda la localización de los mismos para después obtener los datos con un mapeo de los bloques que lo componen, estructura del árbol, permisos, etc. Muy similar a ext3, por ejemplo. HDFS es lo que se denomina un sistema de ficheros en espacio de usuario, que es una manera de decir que el sistema de ficheros se ejecuta fuera del Kernel. Esto nos proporciona simpleza, flexibilidad y posiblemente más seguro a la hora de ponerlo en práctica. Consecuentemente, no se monta HDFS como se realizaría con ext3 y requiere aplicaciones explícitamente para su uso. Otra de los puntos más fuertes de HDFS es que es un sistema de ficheros distribuido. Estos tipos de sistemas se usan para superar el límite que un disco duro individual o una máquina puede proporcionar. Cada máquina del clúster almacena un subconjunto de datos que componen el sistema de archivos completo con la idea de tener varias máquinas con distintos discos duros y así distribuir toda la información en ellos. Los metadatos se almacenan en un servidor centralizado actuando como un directorio de bloques y dotándolo de una visión global del estado del sistema de archivos. Otra diferencia con respecto al resto de sistemas de archivos es su tamaño de bloque. Es común que estos sistemas utilicen un tamaño de 4KB o 8KB para sus datos. Hadoop en cambio utiliza un tamaño de bloque significativamente mayor, 64MB por defecto, aunque los administradores de este tipo de clústers lo suelen elevar a 128MB o 256MB. El aumento del tamaño de los bloques provoca que los datos se escriban en trozos contiguos más grandes en el disco, que a su vez significa que se pueden escribir y leer en operaciones secuenciales más grandes. Esto minimiza las búsqueda de los bloques contiguos (es donde más tiempo se pierde), y mejora el rendimiento en operaciones de I/O. En lugar de recurrir a la protección de esos datos, HDFS replica cada bloque en varias máquinas del clúster (3 veces por defecto). Los cambios que se realizan en un bloque también se traspasan a sus réplicas, por lo que las aplicaciones pueden leer de cualquiera de los bloques disponibles. Tener multiples réplicas significa tener más fallos, pero serán más fácilmente tolerados. HDFS rastrea activamente y gestiona el número de réplicas disponibles de un bloque, de forma que si el número de copias de uno de estos bloques estápor debajo del factor de réplicas establecido, HDFS genera automáticamente una copia de las réplicas restantes. Los desarrolladores con sus aplicaciones no quieren preocuparse de copias, discos, metadatos… simplemente poder realizar operaciones I/O de la forma más fácil posible, por lo que HDFS presenta el sistema de ficheros como uno de alto-nivel con operaciones y conceptos familiares (POSIXx). 3.2.2 Demonios Hay tres tipos de demonios que conforman HDFS y cada uno tiene un papel distinto. Se puede ver en la siguiente tabla. Tabla 1: HDFS Daemons Demonio Número por clúster Función NameNode 1 Almacena el metadato del sistema de archivos, almacena los ficheros como un mapa de bloques, y proporciona una imagen global del sistema de archivos. Secondary NameNode 1 Actúa como un NameNode pasivo que almacena los checkpoints y logs del NameNode activo, además de realizar una serie de tareas que se detallarán 15 Big Data, Hadoop y DataMining sobre eventos de seguridad posteriormente. DataNode 1 o más Almacena los bloques de datos. Los bloques son más que trozos de un archivo. El DataNode (DN) es el responsable de almacenar y recuperar dichos datos, tiene acceso local directo a uno o más discos. En los sistemas de producción dichos discos son para uso exclusivo de Hadoop. El tamaño para almacenamiento puede ser añadido al clúster añadiendo más DataNodes. Como se ha dicho antes en vez de incorporar seguridad a los datos se aprovechan las réplicas por si se estropea algún DataNode tener los datos disponibles en otros. Esto además nos proporciona una mejora de rendimiento ya que si una aplicación requiere de esos datos y los bloques están siendo usados por otras aplicaciones, podrá utilizar las copias alojadas en otros DataNodes sin necesidad de esperar a que terminen el resto. Mientras que los DataNodes son los responsables de almacenar los bloques de datos, el NameNode (NN) es el demonio que guarda los metadatos del sistema de archivos y mantiene una imagen completa del mismo. Los clientes se conectan al NameNode para realizar operaciones con el sistema de ficheros, pero los bloques de datos se transmiten desde y hacia DataNodes directamente por lo que el ancho de banda no está limitado por un solo nodo. Los DataNodes informan regularmente de su estado al NameNode, de esta forma en un instante determinado el NameNode tiene una visión completa de todos los DataNodes del clúster, su salud, los bloques que tienen disponible, etc. Podemos ver la estructura de estos tres demonios en la figura 10. Figura 10: NameNode, SecondaryNN y DataNode Cuando un DataNode se inicia, así como a cada hora a partir de entonces, envía lo que se denomina un informe de bloques al NameNode, en el que lista todos los bloques que el DataNode tiene actualmente en sus discos y permite al NameNode realizar un seguimiento de los cambios que en ellos se produzcan. Esto permite también que ante un fallo en algún DataNode, el NameNode podrá repartir la información que éste tenía anteriormente a otro DataNode nuevo o a los que ya disponía que sigan operativos. El único inconveniente de todo este proceso es que en el arranque del clúster, el NameNode tiene que esperar a que le llegue toda la información posible de los datos desde los DataNodes para poder crear toda la estructura y comenzar a funcionar. El último de los demonios que queda por ver es el SecondaryNameNode. Despista su nombre ya que no solo Hadoop 16 se trata de una copia de seguridad del NameNode, éste será detallado en punto posterior. 3.2.3 Leer y escribir datos Los clientes pueden leer y escribir en HDFS utilizando diversas herramientas y APIs, aunque todos siguen el mismo proceso, el cliente terminará usando alguna biblioteca de Hadoop. Esta biblioteca encapsula la mayor parte de los detalles de comunicación entre los distintos nodos. Lectura Como podemos ver en la Figura 11 y suponiendo que ya esté alojado en HDFS el fichero /user/Sergio/foo.txt, el cliente empieza contactando con el NameNode indicándole que archivo desearía leer. El NameNode comprueba la existencia del archivo y sus permisos, en caso de que exista y con permisos a ese usuario, el NameNode responde al cliente con el primer identificador de bloque y la lista de DataNodes en el que existe una copia del mismo. En el caso de que el NameNode no esté operativo, no lo estará HDFS, por lo que no será posible realizar la lectura del fichero. Con los ID de bloque y las direcciones de los DataNodes, el cliente ya puede ponerse en contacto con estos últimos y leer los bloques de datos que necesite, terminándose este proceso cuando se lee el último bloque del fichero o el cliente cierra la secuencia del archivo. Otro problema que puede surgir es que en el proceso de lectura el DataNode muera, en ese caso, la biblioteca automáticamente intentará leer de otra copia del mismo bloque. Figura 11: HDFS read path Escritura La escritura de archivos HDFS es un poco más compleja que la lectura. Si se considera el caso más simple representado en la Figura 12, un cliente está creando un nuevo archivo, realiza una solicitud para abrir un archivo con su nombre de escritura utilizando la API de Hadoop FileSystem. Se envía esa solicitud al NameNode para crear el metadato (solo si el usuario tiene permisos para hacerlo). Una vez realizada la entrada de ese metadato, se envía al cliente una respuesta en la que se le indica que el fichero se ha abierto correctamente y que ya puede empezar a escribir datos. A medida que el cliente va escribiendo datos, se va fragmentando en paquetes, que se colocan en cola en la memoria. Un hilo separado del cliente va consumiendo los paquetes de esa cola, a medida que va necesitando más bloques o es necesario la realización de réplicas, se establece una conexión directa al primer DataNode, al segundo, tercero… esto forma una tubería de replicación. Los DataNodes envían un asentimiento, y cuando les llega al cliente, este 17 Big Data, Hadoop y DataMining sobre eventos de seguridad sabrá que los datos se han escrito en todos los nodos o en los que haya sido necesario replicar. A medida que va necesitando más espacio, supondrá más bloques. Cuando ha terminado de enviar el último bloque, el cliente indica que el archivo está completo. Figura 12: HDFS write path 3.2.4 Alta disponibilidad El NameNode almacena los metadatos del sistema de archivos en su disco local, en dos archivos denominados fsimage y edits. Como en cualquier base de datos, fsimage contiene una instantánea completa de los metadatos del sistema de archivos, mientras que edits contiene las modificaciones que se le han aplicado a dichos metadatos. Al inicio el NameNode carga en la memoria RAM la fsimage y se reproducen los cambios que se encuentran en el fichero edits, con lo que se actualiza la visión del sistema de archivos. Con el tiempo el archivo edits crece y crece, por lo que debe aplicarse periódicamente al archivo fsimage del disco. El problema es que el NameNode puede no contar en ese instante con los recursos de CPU o RAM disponibles sin dejar de prestar servicio al clúster, y es aquí es donde aparece el NameNode Secundario. En la Figura 13 se puede ver la interacción que se produce entre el NameNode y el Secondary NameNode, este proceso ocurre cada hora por defecto. El Secondary NameNode le solicita al NameNode que deje de escribir en el fichero edits y comience a escribir en un nuevo fichero llamado edits.new. El Secondary copia los ficheros fsimage y edits del NameNode a un punto local. El Secondary carga la imagen y le aplica los cambios del otro archivo generando un nuevo fsimage con todos los cambios actualizados. Se encargará finalmente de enviar ese nuevo fichero al NameNodeque será su nuevo fsimage, y renombrará edits.new a edits. De esta forma se ha realizado todo el proceso de actualización sin que el NameNode tenga que dejar de atender al servicio del clúster. Hadoop 18 Figura 13: MetaData checkpoint process Como administrador de un clúster no se puede permitir que la caída del mismo dependa de un solo punto de fallo, en este caso el NameNode lo ha sido durante muchos años, pero la comunidad ha invertido mucho tiempo en conseguir solventar esta vulnerabilidad. La alta disponibilidad del NameNode (HA) se despliega como un par activo/pasivo de namenodes. Los edits se van modificando en ambos NameNodes, de forma que si se cae el NameNode el Secondary NameNode debe estar completamente preparado para asumir el mando. Esa comunicación entre ambos se puede realizar de forma manual o de forma automática. En la primera, se debe enviar un comando para efectuar la comunicación entre NameNodes. En cambio, cuando se realiza de forma automática, cada NameNode ejecuta un proceso adicional llamado controlador de conmutación por error (failover controller) que se puede ver en la Figura 14, que monitoriza la salud del proceso y coordina las transacciones entre ambos. Figura 14: HA NameNode 19 Big Data, Hadoop y DataMining sobre eventos de seguridad 3.2.5 Herramientas de línea de comandos También se debe de mencionar un poco sobre la línea de comandos y la API que el cliente utilizará para interaccionar con Hadoop. Hadoop proporciona herramientas de línea de comandos que habilita las operaciones básicas sobre un sistema de ficheros. Dentro de esas herramientas HDFS dispone de un subconjunto de ellas, por ejemplo: hadoop fs muestra un uso básico de las distintas posibilidades. [sergio@hadoop01 ~]$ hadoop fs Usage: java FsShell [-ls <path>] [-lsr <path>] [-df [<path>]] [-du <path>] [-dus <path>] [-count[-q] <path>] [-mv <src> <dst>] [-cp <src> <dst>] [-rm [-skipTrash] <path>] [-rmr [-skipTrash] <path>] [-expunge] [-put <localsrc> ... <dst>] … Por ejempo para listar y copiar archivos del/hacia HDFS deben utilizarse las siguientes líneas: [sergio@hadoop01 ~]$ hadoop fs -ls /user/sergio/ Found 2 items drwx------ - sergio supergroup 0 2014-04-11 15:06 /user/sergio/.staging -rw-r--r-- 3 sergio supergroup 27888890 2014-04-10 13:41 /user/sergio/data.txt [sergio@hadoop01 ~]$ hadoop fs -put /etc/passwd /user/sergio/ [sergio@hadoop01 ~]$ hadoop fs -ls /user/sergio/ Found 3 items drwx------ - sergio supergroup 0 2014-04-11 15:06 /user/sergio/.staging -rw-r--r-- 3 sergio supergroup 27888890 2014-03-10 13:41 /user/sergio/data.txt -rw-r--r-- 3 sergio supergroup 2216 2014-03-25 21:07 /user/sergio/passwd [sergio@hadoop01 ~]$ ls -al passwd ls: passwd: No such file or directory [sergio@hadoop01 ~]$ hadoop fs -get /user/sergio/passwd ./ [sergio@hadoop01 ~]$ ls -al passwd -rw-rw-r--+ 1 sergio sergio 2216 Jan 25 21:17 passwd [sergio@hadoop01 ~]$ hadoop fs -rm /user/sergio/passwd Deleted hdfs://hadoop01.sf.cloudera.com/user/sergio/passwd Lo que se ha realizado en las siguientes líneas no es más que subir un fichero a HDFS, al instentar listarlo en el directorio actual no aparece ya que no está en el sistema propio de ficheros. Pero al bajarse el mismo fichero que se subió en el directorio actual ya si existirá y se tendrá acceso a él. Con esto se quiere ver que el sistema Hadoop 20 de ficheros local y HDFS son completamente independientes. Se podrán subir y bajar ficheros entre ellos y para acceder a HDFS deberá de escribirse hadoop fs para tener acceso a todas los comandos que Hadoop ofrece. 3.3 MapReduce & YARN 3.3.1 Introducción MapReduce es un modelo de computación que permite realizar problemas donde se cuenta con gran volumen de datos sobre Hadoop. Una de las ventajas de MapReduce es que podemos resolver este tipo de problemas utilizando para ello lo que se conoce como commodity hardware, es decir ordenadores de gama básica. Esto permite no tener que invertir grandes cantidades de dinero en equipos costosos como se hacía antiguamente para solventar problemas de Big Data. 3.3.2 Fases MapReduce Las fases de MapReduce se dividen, como su propio nombre indica, en dos funciones, map y reduce, pero también existen otra serie de funciones intermedias que deben ser realizadas de forma correcta para que tenga éxito la resolución del problema. 1. Input: Es una fase previa al mapeo. Consiste en preparar y dividir (splitting) los datos de entrada del problema en pares “claves/valor” que son distribuidos entre los distintos nodos que componen el clúster de ordenadores. Estos bloques parciales suelen ser almacenados en un sistema distribuido de ficheros como HDFS para mejorar la eficiencia del procesamiento. En HDFS estos bloques suelen tener un tamaño de 64MB. Es normal que además de distribuir esta información haya algún tipo de replicación de datos entre nodos para asegurar la tolerancia a los fallos que se habló con anterioridad. 2. Map: En esta fase se ejecutará una función de mapeo escrita por el usuario por cada par clave/valor que se encuentre en cada nodo. Tomará como entrada una de las claves y su valor asociado obtenido de la fase de splitting. La salida de esta función será un conjunto de pares clave/valor que más tarde será la entrada de la fase Reduce. Una de las ventajas de MapReduce es que es el algoritmo el que va a los datos, evitando que exista una transferencia continua de datos entre los distintos nodos del cluster, es uno de los cuellos de botella más comunes en estos tipos de computaciones paralela. 3. Shuffle: Durante esta fase se ordenará de manera local a cada nodo los resultados de la fase anterior. Es conveniente garantizar por parte de la implementación que se use de MapReduce que todos los pares creados en la fase anterior sean enviados como entrada al mismo nodo reducer. Al terminar esta fase se tendrán que distribuir obteniendo un conjunto formado por n claves y una lista de valores asociados a cada una de estas claves. 4. Reduce: En esta fase se tomará como datos de entrada cada una de las claves y la lista de valores asociados a ella, obtenidos durante la fase de shuffle. Sobre esta lista de valores se aplicará el algoritmo a través del cual quiera resolverse el problema. La salida de la fase de Reduce es una lista de pares claves/valor. 5. Output: Los datos obtenidos en la fase de Reduce deberán ser movidos a un sistema de ficheros HDFS, una base de datos o cualquier otro sistema al que quiera consultarse el resultado del problema. En la siguiente figura puede ver todo el proceso detallado arriba. 21 Big Data, Hadoop y DataMining sobre eventos de seguridad Figura 15: MapReduce process Ejemplo Si se imagina un problema que consiste en contar el número de apariciones de cada palabra dentro de un texto plano. En la fase input se va a transformar el texto plano en una lista de claves/valor donde la clave podría ser el desplazamiento del primer carácter de cada sentencia del texto y la lista de valores estaría formada por las palabras que conforman cada una de estas sentencias. Esta lista de claves/valor está distribuida entre los distintos nodos del clúster. La función de mapeo cogerá un elemento de la lista clave/valor. Si la palabra aparece por primera vez, e creará un par clave/valor, donde la clave será la palabra y el valor se pondrá a uno. Si la palabra ya ha aparecido se aumentará en una unidad de valor asociado a esa palabra. Finalmente la función Map, emitirá un conjunto de pares clave/valor donde la clave será una palabra y el valor será el número de apariciones de esa palabra dentro de cada unade las sentencias. En la fase Shuffle, se tendrá en cada nodo del clúster un conjunto formado por pares donde cada clave será una palabra y el valor será igual al número de aparicicones de esta en una sentencia concreta del texto plano Hadoop 22 original. Durante esta fase se va a asegurar que cada par que comparte la misma clave sea enviada al mismo nodo reduce. Finalmente, a cada función Reduce en cada uno de los nodos se le pasará como parámetro una clave (en nuestro caso la palabra) y una lista con el valor de las apariciones en cada una de las sentencias del texto plano. El algoritmo aplicado será sumar dicha lista de valores para obtener el número de apariciones de cada una de las palabras dentro del texto original. Una vez obtenido el número de apariciones de cada palabra, se deberá escribir su resultado a la salida estándar, un sistema de ficheros HDFS o a otro tipo de sistema como otra base de datos donde poder evaluar dicho resultado. Figura 16: Ejemplo MapReduce 3.3.3 Arquitectura y demonios Yarn es la nueva infraestructura sobre la que se soporta Hadoop. Originariamente escrito para implementar MapReduce, YARN generaliza la arquitectura original para dar soporte a aplicaciones no sólo MapReduce. La anterior versión de MapReduce (MR1) está enfocada a la gestión eficiente de recursos para dar soporte exclusivamente a tareas MapReduce. Cambio en la arquitectura de la anterior versión a la nueva Los nodos en MR1 son el JobTracker con sus TaskTrackers, y el NameNode con sus DataNodes en la parte HDFS para dar soporte a las anteriores. La tarea del JobTracker era doble, tenía que gestionar los recursos por un lado y el dispatching y monitorización de los trabajos por otro. En YARN, el JobTracker se transforma en el ResourceManager. Éste a su vez se separa en dos componentes especializados enfocados a las dos tareas mencionadas en el párrafo anterior, Scheduler y ApplicationManager. El Scheduler se encarga de disponibilizar los recursos para las distintas aplicaciones agrupándolas según sus restricciones de capacidad, colas, etc… pero no se ocupa de monitorizar estas aplicaciones. Es el encargado de particionar los recursos del clúster entre las distintas aplicaciones. Los NodeManagers son los delegados del Scheduler en cada nodo, responsables de monitorizar el consumo de recursos de cada nodo y de enviar esta información al Scheduler. Los ApplicationMaster son los responsables de solicitar al Scheduler los recursos necesarios para las aplicaciones y éstos si que se encargan de monitorizar el estado de las mismas y su progreso. Son gestionados por el ApplicationManager. Los recursos se gestionan en forma de “containers” (que encapsulan CPU, memoria, disco, red, etc…). 23 Big Data, Hadoop y DataMining sobre eventos de seguridad Cambios conceptuales En MR1 un cliente enviaba una tarea al JobTracker, y éste lo desmenuzaba en tasks que remitía a los TaskTrackers. En Yarn, el cliente envía una aplicación al ResourceManager, que remite esta petición al ApplicationManager. Los ApplicationMaster son los responsables de obtener un container (pack de recursos) del Scheduler para ejecutar su aplicación, lanzarla, monitorizarla y relanzarla si fuera necesario. El ApplicationMaanager se encarga de mantener levantados los ApplicationesMasters. ZooKeeper se mantiene a su vez como vigilante de los nodos. En la siguiente figura puede verse un esquema de YARN con todo lo explicado anteriormente. Figura 17: YARN arquitecture Además de los demonios vistos anteriormente, es opcional pero se puede incorporar otro demonio más llamado JobHistory Server. En él se podrá ver en tiempo real todos las tareas que se estén ejecutando y las que ya se hayan ejecutado, viendo cuáles han sido satisfactorios, cuáles han fallado… etc. 3.4 Puesta en marcha 3.4.1 Instalación La instalación es relativamente sencilla, la dificultad recae mayormente en la configuración. Para el funcionamiento de Hadoop son necesarios una serie de requisitos como tener protoc 2.5.0 instalado, java 1.6… toda la información relativa a los requisitos puedes encontrarse en la página oficial hadoop.apache.org. En dicha página se pueden encontrar las distintas versiones estables. En este proyecto se comenzó trabajando con la 2.3, en este último mes se actualizó a la 2.4, y por estas fechas estará disponible la 2.5. Hadoop 24 En este caso si se accede al directorio de Hadoop 2.4 podrá encontrarse tanto la versión en formato .tar.gz como la versión src. En el proyecto se trabajará con máquinas “Centos release 6.5”. En esta ocasión se alojará la carpeta completa de Hadoop en /opt/rb/var/hadoop. Por lo que con wget se puede descargar de la página mencionada anteriormente. Una vez se encuentra todo Hadoop alojado en /opt/rb/var/hadoop, se debe establecer las variables de entorno $HADOOP_HOME al directorio anterior, y para los ficheros de configuración $HADOOP_CONF_DIR que debe ser /opt/rb/var/hadoop/etc/hadoop. En la siguiente figura puede verse la estructura de directorios que se tiene dentro de la carpeta de hadoop. Figura 18: directorios dentro de Hadoop Si se necesita Hadoop para realizar algo temporal y no supone un proyecto a largo plazo, se puede acceder a soluciones de empresas como Cloudera o Hortonworks, que proporcionan máquinas virtuales con todos los servicios funcionando correctamente. En el caso de este proyecto, Hadoop debe adecuarse a la máquina en la que se instala con sus correspondientes características, limitaciones, propiedades, etc. Por lo que en el siguiente apartado se verá la configuración de la misma. 3.4.2 Configuración En el directorio de Hadoop que se ha visto anteriormente, se puede ver la carpeta etc, donde se podrá encontrar los archivos de configuración ($HADOOP_CONF_DIR). Los 4 pilares de la configuración de Hadoop son los archivos: core-site.xml, hdfs-site.xml, mapred-site.xml y yarn-site.xml. Debido a la longitud de los mismos, se ha añadido cada uno de ellos en el Anexo A. Aquí solo se verán las propiedades más relevantes de algunos de ellos. Nota: el valor de estas propiedades se ha obtenido de nodos alojados en la empresa. Tabla 2: core-site.xml CORE-SITE.XML fs.defaultFS hdfs://192.168.101.202:8020 Dirección del NameNode. Tabla 3: hdfs-site.xml HDFS-SITE.XML dfs.replication 1 Número de veces que debe replicarse cada uno de los bloques a lo largo del clúster. dfs.namenode.name.dir file:/var/lib/hadoop/name Determina el lugar dentro del sistema de ficheros local, donde debe guardar la imagen de todo el sistema de archivos (fsimage). dfs.datanode.data.dir file:/var/lib/hadoop/data Determina el lugar dentro del sistema de ficheros local donde los DataNodes deben guardar los 25 Big Data, Hadoop y DataMining sobre eventos de seguridad bloques. dfs.datanode.adress 192.168.101.202:50010 Dirección del DataNode. dfs.datanode.http.address 192.168.101.202:50075 Dirección web por la que escucha la página del DataNode. dfs.namenode.http-address 192.168.101.202:50070 Dirección web por la que escuha la página del NameNode. dfs.heartbeat.interval 3 Intervalo (segundos) tras los que los DataNodes irán enviándole mensajes al NameNode indicando que siguen vivos. Tabla 4: mapred-site.xml MAPRED-SITE.XML mapreduce.map.java.opts -Xmx1242002K Máximo tamaño de memoria permitido para los procesos de mapeo. mapreduce.reduce.java.opts -Xmx2484005K Máximo tamaño de memoria permitido para los procesos de reduce. mapreduce.jobhistory.webapp.address 192.168.101.202:19888 Interfaz web de usuario por la que escucha el JobHistory mapreduce.jobtracker.address192.168.101.202:8021 Host y puerto por el que el MapReduce job tracker está escuchando. Tabla 5: yarn-site.xml YARN-SITE.XML yarn.resourcemanager.address 192.168.101.202:8032 Dirección de la interfaz del Application Manager en el ResourceManager. yarn.nodemanager.local-dirs var/lib/hadoop/yarn Carpeta local donde se almacenarán otros subdirectorios que serán los Containers. yarn.nodemanager.address 192.168.101.202:45454 Dirección del container manager en el NodeManager. Hadoop 26 Además de los 4 ficheros de configuración mencionados anteriormente, se tienen dentro de la carpeta de configuración otros dos archivos llamados slaves y exclude. Estos archivos solo deben rellenarse en el nodo NameNode, en el fichero slaves deberán colocarse los nombres de los DataNodes que vayan a permitir el NameNode que se asocien a él. En cambio en el fichero exclude es lo inverso, se colocarán los hostnames o IPs de los DataNode que no se quiera que se asocien al NameNode. El problema es que dependiendo del clúster que se vaya a montar, los ficheros de configuración cambiarán, es decir, las IPs no serán las mismas, la memoria dependerá del nodo en el que esté alojado… La solución que se ha adoptado para estos problemas es aprovechar el uso de Chef en el sistema operativo donde se está incorporando Apache Hadoop. Con Chef se puede automatizar la forma de construir, implementar y administrar la infraestructura. Chef se basa en unos templates o plantillas para automatizar las tareas de infraestructura y crear los ficheros de configuración. Se han creado en /opt/rb/var/chef/cookbooks/redBorder-manager/templates/default una serie de ficheros en formato Embedded Ruby, este formato es un sistema de plantillas. Un ejemplo de lo que se puede encontrar en él es: <property> <name>fs.defaultFS</name> <value>hdfs://<%= @hadoop_namenode_node.nil? ? "127.0.0.1" : @hadoop_namenode_node.name %>:8020</value> </property> Con el anterior fragmento, mira si en /etc/hosts existe la siguiente línea 192.168.106.202 hadoop_namenode.redborder.clúster En el caso de que exista pondrá el valor de la misma, en este caso 192.168.106.202:8020, en caso contrario se pondrá la IP 127.0.0.1:8020. De esta forma, poniendo en /etc/hosts las IPs del NameNode, DataNodes, ResourceManager, etc. Chef se encargará de crear los ficheros de configuración con los parámetros correctos para que al levantar el clúster, los DataNodes sepan la dirección del NameNode o ResourceManager, por ejemplo. El otro problema que surge con la configuración es el tema de la memoria. Ésta debe de ponderarse según la memoria total del nodo, es decir, al NameNode no le corresponderá la misma memoria si el ordenador tiene 4 GB de RAM que si tiene 16Gb. Por lo que en un fichero de configuración se le ha asignado una ponderación a cada uno de los nodos: … {:name => "hadoop_nodemanager", :count => 8}, {:name => "hadoop_datanode", :count => 3}, {:name => "hadoop_namenode", :count => 3}, {:name => "hadoop_historyserver", :count => 2}, {:name => "hadoop_resourcemanager", :count => 2}, … Como se puede apreciar al nodo que más memoria se le ha concedido será al NodeManager ya que será el que tenga que ejecutar las tareas que el ResourceManager le asigne, y por tanto, el que en un momento puntual más memoria RAM requerirá. Estos parámetros hacen que se genere su correspondiente archivo donde se encuentran los KB que le han sido asignados: [root@pablo02 sysconfig]# ls | grep hadoop hadoop_datanode hadoop_historyserver hadoop_namenode 27 Big Data, Hadoop y DataMining sobre eventos de seguridad hadoop_nodemanager hadoop_resourcemanager [root@pablo02 sysconfig]# cat hadoop_* MEMTOTAL=1164377 MEMTOTAL=776251 MEMTOTAL=1164377 MEMTOTAL=3105007 MEMTOTAL=776251 Por lo que en las plantillas .erb (embedded ruby) se accede a esos valores <property> <name>mapreduce.reduce.java.opts</name> <value>-Xmx<%= @memory_services["hadoop_nodemanager"].nil? ? "827392": (@memory_services["hadoop_nodemanager"]*0.8).to_i %>K </value> </property> Y de esta forma se está configurando los valores que a la memoria respecta de mapred-site.xml y yarn- site.xml, según la memoria total del nodo en el que se encuentra alojado, solventándose así los dos problemas que se tenían en un comienzo. 3.4.3 Arranque Para comenzar a utilizar Hadoop lo primero que se deberá hacer es formatear el HDFS. Para ello, dentro de la carpeta sbin de Hadoop se podrá realizar de la siguiente forma: Tras realizar el formateo se podrá ir arrancando todos los nodos: - NameNode $HADOOP_HOME/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR --script hdfs start namenode - DataNodes $HADOOP_HOME/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR --script hdfs start datanode - Secondary NameNode $HADOOP_HOME/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR --script hdfs start secondarynamenode - ResourceManager $HADOOP_HOME/sbin/yarn-daemon.sh --config $HADOOP_CONF_DIR start resourcemanager - NodeManagers $HADOOP_HOME/sbin/yarn-daemon.sh --config $HADOOP_CONF_DIR start nodemanager - JobHistory $HADOOP_HOME/sbin/mr-jobhistory-daemon.sh start historyserver --config $HADOOP_CONF_DIR Hadoop 28 Una vez arrancados todos los nodos, se podrá comprobar si todo está funcionando correctamente accediendo a las páginas webs de cada uno de ellos, o simplemente listando mediante ls el contenido de hadoop como se vio anteriormente en el apartado de línea de comandos. Las páginas webs se mostrarán en el siguiente apartado con el levantamiento del singleNode y del clúster. 3.5 Hadoop Single Node & Hadoop Clúster En este apartado se verán los dos tipos de despligues que se pueden realizar con Hadoop: en un único nodo “Single node” o en modo “clúster”. Se comenzará con la instalación en un único nodo, aunque no tiene mucho sentido ya que no se aprovecha las grandes ventajas que este sistema de ficheros distribuido aporta, pero es una buena solución para comenzar aprendiendo las configuraciones básicas, para pequeños proyectos, etc. 3.5.1 Single Node Se arrancan todos los nodos tal y como se ha mencionado en apartados anteriores. Figura 19: Single node running La manera más rápida de comprobar si está funcionando correctamente la parte HDFS es realizar un ls a la carpeta raíz del mismo. [root@pablo05 ~]# hdfs dfs -ls / Found 5 items drwxrwxrwt - hadoop supergroup 0 2014-08-28 09:51 /app-logs drwxr-xr-x - hadoop supergroup 0 2014-08-28 09:48 /mr- history drwxr-xr-x - root supergroup 0 2014-08-28 09:51 /rb drwx------ - root supergroup 0 2014-08-28 09:51 /user drwxrwx--- - hadoop supergroup 0 2014-08-28 09:48 /var Como se puede apreciar, se lista los subdirectorios que están por debajo del directorio raíz de HDFS. Se puede subir ficheros, descargar ficheros con los comandos vistos en el apartado anterior. Ahora se mostrará la vista desde la interfaz web de los distintos nodos. Si se accede a la del NameNode, podrá verse la información que se muestra en las siguientes figuras. Ip_namenode:50070 (La ip y el puerto por el que escucha se a configurado en hdfs-site.xml) 29 Big Data, Hadoop y DataMining sobre eventos de seguridad Figura 20: Interfaz Web NameNode (1) Se puede ver la fecha en la que se inició el clúster, la versión de Hadoop y algunos identificadores. Se puede apreciar que en la parte superior se tiene un menú donde acceder a la ventana de los DataNodes, cómo ha ido el proceso de arranque, etc. Si se continua descendiendo en la misma pestaña se puede encontrar un resumen del estado del sistema de archivos.En esta imagen se aprecia el número de bloques, memoria total y usada, tanto la memoria que se ha reservado para HDFS como la memoria que se ha dejado para utilizar de forma no distribuida. También en la parte inferior se ve cuántos DataNodes están activos, en este caso como se está trabajando en un único nodo solo se dispone de 1 DataNode operativo. También se aprecian los DataNodes que se han dado de baja, o a los que se le está dando. Figura 21: Interfaz Web NameNode (2) Hadoop 30 También se puede comprobar que los ficheros image y edits se encuentran en el directorio /var/lib/hadoop/name. Figura 22: ficheros image y edits En el menú de arriba, al seleccionar la pestaña Datanodes se mostrará la información de cada uno de los DataNodes, en este caso se verá que se dispone de un DataNode en funcionamiento (junto con sus características) y ninguno ha sido dado de baja. Figura 23: (NameNode) Página DataNodes Por ejemplo se dispone de una carpeta en el directorio raíz de HDFS llamada /rb, se puede crear una copia de seguridad o instantánea de ese directorio. Los pasos a seguir serán habilitarle a dicho directorio la posibilidad de crear Snapshots sobre él, y realizarle el mismo. [root@pablo05 hadoop]# hdfs dfsadmin -allowSnapshot /rb Allowing snaphot on /rb succeeded [root@pablo05 hadoop]# hdfs dfs -createSnapshot /rb Created snapshot /rb/.snapshot/s20140828-124722.329 Por lo que al acceder a la pestaña de Snapshots se verá que se ha creado una instantánea de ese directorio. 31 Big Data, Hadoop y DataMining sobre eventos de seguridad Figura 24: (NameNode) Página de Snapshots En la siguiente pestaña se mostrará qué tal ha ido el arranque del clúster (Startup Progress). En él se puede apreciar cómo comienza cargándose la fsimage, y posteriormente se le aplican los cambios de edits. Figura 25: (NameNode) Proceso de arranque Y, por último, en Utilities, se puede acceder tanto al contenido del sistema de ficheros como a los logs. Figura 26: (NameNode) Página de utilidades Hadoop 32 En Browse the file System se encuentra el mismo resultado de hacer un ls. Figura 27: (NameNode) Browse Directory En Logs, se encuentran los logs clasificados por nodo. Todo lo visto con anterioridad pertenece al NameNode, si se accede a la ip del DataNode y puerto 50075 se podrá ver la información relativa al DataNode. Figura 28: (NameNode) Logs Figura 29: Información del DataNode 33 Big Data, Hadoop y DataMining sobre eventos de seguridad Para el ResourceManager (puerto 8021) se pueden ver las tareas pendientes, las que están ejecutándose, la memoria total para ejecutar dichos procesos, los NodeManagers que tiene disponibles (Active Nodes). Figura 30: Interfaz web del ResourceManager Por último, el JobHistory (puerto 19888) muestra solo los trabajos que se están ejecutando y se han ejecutado, si el resultado ha sido satisfactorio, o en el caso de que haya fallado, se muestran los logs del error, por lo que es una buena página donde se puede hacer el seguimiento de todos los procesos MapReduce que trabajen en nuestro clúster. Figura 31: Interfaz web del JobHistory 3.5.2 Clúster mode Toda la configuración que se ha visto en el apartado anterior es para conseguir tener todos los demonios corriendo en el mismo nodo. Pero la mayor funcionalidad de Hadoop es la escalabilidad, si necesitas más memoria física, se añaden más DataNodes, que necesitas más capacidad de procesamiento, se añaden más NodeManagers. En este tipo de arquitecturas, los componentes crecen en horizontal y no en vertical. Es decir, si se necesitan mejores prestaciones se añade otro nodo más, no se mejoran las características de uno de ellos. Si la configuración de los templates (plantillas) de Chef de los que se habló con anterioridad es correcta, a la hora de montar un clúster, con solo indicar el nombre del host o la IP donde estaría alojado cada uno de los demonios se debería de configurar todo el clúster solo. Hadoop 34 Por ejemplo en el template de hdfs-site.xml se puede encontrar la siguiente propiedad: <property> <name>dfs.namenode.rpc-address</name> <value><%= @hadoop_namenode_node.nil? ? "127.0.0.1" : @hadoop_namenode_node.name %>:8020</value> </property> que da lugar a la siguiente línea en hdfs-site.xml perteneciente a la configuración de Hadoop. <property> <name>dfs.namenode.rpc-address</name> <value>pablo06:8020</value> </property> Y hace referencia al lugar donde los DataNodes deberán comunicarse con el NameNode, de esta forma al arrancar cualquier DataNode del clúster sabrá donde se encuentra el NameNode y el puerto por el que está escuchando. Figura 32: Nodos en el clúster Si se vuelve a navegar por las interfaces web de los distintos nodos se puede ver como ha incrementado el número de DataNodes o NodeManagers (y consecuentemente la capacidad de almacenamiento y de procesamiento). Figura 33: Incremento de DataNodes En el ResourceManager se puede apreciar cómo también se ha incrementado el número de NodeManagers y con ello la capacidad de procesamiento, llegando en este caso a casi 12 GB. Figura 34: Incremento de NodeManagers 35 Big Data, Hadoop y DataMining sobre eventos de seguridad 3.6 Mantenimiento del clúster 3.6.1 Añadir o dar de baja un DataNode La adición de un DataNode al clúster se hace en respuesta a una necesidad adicional de capacidad de almacenamiento en la mayoría de los casos, aunque también puede deberse a querer aumentar el ancho de banda de entrada y salida de datos o a reducir el impacto de la pérdida de una sola máquina. Para que el sistema HDFS lo acoja habrá que añadir la nueva IP del DataNode a incluir y que este proceso se actualice de forma dinámica sin necesidad de reiniciar el NameNode. Para ello habrá que seguir los siguientes pasos: 1. Añadir la nueva dirección IP del DataNode en el archivo dfs.hosts. 2. Ejecutar el comando hadoop dfsadmin –refreshNodes como superusuario de HDFS. 3. Arrancar el proceso del DataNode. 4. Comprobar la UI web del NameNode o la salida de hadoop dfsadmin –report para confirmar que el nuevo DataNode ha sido conectado. También puede ocurrir que se de la situación contraria, que haya que dar de baja un DataNode, este proceso es algo más complejo ya que se deben tener en cuenta los datos que ese DataNode almacenaba, la velocidad de la red, etc. ya que es necesario mantener el factor de replicación. El desmantelamiento de un DataNode aumenta el uso de la red, ya que HDFS se ve obligado a crear nuevas réplicas de los bloques que éste contenía en otros DataNodes. Cuando el proceso comienza, la interfaz de usuario del NameNode indicará que la baja de uno o más nodos se encuentra en curso. Una vez cambia de estado pasa a fuera de servicio. En ese punto, el proceso DataNode puede detenerse sin peligro. 1. Agregar la dirección IP del DataNode en el archivo dfs.host.exclude. 2. Ejecutar el comando hadoop dfsadmin –refreshNodes como superusuario de HDFS. 3. Comrpobar en la interfaz del NameNode que el DataNode se encuentra en proceso de baja.
Compartir