Saltar al contenido
Nuevo

DeepSeek V4.1 Flash gratis por 7 días: 10M tokens al día tras cualquier recarga. Hasta el 30/11.

Cómo funciona

Claves SSH: cómo funcionan y cómo usarlas con seguridad

Cómo funcionan las claves SSH de host y de usuario, por qué Ed25519 con frase de paso es el estándar y cómo proteger el acceso en una VM de laboratorio.

Principiante11 min de lecturaPor NotHoly

Qué protege SSH

SSH (Secure Shell) es el protocolo que más personas usan para entrar a servidores Linux, máquinas virtuales de laboratorio y hospedajes de Git. Abre una shell sobre un canal cifrado, y ese mismo canal puede copiar archivos o redirigir puertos. Tiene tres funciones. Cifra el tráfico para que nadie en la ruta de la red pueda leerlo. Demuestra al servidor quién eres. Te demuestra a ti quién es el servidor.

Las claves cumplen la segunda función sin enviar una contraseña por la red. Una contraseña puede adivinarse o robarse con phishing. Un par de claves funciona de otra forma. El servidor guarda solo la mitad pública. Para entrar, tu cliente firma un desafío con la mitad privada, y el servidor verifica la firma. La clave privada nunca sale de tu equipo.

SSH no te protege en algunos casos, y esos casos importan tanto como el protocolo. Si tu propio equipo está comprometido, un malware que corre con tu usuario puede leer el archivo de la clave privada o pedirle al agente que firme cosas por ti. Si la clave privada se roba y su frase de paso es débil, el atacante puede intentar adivinarla sin conexión. Si aceptas la identidad de un servidor sin verificarla, puedes estar hablando con alguien que no es el servidor.

Dos tipos de claves

SSH usa dos tipos distintos de claves, y la gente suele confundirlos.

Claves de host identifican al servidor. Cada servidor SSH tiene una o más, normalmente guardadas en /etc/ssh/ssh_host_*_key. La parte privada se queda en el servidor. La parte pública se presenta a todo cliente que se conecta. La primera vez que tu cliente la ve, la guarda en known_hosts. En conexiones posteriores, una clave de host distinta dispara una advertencia.

Claves de usuario te identifican a ti. Generas el par en tu propio equipo. La clave privada se queda contigo. La clave pública va al servidor, en ~/.ssh/authorized_keys de la cuenta a la que quieres entrar.

La diferencia tiene consecuencias prácticas. Copiar tu clave privada a un servidor le entrega a ese servidor, y a cualquiera que pueda leerla, el material necesario para actuar como tú en todo lugar donde la clave sea confiable. Ignorar una advertencia de clave de host significa que puedes enviar tu contraseña o tus comandos a un impostor.

Por qué Ed25519 con frase de paso

OpenSSH admite varios tipos de clave. RSA sigue funcionando, pero las claves RSA nuevas deben tener al menos 3072 bits, y las líneas de clave pública quedan largas. Las claves Ed25519 son cortas, rápidas de verificar y están estandarizadas para SSH en la RFC 8709. OpenSSH 9.5 y las versiones posteriores ya usan Ed25519 como valor por defecto en ssh-keygen. Para una clave de laboratorio, Ed25519 es la opción adecuada, salvo que un sistema al que necesitas entrar acepte solo un tipo más antiguo.

La frase de paso cifra el archivo de la clave privada en el disco. Sin ella, cualquiera que copie el archivo puede usar la clave. Con ella, el atacante necesita el archivo y la frase. Eso protege contra los accidentes más comunes: una copia de seguridad enviada al lugar equivocado, una clave dejada en una carpeta compartida, un archivo sincronizado por error con la nube. La frase no ayuda una vez que la clave está cargada en un agente y un malware corre como tú. Usa una frase larga, guárdala en un gestor de contraseñas y conserva una copia del archivo de la clave en un lugar seguro.

Cómo funciona una conexión

La RFC 4253 describe la capa de transporte. En términos generales, una conexión pasa por estos pasos:

  1. Tu cliente abre una conexión TCP con el servidor, normalmente en el puerto 22.
  2. Ambos lados envían los algoritmos que soportan y acuerdan un intercambio de claves. El intercambio produce secretos compartidos, y desde ese momento todo el tráfico va cifrado.
  3. El servidor envía su clave de host y una firma sobre el intercambio. Tu cliente compara esa clave con known_hosts. Si el host es nuevo, el cliente muestra la huella y te pide que la confirmes.
  4. Te autenticas. El cliente ofrece una clave pública. Si el servidor la encuentra en authorized_keys, envía un desafío. Tu cliente firma el desafío con la clave privada, y el servidor verifica la firma.

Fíjate de dónde viene la confianza. El paso 3 trata del servidor. El paso 4 trata de ti. Si omites la verificación de la huella en el paso 3, el resto del proceso sigue funcionando para quien contestó la llamada.

Huellas digitales

Una huella es un hash corto de una clave pública. OpenSSH muestra huellas SHA256 por defecto. Dos personas pueden comparar una huella para confirmar que tienen la misma clave pública, sin leer la clave completa en voz alta.

Los comandos siguientes se ejecutaron en un Windows 11 con OpenSSH 9.9p2 (ssh -V), en Git Bash. La clave era una copia de prueba creada solo para esta observación, con frase vacía, para que la salida pudiera mostrarse aquí. Tu clave real tendrá otra huella.

bash
ssh-keygen -t ed25519 -C 'lab-key' -f ./lab_ed25519 -N ''
ssh-keygen -lf ./lab_ed25519.pub

Salida observada:

text
256 SHA256:2BAyZTrHADdiG1FNwfCwb/fC5vSVZPwfGnZjRaaExc4 lab-key (ED25519)

ssh-keygen -lvf muestra la misma huella con una imagen aleatoria. La imagen ayuda a notar un cambio, pero el texto de la huella es lo que se compara.

Práctica de laboratorio

Necesitas una máquina virtual o una instancia en la nube que sea tuya y que controlas, con un servidor OpenSSH en ejecución y una cuenta que pueda usar sudo. Sirve una VM local en VirtualBox o Hyper-V. También sirve una instancia pequeña en la nube que pagues y puedas borrar. No ejecutes estos pasos en una máquina que pertenezca a otra persona.

Paso 1: generar la clave

bash
ssh-keygen -t ed25519 -C 'lab-key' -f ~/.ssh/lab_ed25519

Cuando te lo pida, escribe una frase de paso larga. El comando crea dos archivos: lab_ed25519 (privada) y lab_ed25519.pub (pública). Solo el archivo .pub debe salir de tu equipo.

Paso 2: verificar la huella

bash
ssh-keygen -lf ~/.ssh/lab_ed25519.pub

Anota esta huella, o al menos los primeros caracteres. La compararás más tarde.

Paso 3: proteger el archivo de la clave privada

bash
chmod 600 ~/.ssh/lab_ed25519

En Linux y macOS, ssh rechaza una clave privada que otros usuarios pueden leer. En Windows, OpenSSH revisa las ACL del archivo, no los bits de modo de Unix. En esta máquina Windows, chmod 600 se ejecutó sin error, pero ls -l siguió mostrando -rw-r--r-- después. No des por hecho que los bits de modo cambiaron ahí. Si ssh se queja de permisos en Windows, inspecciona el archivo con icacls y quita el acceso a otras cuentas.

Paso 4: instalar la clave pública en la VM

bash
ssh-copy-id -i ~/.ssh/lab_ed25519.pub tuusuario@tu-vm-de-laboratorio

Esta es la única vez que escribes la contraseña de la cuenta a propósito. El comando añade la clave pública a ~/.ssh/authorized_keys en la VM.

La primera conexión a la VM también muestra una huella de la clave de host. Compárala con la real. En la VM, ejecuta:

bash
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

Si las dos huellas coinciden, escribe yes. Si no coinciden, detente. Averigua la causa antes de seguir. Una diferencia puede significar que reinstalaste la VM, o que alguien está entre tú y ella.

Este paso no se ejecutó aquí, porque no había ninguna VM disponible en esta máquina. Por eso los comandos de los pasos 4 a 6 se muestran sin salida. Puedes comprobar cada uno en tu propia VM.

Paso 5: entrar con la clave

bash
ssh -i ~/.ssh/lab_ed25519 tuusuario@tu-vm-de-laboratorio

Tu cliente pide la frase de paso de la clave, no la contraseña de la cuenta. Si aparece una shell, la clave funciona. Mantén esta sesión abierta para el siguiente paso.

Paso 6: desactivar el inicio de sesión con contraseña

En la VM:

bash
sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sshd -t && sudo systemctl restart ssh

La línea de sed reemplaza la línea PasswordAuthentication, esté comentada o no. sshd -t revisa la sintaxis de la configuración y corta la cadena si hay un error. systemctl restart ssh aplica el cambio. En Fedora y otras distribuciones de la familia RHEL, el servicio se llama sshd, así que usa ese nombre.

Aquí suelen fallar tres cosas:

  • La línea se sobrescribe. En muchos sistemas Debian y Ubuntu, /etc/ssh/sshd_config incluye archivos de /etc/ssh/sshd_config.d/, y vale el primer valor leído para cada palabra clave. Verifica el valor que sshd usa de verdad:
bash
sudo sshd -T | grep -i '^passwordauthentication'

Después del cambio, la salida debe ser passwordauthentication no. Si todavía dice yes, busca el archivo que define el valor y corrígelo allí.

  • La línea no existe. sed solo edita una línea que ya está. Si no hay ninguna línea PasswordAuthentication, aplica el valor por defecto, y la página de manual de sshd_config(5) indica que ese valor es yes. Añade la línea tú mismo:
bash
echo 'PasswordAuthentication no' | sudo tee -a /etc/ssh/sshd_config
  • Te bloqueas fuera. Antes de cerrar la sesión que usaste en el paso 5, abre una segunda terminal y entra con la clave. Cierra la primera solo cuando la segunda funcione. Si pierdes el acceso, usa la consola de la VM en el panel de tu hipervisor o de la nube para reparar la configuración.

Luego, prueba desde tu equipo que el inicio de sesión con contraseña se rechaza:

bash
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password tuusuario@tu-vm-de-laboratorio

La conexión debe fallar con un mensaje de permiso denegado. Haz esta comprobación tú mismo, en la VM que controlas. No se ejecutó en esta máquina.

El agente y known_hosts

ssh-agent

Escribir la frase de paso en cada conexión resulta pesado. ssh-agent mantiene la clave ya descifrada en memoria durante tu sesión, así que escribes la frase una sola vez.

bash
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/lab_ed25519
ssh-add -l

ssh-add -l lista las huellas que el agente tiene cargadas. En esta máquina Windows, ssh-add -l se ejecutó sin un agente activo y mostró Could not open a connection to your authentication agent., con código de salida 2. En Windows eso lo gestiona el servicio OpenSSH Authentication Agent. Inicia ese servicio desde la consola de Servicios o desde un PowerShell como administrador. Es un cambio en tu sistema, así que hazlo tú mismo y solo si quieres el agente en ejecución.

El agente es cómodo y también es un objetivo. Quien pueda hablar con el socket del agente mientras tienes la sesión abierta puede pedirle que firme cosas. Por eso conviene evitar el reenvío de agente (ssh -A) hacia hosts en los que no confías del todo. Un usuario root en el host remoto puede usar tu agente reenviado. Si necesitas llegar a una máquina privada a través de un bastión, usa un salto:

bash
ssh -J tuusuario@bastion tuusuario@vm-privada

known_hosts

El cliente guarda las claves de host en ~/.ssh/known_hosts, una línea por host y tipo de clave. Las líneas pueden convertirse en hash si defines HashKnownHosts yes, lo que oculta los nombres de host a quien lea el archivo.

Para buscar un host:

bash
ssh-keygen -F tu-vm-de-laboratorio

Para eliminar una entrada después de reconstruir la VM y obtener una nueva clave de host:

bash
ssh-keygen -R tu-vm-de-laboratorio

Hazlo solo cuando sepas por qué cambió la clave. Una clave de host cambiada es una alerta, no una molestia. Borrar la entrada vieja sin verificar la nueva huella te enseña a ignorar la siguiente alerta, y la siguiente puede ser real.

Puntos clave

  • Nunca compartas la clave privada. Solo el archivo .pub va a servidores, hospedajes de Git u otras personas.
  • Protege la clave privada con una frase de paso y conserva una copia del archivo.
  • Verifica la huella del host en la primera conexión e investiga cualquier cambio posterior.

Errores comunes

  • Pegar la clave privada en un chat, issue, ticket o captura de pantalla. Trátala como una contraseña que no se puede restablecer. Si se filtra, genera una clave nueva, instálala y quita la clave pública anterior de authorized_keys.
  • Instalar la clave privada en el servidor en lugar de la pública. El servidor solo necesita la línea del .pub en authorized_keys.
  • Permisos en el servidor. En Linux, ~/.ssh debe ser 700 y authorized_keys debe ser 600. Modos más abiertos pueden hacer que sshd ignore la clave. Revisa los registros de sshd cuando falle un inicio de sesión por clave.
  • Desactivar las contraseñas antes de que funcione el inicio por clave. Es el bloqueo más frecuente. Sigue el orden del paso 6.
  • Una sola clave para todo. Usar la misma clave en VM de laboratorio, hospedajes de Git y sistemas de producción significa que una filtración abre todo. Usa claves separadas por propósito, como lab_ed25519 para el laboratorio y otra para GitHub.
  • Aceptar una clave de host desconocida sin verificarla. La primera conexión es el momento en que un impostor tiene más posibilidades de entrar. Compara la huella antes de escribir yes.
  • Perder la frase de paso. No hay recuperación. Guárdala en un gestor de contraseñas.
  • Líneas duplicadas en authorized_keys. Ejecutar ssh-copy-id dos veces no hace daño, pero añadir la misma clave a mano varias veces hace que el archivo sea difícil de auditar. Elimina las claves que ya no usas.

Cómo seguir

Cuando el laboratorio funcione, algunos pasos harán más seguro y ordenado el uso diario.

  • Ajustes por host en ~/.ssh/config. Asigna un alias a cada host, define el IdentityFile y añade IdentitiesOnly yes, para que el cliente ofrezca solo la clave que elegiste. Así no prueba todas las claves del agente en cada servidor.
  • Claves de seguridad. OpenSSH puede crear claves guardadas en un dispositivo de seguridad de hardware, con ssh-keygen -t ed25519-sk. La parte privada no se puede copiar fuera del dispositivo. Revisa tu versión de OpenSSH y el soporte antes de depender de esto.
  • Certificados SSH. Las organizaciones con muchos servidores suelen usar una autoridad de certificación en lugar de repartir claves a cada host. El concepto vale la pena aunque todavía no lo necesites.
  • Lee los documentos de referencia. Las páginas de manual de ssh-keygen y sshd_config describen todas las opciones que vas a encontrar. La RFC 4253 explica la capa de transporte, y la RFC 8709 trata Ed25519 en SSH.

Si los permisos y los dueños de archivos todavía te resultan nuevos, lee antes el artículo anterior sobre permisos de archivos en Linux. El siguiente artículo trata de redes Docker aisladas para laboratorios, que sirven para mantener el tráfico del laboratorio lejos de tu red de todos los días.

Fuentes

Fuentes

  1. OpenBSD manual: ssh-keygen(1)
  2. OpenBSD manual: sshd_config(5)
  3. OpenSSH 9.5 release notes
  4. RFC 4253: The Secure Shell (SSH) Transport Layer Protocol
  5. RFC 8709: Ed25519 and Ed448 Public Key Algorithms for SSH

Más en Linux y herramientas de desarrollo

Linux y herramientas de desarrollo

Bash básico para trabajo de seguridad

Aprende pipes, redirección, variables, bucles, códigos de salida y set -euo pipefail, y úsalos para contar logins fallidos y hashear una carpeta.

Principiante14 min de lectura

Linux y herramientas de desarrollo

Permisos en Linux: usuarios, grupos, chmod y umask

Propietarios, grupos, bits rwx, chmod, umask y setuid en Linux, con un laboratorio que prueba el acceso de otro usuario y busca modos riesgosos.

Principiante13 min de lectura