⏱️ Lectura: 15 min

Cada vez que ejecutás ssh usuario@servidor para administrar una máquina remota, confiás en un protocolo diseñado en 1995 por un investigador finlandés harto de ver contraseñas viajar en texto plano por telnet. Treinta años después, el protocolo SSH sigue siendo el método por defecto para administrar servidores Linux.

📑 En este artículo
  1. TL;DR
  2. ¿Qué es el protocolo SSH?
  3. Por qué importa el acceso remoto cifrado
  4. Cómo funciona SSH por dentro: intercambio de claves y autenticación
    1. La capa de transporte SSH: cómo se arma el canal cifrado
    2. Autenticación en SSH: llave pública, contraseña o certificados
  5. Ejemplos prácticos con SSH
  6. Cómo empezar
  7. Casos de uso reales
  8. Errores comunes y buenas prácticas
  9. Comparativa con alternativas
  10. Profundizando
  11. Preguntas frecuentes
    1. ¿Qué diferencia hay entre SSH y Telnet?
    2. ¿Cómo genero un par de llaves SSH seguras?
    3. ¿Es necesario desactivar la autenticación por contraseña en SSH?
    4. ¿Qué es el reenvío del agente en SSH y cuándo es riesgoso?
    5. ¿SSH reemplaza a una VPN?
  12. Referencias

No es solo una terminal remota: es la base de cómo Git transfiere código, cómo Ansible configura servidores y cómo millones de pipelines de CI/CD despliegan sin exponer una sola contraseña en la red.

TL;DR

  • SSH cifra cada comando y contraseña entre tu terminal y el servidor remoto desde el primer intercambio de claves.
  • Diffie-Hellman negocia una clave de sesión efímera antes de que viaje un solo byte de autenticación.
  • Un par de llaves ed25519 reemplaza la contraseña y bloquea ataques de fuerza bruta por diccionario.
  • ssh-agent y ControlMaster reutilizan una conexión ya autenticada para no repetir el intercambio en cada comando.
  • Centralizar el acceso con un bastion host evita exponer servidores internos directamente a internet.

¿Qué es el protocolo SSH?

El protocolo SSH es un protocolo de red criptográfico que permite abrir una sesión de terminal, transferir archivos o reenviar puertos entre dos máquinas a través de un canal cifrado y autenticado. Reemplaza a telnet, rlogin y rsh, que enviaban credenciales sin ningún tipo de protección.

Su nombre completo, Secure Shell, viene de que originalmente solo reemplazaba el shell remoto inseguro de Unix. Hoy el estándar vigente, conocido como SSH-2 y descrito en la RFC 4253, cubre mucho más que una terminal: copia de archivos vía SFTP, reenvío de puertos arbitrarios y hasta el montaje de sistemas de archivos remotos con SSHFS. Por defecto escucha en el puerto 22, aunque cualquier administrador puede cambiarlo.

Tatu Ylönen, investigador de la Universidad Tecnológica de Helsinki, creó la primera versión en 1995 después de que un ataque de rastreo de contraseñas afectara a su red universitaria. La implementación que terminó dominando el mercado es OpenSSH, desarrollada por el proyecto OpenBSD desde 1999 y preinstalada hoy en prácticamente todas las distribuciones de Linux, en macOS y, desde 2018, también en Windows.

Por qué importa el acceso remoto cifrado

El protocolo SSH se volvió el estándar de facto porque resuelve tres problemas a la vez: confidencialidad, porque nadie que intercepte el tráfico ve las contraseñas ni los comandos; integridad, porque cualquier alteración de un paquete en tránsito se detecta y corta la conexión; y autenticación mutua, porque el servidor también demuestra su identidad al cliente, no solo al revés.

Esa combinación lo convirtió en un requisito casi universal de cumplimiento normativo: estándares como PCI-DSS exigen acceso administrativo cifrado a cualquier sistema que procese pagos, y una auditoría SOC 2 típica revisa que las llaves de cuentas de servicio roten y que nadie comparta una misma llave entre varios operadores. Pero su peso real está en la automatización: Git usa SSH para autenticar cada push sin pedir contraseña, Ansible ejecuta sus módulos conectándose por SSH a cada host del inventario, y la mayoría de los runners de GitHub Actions o GitLab CI despliegan a producción con una llave SSH de un solo propósito.

OpenSSH es la implementación de referencia del protocolo desde que el proyecto OpenBSD la liberó en 1999. Foto de Albert Stoynov en Unsplash

Cómo funciona SSH por dentro: intercambio de claves y autenticación

La capa de transporte SSH: cómo se arma el canal cifrado

Antes de que el cliente envíe una sola credencial, SSH negocia un canal seguro en lo que se conoce como la capa de transporte. El cliente abre una conexión TCP al puerto 22, ambos extremos intercambian su versión de protocolo y la lista de algoritmos que soportan (cifrado simétrico, función hash para integridad, algoritmo de intercambio de claves) y acuerdan cuál usar.

Con los algoritmos ya elegidos, cliente y servidor ejecutan un intercambio Diffie-Hellman: cada uno genera un par de valores efímeros, los combina matemáticamente y ambos llegan al mismo secreto compartido sin haberlo transmitido nunca por la red. Ese secreto deriva la clave simétrica que cifra el resto de la sesión. El servidor firma ese intercambio con su clave de host (RSA, ed25519 u otra) para probar que es quien dice ser; el cliente verifica esa firma contra la huella que tiene guardada en ~/.ssh/known_hosts o, si es la primera conexión, la acepta bajo el modelo de confianza en el primer uso (TOFU).

sequenceDiagram
    participant C as Cliente
    participant S as Servidor
    C->>S: abre conexion TCP al puerto 22
    S-->>C: anuncia version y algoritmos soportados
    C->>S: elige algoritmos y arranca Diffie-Hellman
    Note over C,S: se deriva una clave de sesion efimera
    S-->>C: firma el intercambio con su clave de host
    C->>S: envia su llave publica para autenticarse
    S-->>C: verifica la firma y concede acceso

Autenticación en SSH: llave pública, contraseña o certificados

Una vez que el canal está cifrado, arranca la autenticación propiamente dicha. Con autenticación por llave pública, el cliente le demuestra al servidor que posee la llave privada correspondiente a una pública ya registrada en ~/.ssh/authorized_keys, firmando un desafío que el servidor verifica; la llave privada nunca sale de la máquina del cliente. Con autenticación por contraseña, el texto viaja dentro del túnel ya cifrado, pero sigue siendo vulnerable a fuerza bruta si el servidor no limita los intentos. Con certificados, una autoridad firma las llaves de usuarios y de hosts, así que un servidor confía en cualquier llave firmada por esa autoridad sin necesidad de mantener una lista manual de llaves autorizadas.

flowchart LR
    A["Cliente intenta autenticarse"] --> B{"Hay llave publica aceptada?"}
    B -->|"Si"| C["Autenticacion por llave publica"]
    B -->|"No"| D{"Password auth habilitado en el servidor?"}
    D -->|"Si"| E["Solicita contrasena por el canal cifrado"]
    D -->|"No"| F["Conexion rechazada"]
💡 Tip: Preferí llaves ed25519 sobre RSA: son más cortas, más rápidas de verificar y GitHub las recomienda como opción por defecto desde hace años.

Ejemplos prácticos con SSH

Generar un par de llaves es el primer paso para dejar de depender de contraseñas:

$ ssh-keygen -t ed25519 -C "ana@portatil"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/ana/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/ana/.ssh/id_ed25519
Your public key has been saved in /home/ana/.ssh/id_ed25519.pub

El comando crea dos archivos: id_ed25519 (privado, nunca se comparte) e id_ed25519.pub (pública, la que vas a copiar a cada servidor). Con la llave generada, copiarla al servidor es un solo comando:

$ ssh-copy-id -i ~/.ssh/id_ed25519.pub ana@servidor-web01
Number of key(s) added: 1

Now try logging into the machine, with: "ssh 'ana@servidor-web01'"
and check to make sure that only the key(s) you wanted were added.

A partir de ahí, ssh ana@servidor-web01 entra sin pedir contraseña. Para no repetir usuario y host cada vez, ~/.ssh/config guarda atajos:

Host web01
    HostName servidor-web01.redinterna.local
    User ana
    IdentityFile ~/.ssh/id_ed25519
    ProxyJump bastion

Host bastion
    HostName bastion.redinterna.local
    User ana
    IdentityFile ~/.ssh/id_ed25519

Con esa configuración, ssh web01 conecta primero al bastion y desde ahí salta a servidor-web01 en un solo comando, sin que tengas que autenticarte dos veces a mano.

Cómo empezar

En Linux y macOS, el cliente y el servidor de OpenSSH vienen preinstalados o a un apt install openssh-server de distancia; en Windows 10 (1809 en adelante) y Windows 11, el cliente OpenSSH es una característica opcional activada por defecto. Estos pasos asumen un servidor Linux con systemd y un cliente Linux o macOS:

  1. Generá el par de llaves: ssh-keygen -t ed25519 -C "tu_usuario@tu_maquina".
  2. Copiá la llave pública al servidor: ssh-copy-id usuario@servidor.
  3. Confirmá que entrás sin contraseña: ssh usuario@servidor.
  4. En el servidor, editá /etc/ssh/sshd_config y ajustá PasswordAuthentication no y PermitRootLogin no.
  5. Aplicá el cambio: sudo systemctl restart sshd.
  6. Verificá que la configuración activa de verdad rechaza contraseñas: sudo sshd -T | grep passwordauthentication debe imprimir passwordauthentication no.

Casos de uso reales

Un repositorio clonado con git clone [email protected]:usuario/repo.git usa SSH para autenticar cada push sin pedir usuario ni contraseña, siempre que la llave pública esté registrada en la cuenta. Herramientas de transferencia como scp y rsync -e ssh reutilizan el mismo canal cifrado para mover archivos completos o solo las diferencias.

El reenvío de puertos es otro uso frecuente: ssh -L 5432:localhost:5432 ana@bastion expone en tu máquina local una base de datos que solo es accesible desde la red interna, sin abrir ese puerto a internet ni instalar una VPN para una tarea puntual. ssh -D 1080 ana@bastion cumple una función parecida, pero crea un proxy SOCKS que enruta cualquier aplicación a través del túnel.

Ansible se apoya en SSH para cada tarea que ejecuta contra un inventario de servidores; la extensión Remote-SSH de Visual Studio Code abre un entorno de desarrollo completo dentro de un servidor remoto reusando la misma conexión; y la mayoría de los runners de integración continua despliegan a producción con una llave de un solo propósito, limitada en authorized_keys a un único comando permitido.

La transferencia por SFTP viaja dentro del mismo canal cifrado que abre una sesión de SSH.

Errores comunes y buenas prácticas

Permission denied (publickey) casi siempre significa permisos incorrectos, no una llave mala: el servidor ignora authorized_keys si el directorio ~/.ssh no tiene permisos 700 o el archivo no tiene 600. Corregilo con chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys.

El aviso WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED no es un error cosmético: significa que la huella del servidor cambió, lo que puede ser un reinicio legítimo con una llave nueva o un ataque de intermediario. Confirmá la huella por un canal distinto antes de borrar la entrada vieja de known_hosts con ssh-keygen -R.

Otro error frecuente, sobre todo con muchas llaves cargadas en el agente, es Too many authentication failures: el servidor corta la conexión después de un número limitado de intentos porque el cliente ofrece cada llave del agente antes de probar la indicada en IdentityFile. Agregar IdentitiesOnly yes a la entrada del host en ~/.ssh/config fuerza a usar solo la llave configurada para ese host.

Las llaves RSA de 1024 bits y las llaves DSA ya están deprecadas en OpenSSH moderno por ser criptográficamente débiles; migrá a ed25519 o, si necesitás compatibilidad con sistemas viejos, a RSA de al menos 3072 bits. Y el error más silencioso de todos es editar sshd_config y olvidar reiniciar el servicio: los cambios no toman efecto hasta el restart, así que correr sudo sshd -T después de cada cambio evita confirmar en falso que algo quedó aplicado.

Comparativa con alternativas

OpciónCifradoCuándo usarlaLimitación
SSHCifrado de extremo a extremo desde el intercambio inicialTerminal remota, túneles, Git, SFTPRequiere una conexión TCP estable al puerto configurado
TelnetNinguno, texto planoSolo laboratorios aislados sin red externaCualquiera que intercepte el tráfico ve las credenciales
MoshUsa SSH para el login inicial, luego cifra sobre UDPConexiones móviles o satelitales inestablesNo soporta reenvío de puertos ni X11
VPN + escritorio remotoCifra toda la red, no solo una sesiónAcceso a escritorios gráficos completosMás compleja de desplegar y mantener que una llave SSH

Profundizando

Los certificados SSH resuelven el problema de escala de las llaves sueltas: en vez de distribuir cada llave pública a cada servidor, una autoridad certificadora firma las llaves de usuario con ssh-keygen -s ca_key -I id_usuario -n ana -V +52w id_ed25519.pub, y cada servidor solo necesita confiar en la llave pública de esa autoridad. El certificado además expira solo, algo que una llave sin fecha de vencimiento nunca hace por sí sola.

El reenvío del agente SSH (agent forwarding, activado con ssh -A) deja que un servidor intermedio use tu llave privada para autenticarse en un tercer servidor, sin que la llave viaje físicamente. Es cómodo para saltar a través de un bastion host, pero si ese bastion está comprometido, cualquier proceso con privilegios suficientes ahí puede pedirle al agente que firme en tu nombre mientras la sesión esté activa.

⚠️ Ojo: Activá el reenvío del agente solo en bastiones que confiés tanto como en tu propia laptop; de lo contrario, usá ProxyJump sin forwarding, como en el ejemplo de configuración de más arriba.
flowchart TD
    A["Tu laptop"] --> B["Bastion host (jump box)"]
    B --> C["Servidor interno web01"]
    B --> D["Servidor interno db01"]
    subgraph "Red privada sin salida a internet"
    C
    D
    end

Para sesiones repetidas al mismo host, ControlMaster reutiliza la conexión TCP y el intercambio de claves ya hechos: agregando ControlMaster auto y ControlPath ~/.ssh/sockets/%r@%h-%p a ~/.ssh/config, la segunda conexión y las siguientes abren en milisegundos porque comparten el socket de la primera. SSHFS, por su parte, monta un directorio remoto como si fuera local reusando la misma sesión cifrada: útil para editar archivos de un servidor con herramientas gráficas de escritorio, aunque cada operación de archivo paga la latencia de ir y volver por la red. Versiones recientes de OpenSSH también ofrecen un intercambio de claves híbrido poscuántico, pensado para que el tráfico cifrado hoy no se vuelva legible dentro de una década si alguien lo grabó y después tiene acceso a una computadora cuántica capaz de romper Diffie-Hellman clásico.

📖 Resumen en Telegram: Ver resumen

Tu próximo paso: generá un par de llaves ed25519 en tu máquina, copiá la pública a un servidor de prueba con ssh-copy-id y confirmá con ssh -v que la línea Authentication succeeded (publickey) aparece antes de que se te pida cualquier contraseña.

📬 Recibí lo nuevo en tu email

Te avisamos de artículos grandes (1-2 por mes).

Preguntas frecuentes

¿Qué diferencia hay entre SSH y Telnet?

SSH cifra toda la sesión, incluidas las credenciales; Telnet envía todo en texto plano, así que cualquiera con acceso a la red puede leer contraseñas y comandos con un simple capturador de paquetes.

¿Cómo genero un par de llaves SSH seguras?

Con ssh-keygen -t ed25519: es el tipo de llave recomendado hoy por ser rápido de verificar y resistente a los ataques conocidos contra RSA de claves cortas.

¿Es necesario desactivar la autenticación por contraseña en SSH?

No es obligatorio, pero sí recomendable en cualquier servidor expuesto a internet: elimina por completo el riesgo de fuerza bruta contra contraseñas, incluso débiles o reutilizadas.

¿Qué es el reenvío del agente en SSH y cuándo es riesgoso?

Es la función que permite usar tu llave privada local para autenticarte en un tercer servidor a través de uno intermedio. Es riesgosa si el servidor intermedio está comprometido, porque cualquiera con privilegios ahí puede pedirle al agente que firme en tu nombre.

¿SSH reemplaza a una VPN?

No del todo: SSH cifra una sesión o un puerto específico, mientras que una VPN cifra todo el tráfico de red del dispositivo. Para administrar un servidor puntual, SSH alcanza; para acceder a una red corporativa completa, una VPN sigue siendo necesaria.

Referencias

  • OpenSSH: sitio oficial del proyecto y la implementación de referencia del protocolo.
  • RFC 4253 (IETF): especificación de la capa de transporte de SSH-2.
  • GitHub Docs: guía oficial para generar y usar llaves SSH con GitHub.
  • Wikipedia: historia y resumen técnico del protocolo Secure Shell.

📱 ¿Te gusta este contenido? Únete a nuestro canal de Telegram @programacion donde publicamos a diario lo más relevante de tecnología, IA y desarrollo. Resúmenes rápidos, contenido fresco todos los días.

Imagen destacada: Foto de Sasun Bughdaryan en Unsplash

¿Te sirvió? ¿Te dio otro error? Contalo abajo: las preguntas se responden y le sirven al siguiente que llegue.

Dejar un comentario

Clara Vásquez

Analista de ciberseguridad enfocada en vulnerabilidades críticas, zero-days y amenazas emergentes. Cubre CVEs de alto impacto, análisis de malware, incidentes de ransomware y tendencias de seguridad para LATAM.

0 Comentarios

Deja un comentario

Marcador de posición del avatar

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Podés incluir código entre <code>…</code> o, para varias líneas, <pre><code>…</code></pre>.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.