Categories
General Guide In detail Security

Hiera-eyaml: A salvo de miradas indiscretas


Para todos aquellos que utilizamos Puppet habitualmente hemos implementado módulos para distintos entornos (development, testing, production), distintos problemas, pautas, ideas… Cada una de las declaraciones que podemos hacer en ellos puede tener requerimientos distintos y debemos tener en cuenta los cambios que pueden surgir en un futuro. Probablemente nos hemos encontrado en la situación en la que hemos integrado nuestros datos de configuración (direcciones IP, nombres de aplicaciones, credenciales, o cualquier tipo de datos que no queramos compartir) en el código de nuestro repositorio.
Existen distintos métodos para separar esta información sensible, a continuación explicaremos como hacerlo a través de Hiera y eyaml.
Hiera es una herramienta de búsqueda de pares clave/valor para configurar información. Hiera-eyaml es un backend para Hiera que nos proporciona pares de clave/valor cifradas en ficheros yaml para ser utilizadas a través de Puppet.
PD: Si utilizáis algún gestor de versiones de Ruby como rbenv o rvm tenedlo en cuenta al instalar hiera y hiera-eyaml 😉
Podemos tomar como ejemplo la configuración de un módulo para gestionar el servicio SSH:

class ssh {
  $ssh_packages      = ['openssh','openssh-clients','openssh-server']
  $permit_root_login = 'no'
  $ssh_users         = ['root','jeff','gary','hunter']
  package { $ssh_packages:
    ensure => present,
    before => File['/etc/ssh/sshd_config'],
  }
  file { '/etc/ssh/sshd_config':
    ensure  => present,
    owner   => 'root',
    group   => 'root',
    mode    => '0644',
    # Template uses $permit_root_login and $ssh_users
    content => template('ssh/sshd_config.erb'),
  }

Y este sería la plantilla que podríamos utilizar para el fichero sshd_config:

Protocol 2
SyslogFacility AUTHPRIV
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
# PermitRootLogin Setting
PermitRootLogin <%= permit_root_login %>
# Allow individual Users
<% ssh_users.each do |user| -%>
AllowUser <%= user %>
<% end -%>
# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL
X11Forwarding yes
Subsystem	sftp	/usr/libexec/openssh/sftp-server

Con Hiera podemos hacer referencia a las variables más sensibles cambiando estas 3 lineas:

$ssh_packages      = hiera('ssh_packages')
$permit_root_login = hiera('permit_root_login')
$ssh_users         = hiera('ssh_users')

 
 
Hiera-eyaml nos puede ayudar a evitar comprometer nuestros datos sensible en el backend configurado con hiera. Podemos seguir este procedimiento para lograrlo:

  1. Generar claves pública y privada, por defecto las crea dentro del directorio ./keys en que ejecutemos el siguiente comando. $ eyaml createkeys
  2.  

  3. Añadimos el backend eyaml a la configuración de Hiera en /etc/hiera.yaml
    ---
    :backends:
        - eyaml
        - yaml
    :hierarchy:
        - %{environment}
        - common
    :yaml:
        :datadir: '/etc/puppet/hieradata'
    :eyaml:
        :datadir: '/etc/puppet/hieradata'
        # If using the pkcs7 encryptor (default)
        :pkcs7_private_key: /path/to/private_key.pkcs7.pem
        :pkcs7_public_key:  /path/to/public_key.pkcs7.pem
  4.  

  5. Añadir un fichero de configuración eyaml, de este modo no deberemos especificar la ubicación cada vez que queramos cifrar datos, por defecto sería ~/.eyaml/config.yaml pero podemos sobrescribir esta configuración con la variable de entorno EYAML_CONFIG.
  6.  

  7. Encriptamos los datos con el comando $ eyaml encrypt -p y obtenemos un string similar a este
    ENC[PKCS7,Y22exl+OvjDe+drmik2XEeD3VQtl1uZJXFFF2NnrMXDWx0csyqLB/2NOWefvNBTZfOlPvMlAesyr4bUY4I5XeVbVk38XKxeriH69EFAD4CahIZlC8lkE/uDhjJGQfh052eonkungHIcuGKY/5sEbbZl/qufjAtp/ufor15VBJtsXt17tXP4yl5ZP119Fwq8xiREGOL0lVvFYJz2hZc1ppPCNG5lwuLnTekXN/OazNYpf4CMd/HjZFXwcXRtTlzewJLc+/gox2IfByQRhsI/AgogRfYQKocZgFb/DOZoXR7wmIZGeunzwhqfmEtGiqpvJJQ5wVRdzJVpTnANBA5qxeA==]
  8.  

  9. En este punto ya podemos añadir la información cifrada en el fichero eyaml definido en el segundo paso.
    ssh::permit_root_login: ENC[PKCS7,Y22exl+OvjDe+drmik2XEeD3VQtl1uZJXFFF2NnrMXDWx0csyqLB/2NOWefvNBTZfOlPvMlAesyr4bUY4I5XeVbVk38XKxeriH69EFAD4CahIZlC8lkE/uDhjJGQfh052eonkungHIcuGKY/5sEbbZl/qufjAtp/ufor15VBJtsXt17tXP4yl5ZP119Fwq8xiREGOL0lVvFYJz2hZc1ppPCNG5lwuLnTekXN/OazNYpf4CMd/HjZFXwcXRtTlzewJLc+/gox2IfByQRhsI/AgogRfYQKocZgFb/DOZoXR7wmIZGeunzwhqfmEtGiqpvJJQ5wVRdzJVpTnANBA5qxeA==]
  10.  
     

Debemos tener especial cuidado con las claves generadas con hiera-eyaml y administrar la información cifrada con nuestro gestor de claves favorito (KeepassX, Passpack, etc.) 
En conclusión podemos obtener varias ventajas de utilizar Hiera en combinación con hiera-eyaml, entre ellas:

  • Facilita la configuración de los distintos entornos: configuramos fácilmente datos por defecto con múltiples niveles de override.
  • Facilita la reutilización de los módulos públicos de Puppet: No edites el código, sólo coloca la información necesaria en Hiera.
  • Facilita la colaboración: No necesitas preocuparte de limpiar tu información antes de mostrar el módulo.

 
Saludos!

Categories
General Guide In detail

Primeros pasos de Puppet en Amazon EC2


Después de varias pruebas con Puppet, ir a la Puppet Camp, reuniones de la puppet-users-barcelona y la ayuda de la fabulosa gente del puppet-users-barcelona (https://groups.google.com/forum/?hl=en&fromgroups=#!forum/puppet-users-barcelona). Hemos creado esta pequeña introducción de una de las posibilidades de utilizar Puppet en Amazon EC2. Aunque Amazon hace poco lanzó el producto OpsWorks (https://aws.amazon.com/opsworks/) basado en Chef (http://finance.yahoo.com/news/amazon-services-chooses-opscode-chef-181000793.html). Por ahora, nosotros preferimos utilizar Puppet antes que Chef, porqué hay mucha documentación, mucha más comunidad y nos gusta más. Y por el momento vemos muchos más casos de éxitos de empresas importantes con Puppet que con Chef.  Ejemplo de Pinterest, Wuaki.tv, Zynga, etc.
Recomendamos leer alguna Introducción de como funciona Puppet antes de leer este POST. En Google se pueden encontrar muchos (http://www.ant30.es/2011/11/puppet-gestion-de-configuracion-centralizada/)

Escenario 1: Puppet Master como nodo central.

Recordad que Puppet se presenta en dos partes: un servidor (el Puppetmaster), que recibe las conexiones de los clientes y contiene los manifests, módulos, plantillas, archivos, etc. Y luego un programa cliente que se ejecuta en cada máquina bajo control de Puppet y que se conecta mediante intercambio de certificados al PuppetMaster para conseguir su manifests.

Paquetes a instalar:

Si queremos trabajar con un PuppetMaster y nodos de puppet conectándose al Puppet Master. Primero debemos instalar mediante nuestro sistema de paquetería de nuestro Sistema Operativo los paquetes “puppet” y “puppet-master” en la máquina elegida como servidor. Luego instalamos en cada nodo cliente el paquete “puppet”.
En el servidor:

# apt-get install puppetmaster puppet

En el cliente:

# apt-get install puppet

Resolución de nombres:

Una vez instalados los paquetes, tendremos que hacer una sencilla configuración de Puppet. Aunque antes tendremos que forzar a todas las máquinas que el nodo llamado “puppet” apunte a la IP del puppetmaster. Por eso lo podemos hacer mediante DNS y sinó podemos porqué nosotros no controlamos el DNS, lo podemos hacer modificando el fichero “/etc/hosts” de cada máquina que contenga Puppet.
Para eso editamos el “/etc/hosts” de todas nuestras máquinas. Si por ejemplo el puppet master tiene la IP 192.168.1.20 la cosa quedaría de la siguiente forma:

cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 machine
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.20 puppet

Si estuviésemos dentro del Puppetmaster lanzado el siguiente comando ya bastaría:

# echo `ifconfig eth0|grep addr|head -n 2|tail -n 1 |cut -d “:” -f 2 | cut -d ” ” -f 1` “puppet” >> /etc/hosts

Configuración:

Luego necesitamos editar 2 ficheros.
/etc/puppet/puppet.conf (en teoría ya viene por defecto configurado correctamente)
Miramos si existe el fichero /etc/puppet/autosign.conf, si no existe lo creamos.
Dentro del fichero /etc/puppet/autosign.conf solo hace falta que contenga una “*” que significa que toda petición de un nodo cliente que se conecte se autofirme para ahorrarnos hacerlo manualmente. Esto tiene inconvenientes de seguridad porqué todo nodo con visibilidad al PuppetMaster se podria connectar al él. Por lo tanto tendríamos que proteger la red de nodos no deseados (cerrando los puertos de Puppet). Con Security Groups de Amazon se puede solucionar o con un IP tables o con otros métodos. También podriamos configurar el PuppetMaster para firmar solo un cierto rango de IPs o ciertas máquinas que contengan estén en un subdominio de DNS. Aquí os recomendamos que busquéis en la documentación oficial de Puppet.
En este caso, el autosign.conf queda así:

# cat /etc/puppet/autosign.conf
“*”

Conexión de clientes:

Si acabamos de preparar el servidor Puppetmaster y queremos conectar un nodo cliente de puppet. Antes se tiene que pasar los certificados con el comando y con el mismo comando se lanza también el Puppet.

# puppet agent -t
 

 Si solo quisiesemos lanzar el nodo las veces que nosotros quisiesemos, por ejemplo al arrancar la máquina, y no mediante el demonio de Puppet. Tendríamos que apagar el demonio de Puppet y lanzar el siguiente comando:

# /usr/sbin/puppetd -t –onetime –no-daemonize (para arrancar una sola vez el Puppet y no dejarlo abierto funcionando cada 30 minutos)
 

También tenemos la forma de probar nuevas modificaciones de Puppet sin aplicar cambios mediante el siguiente comando. Es decir para poder debugar antes.

# puppet agent -t -noop
 
En el Puppetmaster para comprobar que esté todo bien, en el servidor podemos listar los nodos firmados y conectados usando el comando:

# puppet cert –list –all
En el caso que no tuviesemos puesto el método comentado anteriormente para firmar automáticamente, podemos firmar manualmente los nuevos nodos de puppet a conectarse al Puppetmaster, mediante el siguiente comando:

# puppet cert sign ec2-10-59-6-191.eu-west-1.compute.internal. 
 

En el Pupetmaster podemos revocar el certificado del nodo:

# puppet cert –revoke nodo1.example.com
 

Para limpiar el nodo.

# puppet cert –clean nodo1.example.com
 

O para limpiar todos los nodos.

# puppet cert –clean –all

Varias cosas a tener en cuenta.

– Este es un ejemplo de muchas posibles. Hay otras opciones de autoregistrar las máquinas en un DNS como el AWS Route 53.
– Si encontráis algún error o que falta algo o que nos hayamos dejado algo. O conoceis otras formas de trabajar con EC2, no dudéis en comentarlo en el grupo de CloudAdmins de LinkedIn.
– Cuando reiniciamos las máquinas virtuales de Amazon, o creamos una AMI, podemos perder el hostname correcto de la máquina. Por lo tanto, nosotros solemos poner en el rc.local , lo siguiente para que la máquina se encienda con el hostname adecuado.

cat /etc/rc.local
#!/bin/sh -e
hostname ec2-`ifconfig eth0|grep addr|head -n 2|tail -n 1 |cut -d “:” -f 2 | cut -d ” ” -f 1| sed ‘s/\./\-/g’`
/bin/hostname > /etc/hostname
echo “127.0.0.1 “`hostname` >> /etc/hosts

Escenario 2 : Sin nodo central Puppet Master. Todo en una sola máquina.

Mirar que fácil y que sencillo es con este método que utilizábamos en nuestros primeros tests.
Primero mediante “apt-get”, yum o equivalente instalamos el: git y puppetmaster.
# apt-get install puppetmaster git
Nos bajamos el código con nuestros manifests de Puppet. Por ejemplo con Git (también podriamos utilizar SVN, wget o lo que nos gusté más). En nuestro ejemplo:

# mkdir /code
# cd /code
# git clone gituser@server.net:/var/cache/git/code.git

Y luego lanzamos el puppet mediante:

# puppet agent -d /code/manifests/site.conf 
 

De esta forma la máquina hace de Puppetmaster y a la vez de cliente Puppet. Sin falta de firmar certificados y configuraciones complicadas. Lástima que aquí perdemos potencialidad de la que nos ofrece Puppet (guardar storeconfigs, los facters, etc.)
Estas 2 líneas las podríamos poner en nuestro “rc.local” del sistema operativo para que cada vez que arranque la máquina de Amazon EC2 se puppetize el entorno.
En este artículo queríamos dar las gracias a la gente de puppet-users-barcelona ( https://groups.google.com/forum/?hl=en&fromgroups=#!forum/puppet-users-barcelona ) por su ayuda, por la fabulosa PuppetCamp que organizaron y por las reuniones mensuales que hacen. Desde aquí os comentamos que es muy recomendado ir .

Referencias interesantes:

http://www.slideshare.net/roml/puppetcamp-15934250
http://kentbye.com/post/32415279029/how-pinterest-uses-amazon-ec2s-auto-scaling-features
http://www.slideshare.net/markstanislav/being-a-puppet-master-automating-amazon-ec2-with-puppet-friends

Categories
General Social

Chef, devops… future of system administration

Some thoughts for the holidays… Best Regards!  Cloudadmins team.
by Julian Dunn, 2012

Opscode Chef logoLast night, at a meeting of NYLUG, the New York City Linux Users’ Group, I watched Sean O’Meara whip through a presentation about Chef, the system configuration management (CM) tool. I was impressed. The last time(s) I tried to play with automation tools like cfengine and Puppet I got very frustrated at their complexity. The folks at Opscode have definitely succeeded at bringing simplicity (as much as can be had) to the CM space.
But what struck me after hearing Sean had nothing to do with Chef. Instead, I came to the conclusion that pure systems administration is eventually going to die out as a profession. The developer is now king (or queen), and that’s not a bad thing.
Let’s step back for a minute and talk about CM tools in general. Traditional CM tools — to the extent that they existed before cfengine et. al. – know nothing about the underlying semantics of what you ask them to do. At CBC, we had a set of elaborate shell and Perl scripts that were written in-house, collectively known as ASC, Application Server Control, to do so-called configuration management of the origin infrastructure. ASC’s sole job was to revision control configurations, perform deploy and rollback operations, and perhaps do some auditing. But it was prescriptive, not descriptive. Most of the time I spent monkeying with ASC was debugging how it was doing things.
Enter Chef (or Puppet, LCFG, cfengine, BCFG2; pick your poison). These are all configuration management tools that allow you to describe your infrastructure  in a fourth-generation language (4GL) way. You describe the features that certain hosts should have, and the tools, using canned recipes, makes it happen. (“Make me a MySQL server,” for instance.) Another advantage of these tools is that they (can) keep track of the state of your infrastructure, and you can query that database to make decisions about new deployments. “How many MySQL servers do I have?” for example. Or even “Which node is the MySQL master?” and then kicking off another job on a new MySQL slave to automatically start replicating from the right server.
Had it not been for the development of IaaS — infrastructure as a service — everything that I’ve told you would not be particularly noteworthy. But IaaS, or “cloud computing”, now allows anyone to provision new (virtual) servers inexpensively. No more waiting around for the system administrator to order a couple servers from Dell, wait a few weeks for them to arrive, rack them up, configure them, etc. Developers, armed with a tool like Chef and its huge cookbook of canned recipes for making many standard infrastructure components, can fire up everything they need to support their application themselves. Therein lies the demise of system administration as a standalone profession and the rise of “devops”.
I admit that when I first heard the concept of “devops”, I snickered. “Give developers the keys to the infrastructure and they’ll surely break it beyond repair and expect the sysadmins to fix it,” I thought. But it’s finally dawned on me that “devops” isn’t just some buzzword concept that someone has thought up to make sysadmins’ lives hell. It’s the natural evolution of both professions. By bringing development and system administration closer together, it does two things. First, it makes developers operationally accountable for their code, because they are the ones that get paged in the middle of the night, not some “operations team” upon whom they can offload that responsibility. And secondly, it makes those on the systems side of the house better at their jobs, because they can use newly-acquired programming skills to manage infrastructure resources in a more natural way.
So will IaaS and sophisticated configuration management tools kill the system administrator? I believe so — but that’s not a bad thing. System administrators have got to stop thinking of servers/disk/memory/whatever as “their resources” that “they manage”. Cloud computing has shown us that all of that stuff is just a service, dedicated to nothing more than serving up an application, which is what really matters. If sysadmins want to remain relevant, they’ll get on board and start learning a bit more about programming.
Source: http://www.juliandunn.net/2012/01/13/chef-devops-and-the-death-of-system-administration/