msgbartop
La Lógica es maravillosa, pero a veces se obtienen mejores resultados pensando
msgbarbottom

08 dic 15 Uso de CirrOS como servidor ligero de prueba independiente

Decíamos ayer que uno de los elementos del entorno de prueba de la solución con la que estoy trabajando en Ansible era un servidor CirrOS. Pero… ¿qué es un servidor CirrOS?

CirrOS es un servidor ligero, muy ligero, especialmente desarrollado para servir como demostrador de la capacidad de despliegue de máquinas en entornos cloud, como Openstack (de ahí el juego de palabras, claro). Es un servidor cuya imagen ocupa tan sólo 12 megas, se puede desplegar con 32 megas de RAM y una sola CPU. No se le pueden instalar -al menos, no fácilmente- paquetes, y las funcionalidades que ofrece son sumamente limitadas.

Por tanto, ¿qué razón habría para querer desplegar un sevidor así en un entorno? No muchas, en realidad, salvo que tu entorno de demo sea especialmente reducido, como es mi caso. :mgreen: En realidad, también tiene algún problema adicional: aunque la imagen a desplegar es una imagen QCOW2 convencional, que en Openstack despliega de manera sencilla en KVM, fuera de un entorno Openstack, aún usando KVM, da un poco de guerra para desplegarlo.Por ejemplo, en Gnome, aunque puedes crear la máquina desde el “Virtual Machine Manager”, utilizando la imagen descargada, la máquina no arranca. Es preciso exportar el fichero XML de configuración de la máquina, modificar el tipo de disco de “raw” a “qcow2″, eliminar la máquina y volver a crearla importando el XML para hacerla funcionar.

Además, un despliegue convencional de la imagen proporcionada por Launchpad tiene otro problema: como espera ser llamada desde un entorno de computación cloud espera recibir determinados parámetros de configuración a través de los servicios metadatos de éste. Y como no los recibe, se queda esperando durante 20 segundos su recepción… 20 veces.

Además, no hay gran cosa que puedas hacer, salvo acceder a ella por SSH. Ni servidor web, ni de correo, ni de nada.

Pero, pese a todo, es una pequeña maravilla que merece una oportunidad. Porque para cada uno de los problemas anteriores, existe una solución:

  • El problema del arranque: como se ha comentado, es cuestión de editar el XML y cambiar el parámetro de despliegue del disco. Y una vez creada la máquina, se puede clonar tantas veces como sea necesario, ya que a partir de este momento siempre se desplegará con la opción correcta.
  • Lentitud en el arranque: Aquí hay dos opciones. O bien tocar los parámetros de arranque para que no espere la información del entorno cloud… o hacer uso de una imagen previamente preparada por el usuario de GitHub Eprasad. Ojo, a esta imagen hay que hacerle de igual manera lo comentado en el punto anterior para poderla arrancar desde KVM.
  • Carencia de servicios: Y es aquí donde llega la magia. Como he comentado, no hay apenas nada instalado en la máquina, salvo SSH y poco más. Pero ese poco más es sumamente importante. Porque tenemos nada más y nada menos que una instalación de Netcat, la navaja suiza del TCP/IP. Y a partir de aquí, la imaginación puede empezar a volar. Por ejemplo, podemos simular de manera sencilla un bonito servidor HTTP:

    MYIP=$(ifconfig eth0|grep 'inet addr'|awk -F: '{print $2}'| awk '{print $1}')

    while true; do echo -e "HTTP/1.0 200 OK\r\n\r\n<h1>Hi IBM. Welcome to $MYIP</h1>" | sudo nc -l -p 80 ; done&

Así que recomiendo de manera encarecida darle una oportunidad a esta pequeña maravilla. Porque lo merece.

P.D.: Otro pequeño recordatorio. Cómo configurar de manera estática el direccionamiento de red en CirrOS, y definir rutas estáticas:

CirrOS configure network:

COMPUTE: /etc/network/interfaces

auto lo
iface lo inet loopback

auto mybr0
iface mybr0 inet static
address 10.1.0.1
netmask 255.255.0.0
network 10.1.0.0
gateway 10.1.0.2
bridge_ports eth5
bridge_stp off
bridge_maxwait 0
bridge_fd 0

up route add -net 10.0.0.0 netmask 255.255.0.0 gw 10.1.0.2 dev eth5
up route add -net 10.1.0.0 netmask 255.255.0.0 gw 10.1.0.2 dev eth5
up route add -net 0.0.0.0 gw 10.1.0.2 eth5

VN:F [1.9.20_1166]
Rating: 0.0/10 (0 votes cast)

Etiquetas: , , , ,

07 dic 15 Automatización de despliegue y gestión de cortafuegos con Ansible

Estas últimas jornadas he estado trabajando en un sistema de automatización de despliegue de cortafuegos en Softlayer. Llevo un tiempo trabajando con cortafuegos Vyatta, que si bien son bastante prácticos para desplegarlos tanto sobre entornos virtuales como sobre máquinas físicas, adolecen de un grave problema: carecen de un sistema de gestión centralizado. Y cuando manejas del orden de medio centenar de cortafuegos, esto se hace especialmente necesario, no sólo para mantener un sistema homogéneo y manejable, sino también para evitar, en la medida de lo posible, fallos humanos.

¿Y cuál ha sido el sistema elegido para automatizar ciertas tareas de despliegue y gestión? Pues como no podía ser menos, ha sido Ansible. Hasta este momento he sido capaz de:

  • Hacer un despliegue automatizado de la configuración inicial de cortafuegos vyatta en clúster a partir de cortafuegos individuales.
  • Automatizar el desploegue y borrado de múltiples reglas en diferentes cortafuegos

Para ello, lo primero ha sido preparar un entorno de demo, que ha tenido casi más chicha que la propia configuracion con Ansible:

Diagrama del entorno de despliegue

Diagrama del entorno de despliegue


…que se compone de los siguientes elementos:

  • Portátil: Mi propio portátil de trabajo. Actúa como entorno de virtualización basado en KVM. Su función como entorno de virtualización no es relevante en sí como elemento de testeo, pero sin él no sería posible realizar el despliegue del entorno. Sí es relevante su función como cliente de los servicios desplegados por el servidor CirrOS. Se le ha configurado una ruta estática para enrutar el tráfico a través de la IP .254 de la subred externa, que será la IP flotante del clúster de cortafuegos.
  • Servidor CirrOS: Servidor extremadamente ligero (en torno a 32 MB de RAM y un procesador) que levanta servicios SSH y HTTP, este último mediante una simulación con NetCat, lo que también tiene su miga. En cuanto al servidor CirrOS, a los conocedores de entornos cloud como Openstack les sonará bastante, pero he conseguido hacer un despliegue en un entorno KVM convencional.
  • Clúster de cortafuegos Vyatta: El clúster de cortafuegos Vyatta (bueno, en realidad VyOS, el fork software libre surgido cuando Brocade compró el proyecto original) actúa como cortafuegos entre las subredes interna y externa. En la fase inicial consiste en dos cortafuegos independientes, como una configuración básica de sus interfaces de red y poco más, con direcciónamiento .252 y .253. En esta fase, por lo tanto, el portátil no es capaz de conectar con el servidor CirrOS. El equipo vyatta1 actuará como maestro en la configuración VRRP, y el equipo vyatta2 actuará como esclavo.
  • Ansible: Este servidor actúa como servidor de Ansible, como su propio nombre indica. Conecta con los dispositivos vyatta haciendo uso de clave SSH, por lo que -y esto es de lo mejor de Ansible- no necesita de ningún tipo de agente o plugin para realizar los despliegues de configuración o recogida de información desde los dispositivos.

Ansible -y esto no pretente ser una descripción exhaustiva de sus características, por lo que ruego se me perdone cualquier incorrección que pueda perpetrar- puede actuar bien enviando comandos únicos a los equipos administrados, bien haciendo uso de recetas (playbooks). Estas recetas consisten en un grupo de tareas, plantillas y parámetros que se combinan para realizar las labores de automatización de configuración y labores de gestión en los dispositivos:

  • Tareas (task): Comando o grupo de comandos que realizan alguna acción en el dispositivo. Éstas pueden ser creadas en base a módulos predefinidos para simplificar su proceso de creación
  • Plantillas (templates): Las tareas pueden hacer uso de plantillas para simplificar el proceso de configuración o gestión de los dispositivos. Estas plantillas, cuyas variables se completan haciendo uso de los valores asignados a los parámetros, se usan para crear al vuelo los scripts (o cualquier comando) que se quieran aplicar al dispositivo. Lo más interesante del asunto es que estas plantillas se pueden crear de manera bastante sencilla en base a scripts convencionales que ya se estuvieran utilizando para gestionar el dispositivo, simplemente reemplazando las variables del scripts por las variables propias de j2, que posteriormente, en tiempo de ejecución, serán sustituidas por los parámetros definidos en Ansible.
  • Parámetros: Valores concretos de la configuración de los dispositivos a gestionar con Ansible, como por ejemplo el nombre del cortafuegos, la IP de una interfaz, o los valores de la VPN. Estos parámetros pueden ser definidos de múltiples maneras: usando un fichero de configuración global de parámetros, usando ficheros específicos para cada dispositivo (algo especialmente interesante para este caso), almacenando valores en tiempo de ejecución de los propios dispositivos gestionados o del entorno, o una combinación de estos métodos. Posteriormente, estos parámetros se usan para configurar los dispositivos, bien mediante tareas individuales o mediante plantillas.
  • Dispositivos (hosts): Conjunto de servidores que queremos administrar. Pueden ser etiquetados para aplicarle sólo ciertas tareas (por ejemplo, los dispositivos individuales de las parejas de vyattas pueden ser etiquetados como maestro y esclavo para sólo aplicar a cada uno de ellos la configuración que corresponda) que sean de aplicación para el tipo de disposito gestionado.

Una vez configurado el entorno, el recetario, las plantillas y parámetros, la configuración quedó lista para ser aplicada a los dispositivos. Las tareas de un recetario pueden ser ejecutadas de manera secuencial o en una sucesión específica, usando para ello las oportunas etiquetas. En mi entorno, y hasta el momento, he definido tres tipos de tareas:

  • Despliegue inicial: Realiza el despligue inicial de la configuración a la pareja de vyattas para convertirlos en un clúster y realizar las configuraciones básicas de seguridad y gestión requeridas. En el entorno de demo, una vez realizada esta tarea, queda configurada la interfaz flotante en ambas subredes, realizado NAT y el enmascaramiento del tráfico de la interfaz interna a la externa, y permitido el tráfico ICMP entrante de la interfaz externa a la interna. Todo ello permite que el portátil haga ping al servidor, pero no pueda acceder a los servicios.
  • Añadir reglas: Esta tarea realiza un despliegue de política a los cortafuegos. En concreto, permite el tráfico por los puertos 22 y 80 TCP al servidor CirrOS.
  • Borrado de reglas: Permite eliminar las reglas anteriormente definidas

Un ejemplo de ejecución de Ansible para este entorno sería el siguiente:

i82hisaj@debian:~/ansible/vyos# ansible-playbook main.yml -t initial

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.122.252]
ok: [192.168.122.253]

TASK: [initial-config | upload script for configuring description] ************
changed: [192.168.122.252]
changed: [192.168.122.253]

TASK: [initial-config | run script for configuring description] ***************
changed: [192.168.122.252]
changed: [192.168.122.253]

TASK: [initial-config | debug var=desc_value.stdout_lines] ********************
ok: [192.168.122.253] => {
"desc_value.stdout_lines": "{{ desc_value.stdout_lines }}",
"item": ""
}
ok: [192.168.122.252] => {
"desc_value.stdout_lines": "{{ desc_value.stdout_lines }}",
"item": ""
}

PLAY RECAP ********************************************************************
192.168.122.252 : ok=4 changed=2 unreachable=0 failed=0
192.168.122.253 : ok=4 changed=2 unreachable=0 failed=0

i82hisaj@debian:~/ansible/vyos# ansible-playbook main.yml -t add

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.122.253]
ok: [192.168.122.252]

TASK: [rules | retrieve Description for a firewall] ***************************
changed: [192.168.122.252]
changed: [192.168.122.253]

TASK: [rules | upload script for configuring description] *********************
changed: [192.168.122.252]
changed: [192.168.122.253]

TASK: [rules | run script for configuring description] ************************
changed: [192.168.122.252]
changed: [192.168.122.253]

TASK: [rules | debug var=desc_value.stdout_lines] *****************************
ok: [192.168.122.252] => {
"desc_value.stdout_lines": [
"Outside In"
],
"item": ""
}
ok: [192.168.122.253] => {
"desc_value.stdout_lines": [
"Outside In"
],
"item": ""
}

PLAY RECAP ********************************************************************
192.168.122.252 : ok=5 changed=3 unreachable=0 failed=0
192.168.122.253 : ok=5 changed=3 unreachable=0 failed=0

i82hisaj@debian:~/ansible/vyos# ansible-playbook main.yml -t delete

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.122.252]
ok: [192.168.122.253]

TASK: [initial-config | debug var=desc_value.stdout_lines] ********************
ok: [192.168.122.252] => {
"desc_value.stdout_lines": "{{ desc_value.stdout_lines }}",
"item": ""
}
ok: [192.168.122.253] => {
"desc_value.stdout_lines": "{{ desc_value.stdout_lines }}",
"item": ""
}

TASK: [rules | upload script for deleting rule] *******************************
changed: [192.168.122.252]
changed: [192.168.122.253]

TASK: [rules | run script for configuring description] ************************
changed: [192.168.122.253]
changed: [192.168.122.252]

TASK: [rules | debug var=desc_value.stdout_lines] *****************************
ok: [192.168.122.253] => {
"desc_value.stdout_lines": "{{ desc_value.stdout_lines }}",
"item": ""
}
ok: [192.168.122.252] => {
"desc_value.stdout_lines": "{{ desc_value.stdout_lines }}",
"item": ""
}

PLAY RECAP ********************************************************************
192.168.122.252 : ok=5 changed=2 unreachable=0 failed=0
192.168.122.253 : ok=5 changed=2 unreachable=0 failed=0

Algunas ideas hasta el momento:

  • Desafortunadamente no existe ningún módulo oficial que permita hacer la administración simplificada de cortafuegos vyatta, lo que significa que todo el trabajo de definir la automatización de tareas ha de realizarse desde cero, en base a scripts y configuraciones básicas de Ansible.
  • Afortunadamente, el sistema de interacción de Ansible es lo suficientemente flexible para permitir la conversión sencilla de scripts previamente existentes a plantillas J2, lo que permite -en mi caso- aprovechar bastante trabajo previo ya existente.
  • Existen interesantes posibilidades de conectar Ansible con sistemas de gestión vía web, como es el caso del proyecto Semaphore.

En resumen, si bien Ansible este caso requiere de bastante trabajo para poder realizar de manera efectiva la automatización del despliegue y gestión de cortafuegos (vyatta, en este caso), las ventajas que proporciona y el trabajo final que ahorra hacen que valga la pena. Como diría nuestro amigo Barney, en este caso nos encontramos claramente por encima de la diagonal Vicky Mendoza:

VN:F [1.9.20_1166]
Rating: 0.0/10 (0 votes cast)

Etiquetas: , , , ,