Instalación y Configuración de HashiCorp Vault
HashiCorp Vault es la solución de referencia para gestión centralizada de secretos, permitiendo almacenar, generar y controlar el acceso a tokens, contraseñas, certificados y claves de cifrado con un registro de auditoría completo. Su modelo de políticas granulares y los múltiples métodos de autenticación lo hacen adecuado tanto para entornos pequeños como para grandes infraestructuras multi-tenant. Esta guía cubre la instalación de Vault en Linux, inicialización, motores de secretos y configuración de alta disponibilidad.
Requisitos Previos
- Servidor Linux (Ubuntu 22.04/Debian 12 o CentOS 9/Rocky 9)
- Mínimo 2 GB de RAM (4 GB para producción)
- Almacenamiento persistente (disco SSD recomendado para Raft)
- Certificado TLS válido para el dominio de Vault
- Para HA: 3 nodos mínimo
Instalación de Vault
# Añadir repositorio HashiCorp (Ubuntu/Debian)
wget -O- https://apt.releases.hashicorp.com/gpg | \
gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
tee /etc/apt/sources.list.d/hashicorp.list
apt-get update && apt-get install -y vault
# CentOS/Rocky Linux
dnf config-manager --add-repo \
https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
dnf install -y vault
# Verificar la instalación
vault version
# Crear directorios de datos y configuración
mkdir -p /opt/vault/data /etc/vault.d /var/log/vault
useradd -r -d /opt/vault -s /bin/false vault
chown vault:vault /opt/vault/data /var/log/vault
chmod 700 /opt/vault/data
Configuración de Almacenamiento
Vault soporta múltiples backends de almacenamiento. Para producción se recomienda Raft integrado:
cat > /etc/vault.d/vault.hcl << 'EOF'
# Dirección de escucha con TLS
ui = true
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/etc/vault.d/tls/vault.crt"
tls_key_file = "/etc/vault.d/tls/vault.key"
tls_min_version = "tls12"
}
# Backend de almacenamiento Raft integrado (recomendado para HA)
storage "raft" {
path = "/opt/vault/data"
node_id = "vault-01" # Único por nodo
}
# URL de la API (debe coincidir con el nombre del certificado TLS)
api_addr = "https://vault.tudominio.com:8200"
cluster_addr = "https://10.0.1.10:8201"
# Desactivar la memoria de secretos en swap
disable_mlock = false
# Logging
log_level = "info"
log_file = "/var/log/vault/vault.log"
# Telemetría Prometheus
telemetry {
prometheus_retention_time = "30s"
disable_hostname = true
}
EOF
# Generar certificado TLS auto-firmado para pruebas
mkdir -p /etc/vault.d/tls
openssl req -x509 -nodes -newkey rsa:4096 -keyout /etc/vault.d/tls/vault.key \
-out /etc/vault.d/tls/vault.crt -days 365 \
-subj "/CN=vault.tudominio.com" \
-addext "subjectAltName=DNS:vault.tudominio.com,IP:10.0.1.10"
chown vault:vault /etc/vault.d/tls/vault.key
chmod 600 /etc/vault.d/tls/vault.key
Crea el servicio systemd:
cat > /etc/systemd/system/vault.service << 'EOF'
[Unit]
Description=HashiCorp Vault - Secrets Management
Documentation=https://www.vaultproject.io/docs/
Requires=network-online.target
After=network-online.target
ConditionFileNotEmpty=/etc/vault.d/vault.hcl
StartLimitIntervalSec=60
StartLimitBurst=3
[Service]
Type=notify
User=vault
Group=vault
ProtectSystem=full
ProtectHome=read-only
PrivateTmp=yes
PrivateDevices=yes
SecureBits=keep-caps
AmbientCapabilities=CAP_IPC_LOCK
CapabilityBoundingSet=CAP_SYSLOG CAP_IPC_LOCK
NoNewPrivileges=yes
ExecStart=/usr/bin/vault server -config=/etc/vault.d/vault.hcl
ExecReload=/bin/kill --signal HUP $MAINPID
KillMode=process
KillSignal=SIGINT
Restart=on-failure
RestartSec=5
TimeoutStopSec=30
LimitNOFILE=65536
LimitMEMLOCK=infinity
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now vault
Inicialización y Unseal
La inicialización de Vault genera las claves para el proceso de unseal y el token raíz:
# Configurar la variable de entorno de la dirección de Vault
export VAULT_ADDR="https://vault.tudominio.com:8200"
export VAULT_CACERT="/etc/vault.d/tls/vault.crt"
# Inicializar Vault (SOLO UNA VEZ en el primer nodo)
# -key-shares: número de fragmentos de la clave maestra
# -key-threshold: mínimo de fragmentos necesarios para unseal
vault operator init -key-shares=5 -key-threshold=3
# CRÍTICO: Guarda las 5 Unseal Keys y el Initial Root Token en un lugar seguro
# (gestión de claves fuera de banda: USB cifrado, HSM, o Vault Enterprise Auto-Unseal)
# Proceso de unseal (necesita 3 de las 5 claves)
vault operator unseal # Introducir Unseal Key 1
vault operator unseal # Introducir Unseal Key 2
vault operator unseal # Introducir Unseal Key 3
# Verificar el estado de Vault
vault status
# Autenticarse con el root token (solo para configuración inicial)
vault login # Introducir el Initial Root Token
# Crear un token de administrador con políticas en lugar de usar root
vault token create -policy="admin" -ttl=8h
Motores de Secretos
Vault organiza los secretos en "motores" montados en rutas:
# Motor KV versión 2 (secretos estáticos con historial de versiones)
vault secrets enable -path=secret kv-v2
# Guardar y leer secretos
vault kv put secret/webapp/database \
url="postgresql://db:5432/webapp" \
username="webapp_user" \
password="$(openssl rand -base64 32)"
vault kv get secret/webapp/database
vault kv get -field=password secret/webapp/database
# Ver versiones anteriores
vault kv history secret/webapp/database
vault kv get -version=1 secret/webapp/database
# Motor de credenciales dinámicas para bases de datos
vault secrets enable database
# Configurar conexión a PostgreSQL
vault write database/config/webapp-postgres \
plugin_name=postgresql-database-plugin \
allowed_roles="webapp-readonly,webapp-readwrite" \
connection_url="postgresql://{{username}}:{{password}}@10.0.3.10:5432/webapp" \
username="vault_admin" \
password="password_vault_admin"
# Crear rol con privilegios limitados
vault write database/roles/webapp-readonly \
db_name=webapp-postgres \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
default_ttl="1h" \
max_ttl="24h"
# Generar credenciales temporales
vault read database/creds/webapp-readonly
# Las credenciales expiran automáticamente tras 1 hora
# Motor PKI para emisión de certificados TLS
vault secrets enable pki
vault secrets tune -max-lease-ttl=87600h pki
vault write pki/root/generate/internal \
common_name="Empresa CA" \
ttl=87600h
vault write pki/roles/servidor \
allowed_domains="empresa.local" \
allow_subdomains=true \
max_ttl=720h
# Emitir un certificado
vault write pki/issue/servidor \
common_name="web.empresa.local"
Métodos de Autenticación
# Autenticación con AppRole (para aplicaciones y automatización)
vault auth enable approle
vault write auth/approle/role/webapp \
secret_id_ttl=24h \
token_num_uses=0 \
token_ttl=1h \
token_max_ttl=4h \
policies="webapp-policy"
# Obtener el Role ID y Secret ID para la aplicación
vault read auth/approle/role/webapp/role-id
vault write -f auth/approle/role/webapp/secret-id
# Autenticar con AppRole
vault write auth/approle/login \
role_id="<role-id>" \
secret_id="<secret-id>"
# Autenticación con Kubernetes ServiceAccounts
vault auth enable kubernetes
vault write auth/kubernetes/config \
kubernetes_host="https://10.0.0.1:6443" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
# Autenticación LDAP/AD
vault auth enable ldap
vault write auth/ldap/config \
url="ldaps://ldap.empresa.local:636" \
userdn="ou=users,dc=empresa,dc=local" \
groupdn="ou=groups,dc=empresa,dc=local" \
binddn="cn=vault-reader,ou=service-accounts,dc=empresa,dc=local" \
bindpass="password_cuenta_servicio"
Políticas de Acceso
# Crear política para la aplicación webapp
cat > /tmp/webapp-policy.hcl << 'EOF'
# Leer secretos de la aplicación webapp
path "secret/data/webapp/*" {
capabilities = ["read", "list"]
}
# Generar credenciales dinámicas de base de datos
path "database/creds/webapp-readonly" {
capabilities = ["read"]
}
# Renovar tokens propios
path "auth/token/renew-self" {
capabilities = ["update"]
}
EOF
vault policy write webapp-policy /tmp/webapp-policy.hcl
# Política de administración del sistema
cat > /tmp/admin-policy.hcl << 'EOF'
path "*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
EOF
vault policy write admin /tmp/admin-policy.hcl
Alta Disponibilidad con Raft
# En el segundo y tercer nodo, después de instalar y configurar vault.hcl
# (ajustar node_id y cluster_addr por nodo)
# Unirse al clúster existente
export VAULT_ADDR="https://10.0.1.11:8200"
vault operator raft join https://vault.tudominio.com:8200
# Hacer unseal del nuevo nodo con 3 de las 5 claves
vault operator unseal
vault operator unseal
vault operator unseal
# Ver los peers del clúster Raft (desde cualquier nodo con el token root o admin)
vault operator raft list-peers
# Ver el estado de HA
vault status | grep -E "HA|Leader"
Solución de Problemas
# Ver logs del servicio
journalctl -u vault -f
# Estado detallado de Vault
vault status
# Verificar si el token actual tiene acceso a una ruta
vault token capabilities secret/data/webapp/database
# Debug de políticas
vault write sys/capabilities-self paths="secret/data/webapp/database"
# Ver el registro de auditoría (activar primero)
vault audit enable file file_path=/var/log/vault/audit.log
tail -f /var/log/vault/audit.log | python3 -m json.tool
# Vault sellado por reinicio del sistema: ejecutar unseal automático con Autounseal
# (configurar con AWS KMS, Azure Key Vault, GCP KMS o Transit engine)
# En vault.hcl:
# seal "awskms" {
# region = "us-east-1"
# kms_key_id = "alias/vault-unseal-key"
# }
Conclusión
HashiCorp Vault transforma la gestión de secretos de un problema disperso y difícil de auditar en un sistema centralizado, con control de acceso granular y registro completo de operaciones. Las credenciales dinámicas con TTL corto y la revocación automática reducen drásticamente la superficie de ataque respecto a secretos estáticos en archivos de configuración, haciendo de Vault una pieza fundamental en cualquier estrategia de seguridad para infraestructuras modernas.


