Mira qué ofrece tu cliente
ssh -v user@server
Busca estas líneas cerca del final de la salida:
| Línea | Qué significa |
|---|---|
Will attempt key: ... | Las claves que tu cliente piensa probar. Si falta la tuya, el cliente no la conoce. |
Offering public key: ... | La clave se envió al servidor. |
Server accepts key: ... | El servidor conoce esta clave. Un fallo después de esta línea es un problema de la clave privada en tu lado. |
Warning: Identity file ... not accessible | La ruta que diste a -i o a IdentityFile no existe. |
Load key "...": bad permissions | El archivo de la clave privada está demasiado abierto, así que se ignoró. Mira archivo de clave privada sin proteger. |
La palabra entre paréntesis del error lista los métodos de inicio de sesión que el servidor todavía permite. (publickey) a solas significa que las contraseñas están desactivadas, así que una clave que funcione es la única forma de entrar.
¿Te pasa con git push o git pull? Consulta git@github.com: Permission denied (publickey).
Lee el log del servidor
Al cliente nunca se le dice por qué se rechazó una clave. Solo lo sabe el servidor. Si aún tienes alguna forma de entrar, como otra sesión o la consola de un proveedor, lee el log:
sudo journalctl -u ssh -n 50 # Debian, Ubuntu
sudo journalctl -u sshd -n 50 # RHEL, Fedora, Arch
sudo tail -n 50 /var/log/auth.log # older Debian and Ubuntu
sudo tail -n 50 /var/log/secure # older RHEL
| Línea del log | Causa |
|---|---|
Invalid user alice from ... | Esa cuenta no existe en el servidor. |
Authentication refused: bad ownership or modes for directory ... | Permisos del directorio personal o de .ssh. |
Authentication refused: bad ownership or modes for file ... | Permisos de authorized_keys. |
Could not open user 'user' authorized keys ...: Permission denied | El archivo pertenece a otra persona, a menudo root, tras crearlo con sudo. |
User user from ... not allowed because not listed in AllowUsers | AllowUsers bloquea la cuenta. DenyUsers, AllowGroups y DenyGroups funcionan de forma parecida. |
Connection closed by authenticating user user ... [preauth] | Si no se registra nada más, normalmente significa que la clave simplemente no está en authorized_keys. |
Si el log no da ningún motivo, ejecuta un segundo sshd en modo depuración en un puerto libre. Atiende una conexión, imprime cada paso y termina. El puerto debe estar abierto en tu firewall.
sudo /usr/sbin/sshd -d -p 2222
ssh -v -p 2222 user@server
Usuario equivocado
Comprueba con qué usuario inicias sesión realmente, porque una línea User de tu configuración puede fijarlo:
ssh -G server | grep '^user '
Las imágenes de la nube suelen usar una cuenta fija como ubuntu, debian o ec2-user, y rechazan root. Una clave instalada para una cuenta no sirve para otra, porque cada cuenta tiene su propio authorized_keys.
Para fijar de una vez el usuario y la clave de un host, pon User e IdentityFile en su bloque del archivo de configuración de ssh.
Clave equivocada, o la clave no está en el servidor
Compara las huellas. En tu máquina:
ssh-keygen -lf ~/.ssh/id_ed25519.pub
En el servidor, esto lista todas las claves del archivo:
ssh-keygen -lf ~/.ssh/authorized_keys
Si falta la huella, instala la clave. Mientras el acceso con contraseña funcione, basta un comando, que además deja los permisos correctos:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
Si el servidor solo acepta claves, añádela desde la consola del proveedor u otra sesión, como ese usuario. Pon tu línea .pub completa en lugar del ejemplo:
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo 'ssh-ed25519 AAAA... you@laptop' >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Si la clave está pero tu cliente ofrece otras antes, indícala por su nombre e ignora el resto:
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 user@server
Un error común al instalarla a mano es una clave partida en dos líneas. Cada clave debe ir en una sola línea: consulta el archivo authorized_keys explicado.
Permisos y propietario
Con el valor por defecto StrictModes yes, sshd ignora authorized_keys si otros usuarios pudieran escribir en él o en los directorios superiores. El permiso de escritura para el grupo en el directorio personal basta para provocarlo. En el servidor, como el usuario:
chmod go-w ~
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Si creaste los archivos con sudo, arregla también el propietario:
sudo chown -R user:user /home/user/.ssh
Para ver todos los niveles de la ruta a la vez:
namei -l /home/user/.ssh/authorized_keys
En sistemas con SELinux en modo enforcing, como RHEL y Fedora, los archivos movidos a su sitio también pueden tener una etiqueta incorrecta. Restablécela con restorecon -Rv ~/.ssh.
AuthorizedKeysFile apunta a otro sitio
Tu clave puede estar en el archivo correcto para la configuración por defecto, pero no para este servidor. Pregunta a sshd qué se aplica a este usuario. -C evalúa también los bloques Match:
sudo sshd -T -C user=user,host=example.com,addr=203.0.113.10 | grep -iE '^(authorizedkeysfile|pubkeyauthentication) '
El valor por defecto es .ssh/authorized_keys .ssh/authorized_keys2, relativo al directorio personal. Un valor como /etc/ssh/authorized_keys/%u significa que la clave tiene que ir allí. Comprueba también que pubkeyauthentication diga yes.
RSA antiguo y PubkeyAcceptedAlgorithms
OpenSSH 8.8 desactivó por defecto la firma ssh-rsa, que usa SHA-1. Esto desactivó la firma antigua, no las claves RSA. Una clave RSA sigue funcionando cuando ambos lados admiten rsa-sha2-256 o rsa-sha2-512, que OpenSSH admite desde la versión 7.2.
Si un cliente nuevo se encuentra con un servidor demasiado antiguo para eso, ssh -v muestra una línea como no mutual signature algorithm, y la clave nunca se ofrece. La solución real es actualizar el servidor. Hasta entonces, permite la firma antigua para ese host en ~/.ssh/config:
Host oldbox
PubkeyAcceptedAlgorithms +ssh-rsa
HostKeyAlgorithms +ssh-rsa
Si un cliente antiguo se conecta a un servidor nuevo, la misma línea va en la configuración de sshd, y afecta a todos los usuarios de ese servidor:
PubkeyAcceptedAlgorithms +ssh-rsa
Antes de OpenSSH 8.5 la opción se llamaba PubkeyAcceptedKeyTypes. Si puedes, cambia a una clave ed25519 y quita estas líneas.
Preguntas
¿Cómo añado mi clave SSH al servidor?
Ejecuta ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server mientras el acceso con contraseña funcione. Si el servidor solo acepta claves, añade tu línea .pub a ~/.ssh/authorized_keys desde la consola del proveedor y ejecuta chmod 600 sobre el archivo.
¿Por qué SSH dice Permission denied (publickey) si la clave está en el servidor?
Casi siempre por los permisos: sshd ignora authorized_keys si otros pueden escribir en el directorio personal, en .ssh o en el archivo. Comprueba también que la clave esté en el archivo de la cuenta con la que entras.
¿Cómo veo qué clave ofrece SSH?
Ejecuta ssh -v user@server y busca las líneas Offering public key. Para usar una sola clave, añade -o IdentitiesOnly=yes y -i con su ruta.
¿Las claves RSA siguen funcionando con OpenSSH reciente?
Sí. OpenSSH 8.8 desactivó la antigua firma ssh-rsa con SHA-1, no las claves RSA, que funcionan con rsa-sha2-256 o rsa-sha2-512.
Fuentes
- ssh(1), manual de OpenBSD
- sshd(8), manual de OpenBSD
- sshd_config(5), manual de OpenBSD
- Notas de la versión de OpenSSH 8.8
- Notas de la versión de OpenSSH 8.5