En este post, vengo a presentaros una herramienta que ha causado mucha expectación que ayuda a complementar el movimiento DevOps y Seguridad haciendo que todos los secretos no estén en el servicio si no en un sitio centralizado. Esta herramienta, se llama Vault y es de la empresa HashiCorp. Esta empresa, tiene varias herramientas muy interesantes como; Consul, Packer, Terraform.. Recomiendo echarles un vistazo.
No quiero meterme mucho en la teoría ya que hay varios posts que explican mejor (abajo os dejo algunos de referencia). Pero básicamente es un servicio que alberga secretos portegidos por PGP que permiten ser consultados mediante una API del modo que no hay que declararlos en el propio servicio.
En este ejemplo, vamos a montarlo sobre docker (oh que sorpresa!). Y como backend para almacenar los secretos, utilizaremos consul. Para esto, como siempre utilizaremos: docker-compose y traefik.
Docker-compose
vim docker-compose.yml
version: '3.5' services: vault: image: vault restart: always container_name: vault volumes: - file:/vault/file - logs:/vault/logs - ./config/policies:/vault/policies cap_add: - IPC_LOCK environment: VAULT_LOCAL_CONFIG: '{"backend": {"consul": {"path": "vault/", "address": "consul:8500", "scheme": "http"}}, "listener": {"tcp": {"address": "0.0.0.0:8200", "tls_disable": 1}}, "default_lease_ttl": "168h", "max_lease_ttl": "720h", "ui": true}' VAULT_ADDR: http://127.0.0.1:8200 networks: - net - traefik command: server depends_on: - consul labels: - "traefik.backend=vault" - "traefik.frontend.rule=Host:vault.example.com" - "traefik.docker.network=traefik" - "traefik.port=8200" consul: image: consul container_name: consul restart: always command: agent -server -bind 0.0.0.0 -data-dir=/consul/data -client 0.0.0.0 -bootstrap-expect=1 networks: - net volumes: - consul1:/consul/data healthcheck: test: ['CMD', '/bin/sh', '-c', 'curl -sfLo /dev/null http://127.0.0.1:8500/v1/health/node/$HOSTNAME'] volumes: file: logs: consul: networks: net: traefik: external: name: traefik
Levantar el stack
docker-compose up -d
vault | Api Address: http://172.19.0.2:8200 vault | Cgo: disabled vault | Cluster Address: https://172.19.0.2:8201 vault | Listener 1: tcp (addr: "0.0.0.0:8200", cluster address: "0.0.0.0:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled") vault | Log Level: info vault | Mlock: supported: true, enabled: true vault | Storage: consul (HA available) vault | Version: Vault v1.1.2 vault | Version Sha: 0082501623c0b704b87b1fbc84c2d725994bac54
Iniciar vault
Nota: Si queremos conectarnos desde un host externo, hay que configurar la siguiente variable:
export VAULT_ADDR=https://vault.example.com
Una vez iniciado, nos mostrará varias Keys para desbloquear vault. Por defecto viene bloqueado. Aparte de las Keys nos dará el token de root que es necesario para crear la configuración.
docker exec -it vault vault operator init
Unseal Key 1: AnvbKvub4vWZ8PcjWSCGO+Wqoe165sI6gc5Q0dJr4Sb5 Unseal Key 2: vvz/FqHo3TE8dW8LQNIrU4dt0L2iIynhOJzdjjWZ3H+h Unseal Key 3: SS5eAnYBM0YPjKnS9kIftaGq95QWva4Lo0tEvZqZ3vj/ Unseal Key 4: Z8v06Mk5eHEBcNFADLFqHMvMPktrGDgIaEFFCViW0r4P Unseal Key 5: CQ8PmG0xf5MzrjyQwBK4AsLdSz9Dg7GGPYprj6dNZbmz Initial Root Token: s.TsEFCD3LVDwquUblsmPFD8Rg
Desbloquear Vault
Una vez iniciado Vault, hay que desbloquearlo. Para esto, se necesitan 3 de las 5 claves de Unseal que nos mostró anteriormente. Se pueden usar cualquiera de ellas
docker exec -it vault vault operator unseal Unseal Key (will be hidden):
Key Value --- ----- Seal Type shamir Sealed true Total Shares 5 Threshold 3 Unseal Progress 1/3 Unseal Nonce a1a4f8ac-2a82-70ea-b333-a341533d2265 Version 0.10.1 HA Enabled true
docker exec -it vault vault operator unseal Unseal Key (will be hidden):
Key Value --- ----- Seal Type shamir Sealed true Total Shares 5 Threshold 3 Unseal Progress 2/3 Unseal Nonce a1a4f8ac-2a82-70ea-b333-a341533d2265 Version 0.10.1 HA Enabled true
docker exec -it vault vault operator unseal Unseal Key (will be hidden):
Key Value --- ----- Seal Type shamir Sealed false Total Shares 5 Threshold 3 Version 0.10.1 Cluster Name vault-cluster-1805cfbc Cluster ID ee3dc20e-e40c-c717-0025-544c6bd2cd71 HA Enabled false
Configuración
Para empezar, hay que autenticarse como root para poder comenzar a configurarlo. Para esto, necesitamos el Token de root que nos ha aparecido antes.
docker exec -it vault vault login
Key Value --- ----- token s.TsEFCD3LVDwquUblsmPFD8Rg token_accessor CNjpS8D3ElE4tIwgygKmYsdo token_duration ∞ token_renewable false token_policies ["root"] identity_policies [] policies ["root"]
Logs
Es recomendable habilitar los logs para poder tener un registro de lo que está pasando y quien accede a los secretos. Este log se guardará en el volumen que hemos mapeado previamente.
docker exec -it vault vault audit enable file file_path=/vault/logs/vault_audit.log
Políticas
Crear políticas
Para las políticas, hemos mapeado anteriormente (en el docker-compose) una carpeta desde ./config/policies que albergará todas las políticas que creemos. De este modo, si el contenedor se borra, los ficheros de las políticas seguirán existiendo. En este caso vamos a crear 2 políticas. Una será para admin con permiso para todo y la otra para usuarios mas restringida.
mkdir ./config/policies
Admin
vim ./config/policies/admin.hcl
path "*" { capabilities = ["create", "read", "update", "delete", "list", "sudo"] }
User
vim ./config/policies/user.hcl
path "secret/*" { capabilities = ["read", "update", "list"] } path "secret/admin" { capabilities = ["deny"] } path "sys/mounts" { capabilities = [ "read" ] } path "sys/auth" { capabilities = [ "read" ] }
Aplicar políticas
docker exec -it vault vault policy write admin /vault/policies/admin.hcl
docker exec -it vault vault policy write user /vault/policies/user.hcl
Autenticación
La autenticación de los usuarios, puede se por distintos modos; github, ldap, userpass.. En este caso, vamos a utilizar la última opción, userpass por lo que hay que hay que habilitar este método y crear los usuarios en vault
Habilitar autenticación de usuario
docker exec -it vault vault auth enable userpass
Crear usuarios
Usuario admin:
docker exec -it vault vault write auth/userpass/users/admin password=S3cr3t policies=admin
Usuario normal:
docker exec -it vault vault write auth/userpass/users/user password=S3cr3t1 policies=user
Probar el usuario en la consola
docker exec -it vault vault login -method=userpass username=admin password=S3cr3t
Key Value --- ----- token s.IrTfojMb5CryYG2n3kMChTDn token_accessor zIwzjwxtkMr83G7CrEZkt9jN token_duration 168h token_renewable true token_policies ["admin" "default"] identity_policies [] policies ["admin" "default"] token_meta_username admin
Probar el usuario por la API
curl -k https://vault.example.com/v1/auth/userpass/login/admin -d '{ "password": "S3cr3t" }'
{ "request_id": "22431a91-7ebe-17b2-d170-bcd639a39a2a", "lease_id": "", "renewable": false, "lease_duration": 0, "data": null, "wrap_info": null, "warnings": null, "auth": { "client_token": "s.zPNwyG26ZVYCNAaHZpkr0AED", "accessor": "tr2xUEB4P3iVoy0bQXFnZU0k", "policies": [ "admin", "default" ], "token_policies": [ "admin", "default" ], "metadata": { "username": "admin" }, "lease_duration": 604800, "renewable": true, "entity_id": "b0017de2-d2ed-7757-706b-1b6bf920f1d4", "token_type": "service", "orphan": true } }
Backends
Los backends son las “ubicaciones” donde podremos almacenar las keys
Listar los backends habilitados
docker exec -it vault vault secrets list
Path Type Accessor Description ---- ---- -------- ----------- cubbyhole/ cubbyhole cubbyhole_aa560446 per-token private secret storage identity/ identity identity_f7242aa5 identity store sys/ system system_cdb394e2 system endpoints used for control, policy and debugging test/ kv kv_19bb74c6 esto es un test
Crear un backend nuevo
Hay diferentes tipos de backends. Mas info aquí
docker exec -it vault vault secrets enable -path=test -description="esto es un test" kv
Crear keys
docker exec -it vault vault write test/user user_key=supersecret docker exec -it vault vault write test/admin admin_key=supersecret
Listar las keys
docker exec -it vault vault list test/
Keys ---- admin user
Leer la key creada
docker exec -it vault vault read test/admin
Key Value --- ----- refresh_interval 168h admin_key supersecret
Listar las keys utilizando la API
curl -H "X-Vault-Token: s.JWDBOiIZQnnn9ze2iW0bUSOg" -X LIST https://vault.example.com/v1/test/ -s | jq
{ "request_id": "2ee4517c-d79e-8270-103a-1fbf8bf0cd96", "lease_id": "", "renewable": false, "lease_duration": 0, "data": { "keys": [ "admin", "user" ] }, "wrap_info": null, "warnings": null, "auth": null }
Ver las keys utilizando la API
curl -H "X-Vault-Token: s.JWDBOiIZQnnn9ze2iW0bUSOg" -X GET https://vault.example.com/v1/test/admin -s | jq
{ "request_id": "5c361926-be89-1a9f-6256-18a95b33f1ed", "lease_id": "", "renewable": false, "lease_duration": 604800, "data": { "admin_key": "supersecret" }, "wrap_info": null, "warnings": null, "auth": null }
UI Web
Una vez añadido en la configuración de Vault el UI a true se podrá acceder a la web mediante la siguiente URL:
https://vault.example.com/ui
De momento esto es todo. En un futuro, iré añadiendo mas posts de como conectar diferentes servicios con Vault según vaya profundizando en la materia.
Post para echar un ojo:
https://blog.irontec.com/guardando-nuestros-secretos-en-vault-1-de-2/
https://blog.irontec.com/guardando-nuestros-secretos-en-vault-2-de-2/
https://www.vaultproject.io/docs/
Also published on Medium.
One comment