Ir al contenido

HashiCorp Vault OTP: acceso SSH de un solo uso con One-Time Password

7 de julio de 2026 por
Ilimit Comunicacions S.L., Oscar Mas

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.