Vault hashicorp

Vault es una herramienta que sirve para almacenar y controlar el acceso a tokens, contraseñas, certificados, claves de cifrado y otros datos confidenciales.

Características

Instalación

history -c
echo "set +o history" >> ~/.bashrc
unzip vault-XYZ.zip
chown root:root vault
mv vault /usr/local/bin/
rm -f vault-XYZ.zip
vault -autocomplete-install
sudo mkdir /etc/vault
sudo mkdir -p /var/lib/vault/data
sudo useradd --system --home /etc/vault --shell /bin/false vault
sudo chown -R vault:vault /etc/vault /var/lib/vault/
cat <<EOF | sudo tee /etc/systemd/system/vault.service
[Unit]
Description="HashiCorp Vault - A tool for managing secrets"
Documentation=https://www.vaultproject.io/docs/
Requires=network-online.target
After=network-online.target
ConditionFileNotEmpty=/etc/vault/config.hcl

[Service]
User=vault
Group=vault
ProtectSystem=full
ProtectHome=read-only
PrivateTmp=yes
PrivateDevices=yes
SecureBits=keep-caps
AmbientCapabilities=CAP_IPC_LOCK
NoNewPrivileges=yes
ExecStart=/usr/local/bin/vault server -config=/etc/vault/config.hcl
ExecReload=/bin/kill --signal HUP 
KillMode=process
KillSignal=SIGINT
Restart=on-failure
RestartSec=5
TimeoutStopSec=30
StartLimitBurst=3
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF
cat <<EOF | sudo tee /etc/vault/config.hcl
disable_cache = true
disable_mlock = true
ui = false
plugin_directory="/etc/vault/plugins"
listener "tcp" {
   address          = "0.0.0.0:8200"
   tls_cert_file = "/etc/letsencrypt/live/entidad.gob.bo/cert.pem"
   tls_key_file  = "/etc/letsencrypt/live/entidad.gob.bo//privkey.pem"
}
storage "file" {
   path  = "/var/lib/vault/data"
 }
api_addr         = "https://0.0.0.0:8200"
max_lease_ttl         = "10h"
default_lease_ttl    = "10h"
cluster_name         = "vault"
raw_storage_endpoint     = true
disable_sealwrap     = true
disable_printable_check = true
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now vault
systemctl status vault

Iniciando el servidor

Vault es una herramienta cliente-servidor que consta de un componente de cliente que utilizan los desarrolladores para las aplicaciones y un componente de servidor que se encarga de proteger los datos en servidores remotos.

export VAULT_ADDR=https://127.0.0.1:8200
echo "export VAULT_ADDR=https://127.0.0.1:8200" >> ~/.bashrc
sudo rm -rf  /var/lib/vault/data/*
vault operator init -key-shares=4 -key-threshold=3

El comando generara las 4 llaves compartidas que deberán ser entregadas a diferentes personas para poder “abrir” vault y tener acceso a los datos privados que se almacenen en ella. Las personas a cargo de la custodia de estas llaves compartidas deberán almacenarlas de manera segura usando PGP (Pretty Good Privacy), pueden usar un servicio como https://keybase.io

vault operator unseal
vault login <<token root>> 
vault audit enable syslog tag="vault" facility="AUTH"
apt-get install syslog-ng
source s_net { udp(ip(0.0.0.0) port(514)); };
filter f_vault { host( "0.0.0.0" ); };
destination df_vault { file("/var/log/vault.log"); };
log { source ( s_net ); filter( f_vault ); destination ( df_vault ); };

Almacenamiento de datos privados

vault secrets enable -version=1 kv
vault secrets list 
vault kv put kv/apikey/Google llave=AAaaBBccDDeeOTXzSMT1234BB_Z8JzG7JkSVxI
vault kv get kv/apikey/Google

Código de ejemplo de una aplicación en python que se comunica con Vault usando un token para obtener el API key:

        response = requests.get(
        'https://127.0.0.1:8200/v1/kv/apikey/Google',
        params={'q': 'requests+language:python'},
        headers={'X-Vault-Token': 's.VjOyZANgP89UEQSVcXNKdZOi'},
        )
        json_response = response.json()
        APIKey = json_response['data']['llave']
vault kv put kv/cert/mysql certificado=@cert.pem
vault kv get -field=certificado kv/cert/mysql

Instalar módulo de generación de contraseñas robustas

mkdir /etc/vault/plugins/
cd /etc/vault/plugins/
wget https://github.com/sethvargo/vault-secrets-gen/releases/download/v0.0.6/vault-secrets-gen_0.0.6_linux_amd64.tgz
tar -zxvf vault-secrets-gen_0.0.6_linux_amd64.tgz
setcap cap_ipc_lock=+ep /etc/vault/plugins/vault-secrets-gen
export SHA256=$(shasum -a 256 "/etc/vault/plugins/vault-secrets-gen" | cut -d' ' -f1)

vault plugin register \
    -sha256="${SHA256}" \
    -command="vault-secrets-gen" \
    secret secrets-gen
vault secrets enable \
    -path="gen" \
    -plugin-name="secrets-gen" \
    plugin
vault write gen/password length=36

Secretos dinámicos

Para incrementar la seguridad de una aplicación se puede usar la funcion de “secretos dinámicos” de Vault que permite crear dinámicamente usuarios y contraseñas temporales de la base de datos para que sean usados por una aplicación y así no exponer el usuario y contraseña.

Este ejemplo asume que mongdb tiene habilitado la autenticación para las credenciales:

usuario="sam"
password="test123

vault secrets enable database
vault write database/config/my-mongodb-database \
    plugin_name=mongodb-database-plugin \
    allowed_roles="my-role" \
    connection_url="mongodb://{{username}}:{{password}}@127.0.0.1:27017/admin" \
    username="sam" \
    password="test123"
vault write database/roles/my-role \
    db_name=my-mongodb-database \
    creation_statements='{ "db": "admin", "roles": [{ "role": "readWrite" }] }' \
    default_ttl="1h" \
    max_ttl="24h"
vault read database/creds/my-role

Código de ejemplo de una aplicación en python que se comunica con Vault usando un token para obtener un usuario y contraseña de la base de datos:

        response = requests.get(
        'http://127.0.0.1:8200/v1/database/creds/my-role',
        params={'q': 'requests+language:python'},
        headers={'X-Vault-Token': 's.VjOyZANgP89UEQSVcXNKdZOi'},
        )
        json_response = response.json()
        Database.USER = json_response['data']['username']
        Database.PASSWORD = json_response['data']['password']

En el siguiente punto se muestra como generar tokens que puede tener restricciones como:

  1. Tiempo de vida
  2. Permiso granular de acceso a Vault
  3. Uso máximo

Habilitar AppRole para la autenticación de aplicaciones con vault

El método AppRole permite que aplicaciones se autentiquen con roles definidos por Vault.

Habilitar la autenticación para aplicaciones

vault auth enable approle

Crear el archivo "database.hcl” que describe la política para la aplicación

cat <<EOF | sudo tee /etc/vault/database.hcl
path "database/creds/my-role" {
 capabilities = ["read", "list"]
}
EOF

Cargar la política a vault

vault policy write database /etc/vault/database.hcl
  1. Tiempo de vida del token 10 minutos
  2. Tiempo de vida del secret-id 1 minuto
  3. Uso máximo de tokens: 3 veces
vault write auth/approle/role/databaseApp secret_id_ttl=1m secret_id_num_uses=1 token_num_uses=3 token_ttl=10m token_max_ttl=30m policies=database
vault read auth/approle/role/databaseApp
vault read auth/approle/role/databaseApp/role-id
vault write -f auth/approle/role/databaseApp/secret-id
vault write auth/approle/login role_id="XXXXX" secret_id="YYYYYYY"
vault token revoke s.V6T0DxxIg5FbBSre61y1WLgmalid

Hardening


Revision #3
Created 7 marzo 2023 09:32:41 by Franz Rojas
Updated 10 abril 2024 11:05:56 by Vladimir Urquiola