Introducción a HashiCorp Vault OTP
Soy Òscar Mas y, continuando con las funcionalidades que nos puede ofrecer HashiCorp Vault, nos encontramos con una que no es muy conocida, pero cuando conozcáis su existencia y funcionalidad, estoy seguro de que os enamorará. Esta funcionalidad se llama OTP (One-Time Password).
¿Qué es HashiCorp Vault OTP?
Para entender el sistema de OTP (One-Time Password), debemos ponernos en situación. Imaginad que un externo tiene que acceder para realizar un determinado trabajo en un servidor de nuestra infraestructura y, una vez finalizado el trabajo, no queremos que pueda volver a acceder nunca más a ese servidor. Esto se podría hacer copiando su clave SSH pública en el servidor y, una vez finalizado el trabajo, eliminar esa clave pública que hemos guardado en el servidor. Pero esto implica un riesgo muy alto: tenemos que acordarnos de eliminar su clave pública del servidor y, aunque me juréis que la eliminaréis, estoy seguro de que si hacemos esta operación varias veces, al final os olvidaréis de quitar la clave SSH y se quedará en ese servidor para siempre. En este punto es donde entra OTP (One-Time Password).
Laboratorio de HashiCorp Vault OTP
La funcionalidad de OTP (One-Time Password) es muy sencilla: dar acceso a un servidor solo una vez. Para que podáis verlo mejor, haremos un laboratorio, en el que necesitaremos dos equipos:
- vault (172.26.0.30): servidor de Vault
- client-otp-vault (172.26.0.240): equipo que utilizaremos como cliente
Configuración de Vault
Activación del motor SSH OTP
Lo primero que haremos será entrar en el contenedor de HashiCorp Vault, autenticarnos y activar el motor de secretos SSH OTP:
root@vault:~# docker exec -it vault ash / # export VAULT_ADDR=http://127.0.0.1:8200 / # vault login s.KaU83zJXYPXaZZCfFkgT8eJX
/ # vault secrets enable -path=otp_ssh -description="Motor SSH para contraseñas de un solo uso (OTP)" ssh / # vault secrets list Path Type Accessor Description ---- ---- -------- ----------- cubbyhole/ cubbyhole cubbyhole_56ed61f9 per-token private secret storage identity/ identity identity_53938dc5 identity store otp_ssh/ ssh ssh_68e013df Motor SSH para contraseñas de un solo uso (OTP) sys/ system system_6e42f7a1 system endpoints used for control, policy and debugging
Creación del rol OTP
A continuación crearemos una política de seguridad, en la que definiremos que cualquier credencial generada será de un solo uso (otp), para la red interna de la empresa (172.26.0.0/24) y que, si el usuario no especifica nada, intentará conectarse como username (default_user).
/ # vault write otp_ssh/roles/otp_key_role \ key_type=otp \ default_user=username \ cidr_list=172.26.0.0/24 \ allowed_users="*"
Generación de la contraseña de un solo uso
Ahora lo que necesitamos es que el usuario oscar.mas pueda acceder al servidor que tiene la IP: 172.26.0.240. Lo que haremos será indicarle a Vault estos datos y Vault nos devolverá la contraseña (aacedcc6-5281-8eb1-869f-f0a5b66c4bab), recordad anotarla, ya que más adelante, cuando queramos acceder al servidor y nos solicite una contraseña, tendremos que introducir esta.
/ # vault write otp_ssh/creds/otp_key_role ip=172.26.0.240 username=oscar.mas Key Value --- ----- lease_id otp_ssh/creds/otp_key_role/B5YaFNncHYiM4ujo15oAAddg lease_duration 768h lease_renewable false ip 172.26.0.240 key aacedcc6-5281-8eb1-869f-f0a5b66c4bab key_type otp port 22 username oscar.mas
Configuración del Cliente
En este punto, debemos ir a nuestro servidor que hará de cliente (client-otp-vault) e indicarle que cuando alguien quiera acceder por SSH consulte al servidor de Vault. Esto lo podemos hacer gracias a: vault-ssh-helper. Si queremos conocer la última versión de vault-ssh-helper, podéis hacerlo en esta web: https://releases.hashicorp.com/vault-ssh-helper/
root@client-otp-vault:~# cd /tmp root@client-otp-vault:/tmp# wget https://releases.hashicorp.com/vault-ssh-helper/0.2.4/vault-ssh-helper_0.2.4_linux_amd64.zip root@client-otp-vault:/tmp# apt-get update && apt-get install -y unzip root@client-otp-vault:/tmp# unzip vault-ssh-helper_0.2.4_linux_amd64.zip root@client-otp-vault:/tmp# mv vault-ssh-helper /usr/local/bin/ root@client-otp-vault:/tmp# chmod +x /usr/local/bin/vault-ssh-helper
Configuración del servidor SSH
Ahora debemos modificar la configuración del demonio SSH del servidor de destino para permitir que PAM haga su trabajo.
root@client-otp-vault:~# vim /etc/ssh/sshd_config # Habilita la autenticación por teclado interactivo (necesaria para PAM) KbdInteractiveAuthentication yes # Asegura que SSH use el sistema PAM del sistema operativo UsePAM yes # Deshabilita el login directo por contraseña estándar (opcional, por seguridad) PasswordAuthentication no root@client-otp-vault:~# systemctl restart ssh
root@client-otp-vault:~# systemctl restart ssh
Aquí es donde se le indica al sistema que cualquier persona que quiera conectarse debe consultar a Vault:
root@client-otp-vault:~# vim /etc/pam.d/vault-otp # /etc/pam.d/vault-otp auth [success=done default=ignore] pam_exec.so quiet expose_authtok /usr/local/bin/vault-ssh-helper -config=/etc/vault-ssh-helper.d/config.hcl -dev
root@client-otp-vault:~# vim /etc/pam.d/sshd @include vault-otp
root@client-otp-vault:~# mkdir -p /etc/vault-ssh-helper.d root@client-otp-vault:~# vim /etc/vault-ssh-helper.d/config.hcl vault_addr = "http://172.26.0.30" ssh_mount_point = "otp_ssh" tls_skip_verify = true allowed_roles = "*"
Con toda esta configuración, cuando el usuario oscar.mas intente hacer un SSH al servidor, SSH pasará el control a PAM, PAM llamará a vault-ssh-helper, y este comprobará instantáneamente si la contraseña utilizada es la OTP.
Verificación del funcionamiento
Pero como siempre, debemos validar que todo funciona correctamente:
root@client-otp-vault:/tmp# vault-ssh-helper -verify-only -config=/etc/vault-ssh-helper.d/config.hcl -dev 2026-06-20T12:13:55.886+0200 [WARN] Dev mode is enabled! 2026-06-20T12:13:55.887+0200 [INFO] using SSH mount point: otp_ssh 2026-06-20T12:13:55.887+0200 [INFO] using namespace: 2026-06-20T12:13:55.893+0200 [INFO] vault-ssh-helper verification successful!
Que no se nos olvide crear el usuario en el sistema.
root@client-otp-vault:~# useradd -m -s /bin/bash oscar.mas
Ahora lo único que queda es iniciar sesión por SSH con el usuario indicado:
$ ssh oscar.mas@172.26.0.240
Recordad que la contraseña que debemos introducir es la que nos ha proporcionado Vault: aacedcc6-5281-8eb1-869f-f0a5b66c4bab y que esta contraseña es de un solo uso. Si una vez utilizada la contraseña necesitamos volver a iniciar sesión por cualquier motivo, habrá que generar una nueva OTP:
/ # vault write otp_ssh/creds/otp_key_role ip=172.26.0.240 username=oscar.mas
Para validar que el usuario ha podido acceder al servidor y todo ha ido bien, podemos ver los logs de SSH:
root@client-otp-vault:~# journalctl -u ssh -f Jun 20 12:27:01 client-otp-vault sshd-session[1105]: Accepted keyboard-interactive/pam for oscar.mas from 172.26.0.218 port 57506 ssh2 Jun 20 12:27:01 client-otp-vault sshd-session[1105]: pam_unix(sshd:session): session opened for user oscar.mas(uid=1001) by oscar.mas(uid=0)
Conclusión
HashiCorp Vault OTP es una funcionalidad muy útil cuando necesitamos conceder accesos temporales a servidores sin tener que gestionar claves SSH permanentes. Mediante contraseñas de un solo uso y la integración con PAM y "vault-ssh-helper", podemos reducir considerablemente el riesgo de dejar accesos abiertos una vez finalizadas las tareas de mantenimiento.
Espero que os haya gustado esta funcionalidad de HashiCorp Vault.