Failed publickey: sólo faltaba la opción IdentitiesOnly

por | febrero 9, 2019

Utilizo varios pares de claves RSA para distintos servidores y servicios, no un par único que se suele alojar en el directorio .ssh de mi home de usuario:

/home/jota/.ssh
/home/jota/.ssh_vps
/home/jota/.ssh_git
/home/jota/.ssh_bitbucket

Cuando conectamos con un servidor remoto con el que hemos establecido una relación de confianza con clave pública, utilizamos la opción -i:

ssh -i /home/jota/.ssh_vps/id_rsa jota@my-server

Sin embargo, aunque hayamos establecido una relación de confianza con el servidor remoto y funcionar a efectos prácticos la autenticación, puede que veamos un mensaje «Failed publickey»:

Jan 30 18:32:28 my-server sshd[10495]: Connection from 192.168.2.1 port 49622 on 192.168.2.101 port 118
Jan 30 18:32:29 my-server sshd[10495]: Failed publickey for jota from 192.168.2.1 port 49622 ssh2: RSA SHA256:df00Cf45ZRCYSfRFKuyHAcJRP7ln4PSvXKqOvwjkzo5
Jan 30 18:32:29 my-server sshd[10495]: Postponed publickey for jota from 192.168.2.1 port 49622 ssh2 [preauth]
Jan 30 18:32:35 my-server sshd[10495]: Accepted publickey for jota from 192.168.2.1 port 49622 ssh2: RSA SHA256:P9vKyPt1l5Z20MIvfu0bmoXildV3LApcUvo9sdsvr0

Esto se debe a que por defecto el cliente SSH va a presentar primero -si existe- la clave privada de nuestro directorio .ssh, aunque especifiquemos otra identidad con la opción -i. Si la clave pública no se ha añadido al authorized_keys del servidor remoto va a producir un error Failed publickey. La autenticación procederá a presentar la siguiente clave, que esta vez es la que hemos especificado nosotros con -i y no debería fallar como vemos en el ejemplo anterior.

Para que el cliente SSH no tenga este comportamiento debemos configurar en /etc/ssh/ssh_config la opción IdentitiesOnly

Especificamos IdentitiesOnly yes quedando de la siguiente manera:

Aunque esto no debe causar de entrada ningún problema ya que acabamos presentando nuestra clave después del intento fallido, la situación se puede complicar si tenemos alguna herramienta de bloqueo de cuenta por intentos de conexión fallidos (como fail2ban) en el servidor remoto. Al hacer varias conexiones por SSH y detectar esos fallos en el log (/var/log/auth en Debian o /var/log/secure en RHEL) podemos acabar con nuestra cuenta bloqueada.