Guardando nuestros secretos en Vault (2 de 2)

Hoy vamos a seguir hablando de secretos y Vault, realizando una configuración real del servidor y afianzando parte de lo que hablamos en el anterior post.

Haciendo Vault persistente

Tal como comentamos en el post anterior, el modo “-dev” de Vault sirve para hacer pruebas, y cualquier secreto y configuración que hagamos se pierde cuando el servicio se para. Por lo tanto, vamos a realizar una configuración persistente del servicio.

 

Antes de empezar

Como ya vimos, de momento no existen paquetes para Vault, por lo que tenemos que instalar el binario, y elegimos dejarlo en /usr/local/sbin . Ahora necesitamos crear los directorios donde se guardará el fichero de configuración y los propios datos cifrados:

 

Cifrando la comunicación con Vault

Toda comunicación con Vault tiene que ir cifrada, ya que no tendría mucho sentido que fuese en texto plano a través de la red. Vamos a generar un certificado auto-firmado para el servidor de Vault, el cual tiene que incluir SubjectAlternativeNames (SAN), algo que exige modificaciones del fichero /etc/ssl/openssl.cnf y que haremos creando un fichero aparte en /etc/vault/openssl.cnf 

Como podéis apreciar, en el apartado “[alt_names]” hemos puesto los DNS y las IPs con las que accederemos al servicio.

Generamos la CA para Vault y el certificado dentro del directorio /etc/vault/ssl:

Y podemos ver cómo se han añadido al certificado los SubjectAlternativeNames:

 

Configuración de Vault

Ahora es cuando vamos a crear la configuración que utilizará Vault cuando arranquemos el servicio. El fichero de configuración es de tipo HCL, un formato muy parecido a JSON. Creamos el fichero /etc/vault/vault-server.hcl con el siguiente contenido:

Vamos a destacar:

  • storage: vamos a hacer uso del tipo de storage “file“, para almacenar los secretos en el disco duro del servidor. Existen más tipos de almacenamientos donde guardar los secretos, como por ejemplo, MySQL, Consul, AWS…
  • listener: todo lo referente al puerto de escucha del servicio y los certificados generados en el paso anterior.

 

Servicio de arranque

Como no hemos instalado Vault por paquetes, no tenemos la manera de arrancarlo automáticamente en caso de reinicio del servidor, por lo que vamos a generar el fichero de arranque para Systemd en /lib/systemd/system/vault-server.service.

Y para que sea efectivo tenemos que indicar que el servicio debe arrancar automáticamente:

El último comando nos debería mostrar cómo el servicio ha arrancado de manera correcta.

 

Inicializando Vault

En el post anterior explicamos cómo funciona Vault de manera interna, y cómo es necesario generar la clave de cifrado, junto con la clave maestra y se generan varias claves compartidas. Como hicimos uso del modo “-dev” todos estos pasos nos los ahorramos, ya que se generaban automáticamente, pero ahora es el momento de hacerlo.

Tenemos que realizar la exportación de un par de variables. La primera es para indicar en qué IP y puerto está escuchando Vault. La segunda sirve para ignorar que el certificado es auto-firmado y no verifica si está firmado por una empresa de certificación:

Y nos sacará un mensaje como el siguiente:

Acabamos de hacer lo que se muestra en la imagen anterior, generar la clave de cifrado, se ha generado la clave maestra y nos muestra las 5 claves compartidas que deberemos guardar. Tal como nos dicen, serán necesarias 3 para desprecintar Vault. Es importante guardar estas claves de manera correcta, porque sin ellas, si Vault se sella, no podremos volver a acceder a los datos.

También nos muestra un token de Root para que podamos hacer configuraciones mediante la API o empezar a crear secretos como ya vimos.

 

Desprecintando Vault

Si ahora comprobamos el “status” de Vault veremos que sigue sellado. Por lo tanto vamos a repetir 3 veces el siguiente comando introduciendo cualquiera de las 5 “Unseal Keys” que tenemos:

Y al introducir la tercera si miramos el estado:

Ya tenemos Vault desellado a la espera de introducir secretos, pero para ello nos tendremos que autenticar con el token de root:

 

Auditando los accesos

Para tener controlados los accesos podemos activar el sistema de auditoría, el cual crea logs de todos los accesos realizados. Vamos a hacer que nos genere logs en /var/log/vault_audit.log

 

Autenticación y políticas de acceso

Hasta ahora, todo lo que hemos realizado es con el token de root, pero como todos sabemos: “un gran poder lleva una gran responsabilidad” (TM), por lo que vamos a añadir un sistema de autenticación para usuarios, con sus correspondientes políticas de acceso.

Al igual que con los backends de almacenamiento, en Vault existen varias alternativas para el sistema de autenticación: LDAP, usuario y password, Github

Para este post vamos a usar la autenticación de “usuarios y contraseñas“, por ser el más sencillo y no depender de ningún servicio externo, ya que en este caso todo se guarda en Vault. En la siguiente imagen se explica cómo funciona la autenticación contra un LDAP, pero el workflow es el mismo para cualquiera de los sistemas permitidos.

Creando backend de autenticación

Vamos a crear dos usuarios para las pruebas de concepto, pero primero tenemos que habilitar el sistema de autenticación:

Como se puede ver, aparte de crear los usuarios, a cada uno le hemos dado un parámetro “policies” o política de acceso que todavía no hemos creado. Luego veremos cómo funcionan, pero primero vamos a loguearnos con un usuario:

El mensaje que nos muestra es bastante autoexplicativo:

  • Nos hemos logueado de manera correcta.
  • Nos ha generado un token y nos lo ha guardado en la sesión, por lo que no tenemos que autenticarnos de nuevo con el token. Ahora mismo, en esta shell, somos user1.
  • La duración del token es de 10799 segundos. Esto son 3 horas, que es lo que hemos puesto en el fichero de configuración más arriba: default_lease_ttl = “3h” . Esto sirve para que los tokens expiren y no sean perpetuos. Entra en vuestro criterio si es mucho tiempo o poco.
  • Políticas del token: siempre nos añade a la política “default”, y aparte a la de “admins” que es la que hemos añadido nosotros al crear el usuario.

Si quisiésemos autenticarnos con curl:

Como ya comentamos en el anterior post, todo en Vault se puede acceder por la API, y la autenticación no iba a ser menos. Al autenticarnos, hemos generado un nuevo token, con sus permisos correspondientes.  Este no invalida el otro, pero cada uno tiene su tiempo de expiración propio.

 

Políticas de acceso (policies)

Hasta ahora no hemos comentado, pero en Vault todo está basado en “paths”. Como se puede ver, el sistema de autenticación está dentro del path “auth/”, en el anterior post vimos que los secretos los guardamos en “secret/”… Las “policies” es la manera de dar permisos a los paths dentro de Vault. Existen los siguientes permisos:

  • create: Permite crear datos dentro del path indicado.
  • read: Permite leer datos en el path.
  • update: Permite actualizar datos. En gran parte del sistema de Vault no existe distinción entre “update” y “create”, por lo que si no existen los datos al hacer “update”, los crea.
  • delete: Permite borrar los datos del path especificado.
  • list: Permite listar los datos dentro de un path. Especialmente útil para listar secretos dentro de un “directorio”.
  • sudo: Tal como pasa en Linux, permite acceso a los paths que están protegidos sólo para root. El token debe de tener permisos de sudo.
  • deny: Deniega el acceso. Siempre tiene precedencia sobre el resto y es el permiso por defecto para todos los paths.

Con esto, vamos a crear las dos políticas expuestas antes en los usuarios. Para ello, vamos a crear un fichero para cada una de las políticas de acceso. En /etc/vault/policies/admins.hcl

Y la política para usuarios normales en /etc/vault/policies/users.hcl :

Y ahora vamos a cargar las políticas, pero acuérdate que tienes que estar autenticado como root, no como user1 😉

Os dejo como deberes que hagáis las siguientes pruebas teniendo en cuenta este post y el anterior para crear secretos:

  1. Crear un secreto en “secret/secreto1” y en “secret/admins/privado1” con los valores que queráis.
  2. Loguearos con el token de root y leer ambos secretos.
  3. Loguearos con el token de “user1” y leer ambos secretos.
  4. Autenticaros con el “user2” e intentad leer “secret/admins/privado1” o listar dentro de “secret/admins”. Deberíais tener el siguiente error:

En la documentación oficial se explican más opciones acerca de las políticas de acceso, y con ejemplos a través de la API.

Por cierto, tras todos estos pasos, deberíais echar un ojo a /var/log/vault_audit.log, que tal como hemos comentado, nos sirve para auditar los accesos que ha habido.

 

Resumen

Con este post hemos querido mostraros un poco más el mundo de Vault, pero la verdad es que nos hemos dejado bastantes cosas en el tintero, como son la creación de distintos backends de autenticación tan interesantes como el de SSH, montar un sistema en alta disponibilidad, ver alguno de los interfaces gráficos que existen…

Si tenéis alguna duda o queréis que hagamos un nuevo post ahondado más en el tema dejadnos un comentario 😀 y nos pondremos a ello.



¿Te gusta este post? Es solo un ejemplo de cómo podemos ayudar a tu empresa...
Sobre Rubén Gómez Olivencia

De programador a administrador de sistemas... Algunos dirán que tengo personalidad múltiple developer-bofh, pero ¿quién no tiene taras mentales? :P

Queremos tu opinión :)