Conectarse a un servidor por SSH: Windows, macOS y Linux

Publicado el 16 min de lectura

La primera conexión SSH paso a paso: PuTTY y OpenSSH en Windows, Terminal en macOS y Linux, cómo verificar bien la huella digital, transferir archivos y resolver los mensajes de error habituales.

Un servidor recién contratado llega sin pantalla y sin teclado. La única vía de entrada pasa por SSH, el protocolo Secure Shell. Este artículo acompaña la primera conexión desde tres sistemas operativos, explica la pregunta sobre la huella digital (que casi todos los principiantes descartan sin leerla) y muestra cómo transferir archivos. Al final está la parte que la mayoría de las guías omite: qué hacer cuando no funciona y en qué notas que realmente ha funcionado.

Todos los datos están comprobados en Debian 13, Debian 12, Ubuntu 24.04 LTS y Ubuntu 22.04 LTS. Donde los cuatro se diferencian, se indica expresamente. Los comandos en el servidor se ejecutan como root. En tu propio equipo, en cambio, trabajas con una cuenta de usuario normal, por eso allí cada comando que modifica el sistema lleva delante un sudo.

Lo que necesitas antes de la primera conexión

Bastan tres datos: la dirección IP del servidor, el nombre de usuario y la contraseña o la clave privada. En KernelHost encuentras la IP y los datos de acceso en el área de cliente una vez terminado el aprovisionamiento. En un servidor KVM root o un servidor dedicado recién instalado, el usuario predeterminado suele ser root.

Como cuarto dato se añade el puerto. El estándar es el 22. Solo necesitas un número distinto si lo has cambiado tú mismo o si la imagen lo ha movido. Ten presente desde ya una trampa que ahorra tiempo más adelante: ssh escribe el puerto en minúscula (-p) y scp lo escribe en mayúscula (-P).

En los ejemplos aparece siempre 203.0.113.10. Esta dirección está reservada oficialmente para documentación y no existe. Sustitúyela por la IP de tu servidor.

La primera conexión en Linux y macOS

Ambos sistemas traen el cliente OpenSSH incluido. En macOS abres Terminal (en la carpeta Utilidades), en Linux cualquier ventana de terminal. El comando es idéntico en los dos:

ssh root@203.0.113.10

Si SSH escucha en otro puerto:

ssh -p 2222 root@203.0.113.10

Si tu sistema no conoce ssh, algo que ocurre en instalaciones mínimas o en contenedores muy ligeros, lo compruebas e instalas así:

ssh -V
sudo apt update
apt-cache policy openssh-client
sudo apt install -y openssh-client

El orden está elegido a propósito. ssh -V es el comando de comprobación y no una prueba de éxito: si la shell responde con bash: ssh: command not found, falta el paquete openssh-client y lo instalas después con sudo apt install -y openssh-client. sudo apt update va antes de apt-cache policy openssh-client, porque ese comando se queda vacío sin las listas de paquetes leídas o solo informa Installed: (none). Y el sudo no es un adorno: sin permisos de administrador, apt aborta con Could not open lock file /var/lib/apt/lists/lock.

ssh -V escribe la versión en la salida de error, no en la salida estándar. No es un fallo, siempre ha sido así. En Debian 13 ves OpenSSH_10.0p2, en Debian 12 OpenSSH_9.2p1, en Ubuntu 24.04 OpenSSH_9.6p1 y en Ubuntu 22.04 OpenSSH_8.9p1. Estas cifras importan más adelante, porque el comportamiento de scp cambió justo entre esas versiones.

La huella digital, y por qué no deberías descartarla sin más

En el primer intento de conexión, SSH pregunta:

The authenticity of host '203.0.113.10 (203.0.113.10)' can't be established.
ED25519 key fingerprint is SHA256:qWU2Zx9mF7hLtHkQ4gRXn0aVbC3sYpJ8dKe1TmNoPU.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Lo que ocurre aquí: cada servidor SSH genera durante su instalación un par de claves propio, la llamada clave de host. La huella digital es una suma de verificación corta de la parte pública. Tu cliente todavía no conoce este servidor y por eso no puede garantizar que al otro extremo esté realmente tu servidor y no alguien que se ha colocado en medio.

Si escribes yes, la huella digital se guarda en ~/.ssh/known_hosts. A partir de ahí, tu cliente comprueba en silencio, en cada conexión posterior, si el servidor presenta la misma clave. Esa única pregunta es, por tanto, el momento en el que se construye todo el modelo de confianza. Después ya no vuelve a preguntar nadie.

Comprobarla de verdad solo es posible por una segunda vía independiente. En un servidor KVM, la consola del área de cliente es la opción natural: allí inicias sesión de forma local, sin red de por medio, y pides que se muestre la huella digital.

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

La salida tiene este aspecto:

256 SHA256:qWU2Zx9mF7hLtHkQ4gRXn0aVbC3sYpJ8dKe1TmNoPU root@server (ED25519)

Si la parte que sigue a SHA256: coincide con lo que muestra tu cliente, todo está en orden. Si quieres probar el formato sin riesgo, genera en local una clave desechable:

ssh-keygen -t ed25519 -f /tmp/demo -N "" -C demo
ssh-keygen -lf /tmp/demo.pub

Dos apuntes de la práctica. Primero: un servidor suele tener varias claves de host (ED25519, ECDSA, RSA). Normalmente se muestra la clave ED25519, porque los clientes modernos la prefieren. Si comparas por error con ssh_host_rsa_key.pub, no encaja nada aunque todo sea correcto. Segundo: StrictHostKeyChecking=no desactiva la comprobación por completo y no es una solución, sino apagar la función de seguridad. Si necesitas automatizar, la opción correcta es -o StrictHostKeyChecking=accept-new: acepta automáticamente servidores desconocidos, pero sigue avisando cuando algo cambia.

Windows: el cliente OpenSSH integrado

Desde Windows 10 versión 1809, Microsoft incluye el mismo cliente OpenSSH que usan Linux y macOS. Así que ya no necesitas ningún programa adicional. Abre PowerShell, el símbolo del sistema o Windows Terminal y escribe el mismo comando de antes:

ssh root@203.0.113.10

En Windows 10 y Windows 11, el cliente es un componente opcional que en la mayoría de las instalaciones ya viene activo. Si no lo está, lo compruebas e instalas en una PowerShell con permisos de administrador:

Get-WindowsCapability -Online -Name OpenSSH.Client*
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

La alternativa pasa por Configuración, Sistema, Características opcionales. Los programas quedan después en C:\Windows\System32\OpenSSH\, y tu configuración junto con las claves de host conocidas en %USERPROFILE%\.ssh\, es decir, normalmente en C:\Users\Name\.ssh\known_hosts.

La versión de Windows va por detrás de la de Linux. En instalaciones actuales de Windows 11, ssh -V suele informar OpenSSH_for_Windows_9.5p2. Para el día a día es más que suficiente.

Sí que hay una particularidad: los permisos de archivo de Windows. Si guardas una clave privada que también pueden leer otras cuentas, SSH se niega a trabajar con Permissions for 'C:\Users\Name\.ssh\id_ed25519' are too open. Eso se repara así:

icacls "$env:USERPROFILE\.ssh\id_ed25519" /inheritance:r /grant:r "$($env:USERNAME):(R)"

Windows: PuTTY

PuTTY fue durante años la vía estándar en Windows y para muchos lo sigue siendo. La versión actual es la 0.84, de mayo de 2026. Descárgala exclusivamente desde la página del autor (chiark.greenend.org.uk) y no desde portales de descargas, porque en el pasado han circulado varias veces versiones falsificadas de PuTTY con robo de contraseñas incorporado.

El procedimiento: en Host Name (or IP address) introduces la IP, en Port el 22, tipo de conexión SSH y luego Open. Si quieres conservar la conexión, escribe antes un nombre en Saved Sessions y pulsa Save. El nombre de usuario lo pregunta PuTTY ya dentro de la ventana, o lo dejas guardado en Connection, Data, Auto-login username.

En el primer establecimiento de conexión aparece la ventana PuTTY Security Alert con el aviso de que la clave de host no está en la caché. Muestra la misma huella SHA256 que enseña OpenSSH, así que puedes comparar las dos una a una. Accept guarda la clave de forma permanente, Connect Once conecta solo esta vez sin guardar nada y Cancel cancela.

Diferencia importante frente a OpenSSH: PuTTY no tiene ningún archivo known_hosts. Las claves acaban en el registro, bajo HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys. Quien quiera limpiar ahí después de reinstalar su servidor, abre regedit y borra la entrada correspondiente. Y otra trampa más: PuTTY usa un formato de clave propio (.ppk). Una clave de OpenSSH tienes que convertirla con PuTTYgen a través de Conversions, Import key antes de que PuTTY pueda utilizarla.

Transferir archivos con scp y sftp

scp copia archivos como cp, solo que a través de la red. Subir un archivo:

scp backup.tar.gz root@203.0.113.10:/root/

Descargar un archivo (el punto del final significa: al directorio actual):

scp root@203.0.113.10:/var/log/syslog .

Un directorio completo, y con un puerto distinto:

scp -r website root@203.0.113.10:/var/www/
scp -P 2222 backup.tar.gz root@203.0.113.10:/root/

sftp es la variante interactiva y resulta práctica cuando primero quieres ver qué hay y dónde está:

sftp root@203.0.113.10

Después trabajas con ls, cd, get archivo, put archivo en el lado remoto, y con lls, lcd en tu propio equipo. bye termina la sesión. Los dos programas existen también en Windows, forman parte de la misma instalación. PuTTY trae sus propios equivalentes con pscp y psftp; quien prefiera una interfaz gráfica, usa WinSCP.

Y aquí está la diferencia con la que muchos tropiezan: desde OpenSSH 9.0, scp ya no transfiere internamente por el viejo protocolo SCP, sino por SFTP. Esto afecta a Debian 13, Debian 12 y Ubuntu 24.04. Ubuntu 22.04 con OpenSSH 8.9 todavía usa el procedimiento antiguo. En la práctica lo notas en dos puntos. Los comodines como *.log en una ruta remota se evalúan de otra manera, y si el otro extremo no ofrece SFTP (por ejemplo, equipos de red o un chroot restringido), la transferencia aborta con:

subsystem request failed on channel 0
scp: Connection closed

La solución de emergencia es scp -O, que fuerza el protocolo antiguo. La solución limpia es activar en el servidor la línea Subsystem sftp /usr/lib/openssh/sftp-server dentro de /etc/ssh/sshd_config. En Debian y Ubuntu, el paquete necesario openssh-sftp-server se instala como dependencia de openssh-server, así que solo falta en instalaciones montadas de forma muy peculiar.

El aviso de known_hosts después de una reinstalación

Reinstalas tu servidor, te conectas y, en lugar del prompt, aparece un muro de signos de exclamación:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!      @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
Offending ED25519 key in /home/tom/.ssh/known_hosts:7
Host key for 203.0.113.10 has changed and you have requested strict checking.
Host key verification failed.

Eso no es un fallo, sino justo la función para la que escribiste yes la primera vez. En una reinstalación el servidor genera nuevas claves de host y la entrada antigua ya no encaja. El mismo mensaje aparece también, por cierto, cuando la misma dirección IP se ha cedido a otro cliente o cuando has arrancado una copia del servidor.

Antes de borrar la entrada, piensa un momento: ¿acabas de reinstalar de verdad? Si es así, elimina la línea antigua:

ssh-keygen -R 203.0.113.10

Con un puerto distinto, la entrada va entre corchetes; si no, el comando no encuentra nada:

ssh-keygen -R "[203.0.113.10]:2222"

Si la entrada existe siquiera, te lo dice ssh-keygen -F 203.0.113.10. Mirar con un editor de texto suele servir de poco, porque Debian y Ubuntu guardan los nombres de host en known_hosts como hash de forma predeterminada. Allí no puedes buscar, y por eso están los dos comandos de arriba.

En el siguiente intento de conexión, SSH vuelve a preguntar por la huella digital. Ese es el momento de contrastarla otra vez a través de la consola del área de cliente, en lugar de teclear yes por reflejo. Justo esa segunda oportunidad es el sentido de todo el aviso.

En Windows, ssh-keygen -R funciona igual en PowerShell. Si usas PuTTY, borras en su lugar la entrada del registro o confirmas en la ventana WARNING - POTENTIAL SECURITY BREACH! con Accept que la nueva clave debe guardarse.

Los mensajes de error literales, y qué hay detrás de cada uno

Los siguientes mensajes cubren, por experiencia, la gran mayoría de los casos.

  • Connection refused: la conexión llegó hasta el servidor, pero en ese puerto no escucha nadie. O bien el servicio SSH no está en marcha, o bien escucha en otro puerto. Desde la consola compruebas con systemctl status ssh y ss -tlnp si el puerto 22 está ocupado.
  • Connection timed out: no llegó ninguna respuesta. Es típico de una IP equivocada, un servidor apagado o un firewall que descarta los paquetes en lugar de rechazarlos. Revisa la dirección IP carácter por carácter y las reglas del firewall.
  • Permission denied, please try again.: el nombre de usuario o la contraseña no son correctos. La causa más frecuente es un usuario equivocado, por ejemplo root en lugar de ubuntu o al revés.
  • Permission denied (publickey).: el servidor no acepta contraseñas en absoluto, solo claves. En muchas imágenes de cloud viene así de fábrica. O bien depositas tu clave pública, o bien permites temporalmente PasswordAuthentication yes desde la consola.
  • Too many authentication failures: tu agente ofrece demasiadas claves seguidas y el servidor corta antes. Solución: ssh -o IdentitiesOnly=yes -i ~/.ssh/mi_clave root@203.0.113.10.
  • WARNING: UNPROTECTED PRIVATE KEY FILE! junto con Permissions 0644 for ... are too open: la clave privada es legible para otros y por eso se ignora. En Linux y macOS ayuda un chmod 600 sobre el archivo de la clave, en Windows el comando icacls de más arriba.
  • Bad owner or permissions on ~/.ssh/config: la misma causa, solo que para el archivo de configuración. chmod 600 ~/.ssh/config.
  • kex_exchange_identification: read: Connection reset by peer: la conexión se cortó en mitad del saludo inicial. En la práctica es casi siempre un bloqueo automático tras varios intentos fallidos, por ejemplo de fail2ban. Espera a que termine el bloqueo o levántalo desde la consola con fail2ban-client unban DIRECCION_IP.
  • no matching host key type found. Their offer: ssh-rsa: el servidor solo ofrece claves RSA firmadas con SHA-1. Desde OpenSSH 8.8 se rechazan, y eso afecta como cliente a los cuatro sistemas tratados aquí. La respuesta correcta es actualizar el servidor antiguo, no debilitar el cliente.
  • client_loop: send disconnect: Broken pipe: la sesión se quedó dormida y un firewall o un router la retiró. Añade en ~/.ssh/config la línea ServerAliveInterval 60 y la conexión se mantiene viva.

Regla básica para cualquier trabajo sobre la configuración de SSH: deja abierta una sesión que funcione mientras haces pruebas. Un reinicio del servicio SSH no expulsa las conexiones existentes. Si te dejas fuera con una configuración defectuosa, vuelves a entrar por esa segunda sesión o por la consola del área de cliente.

Diferencias entre Debian 13, Debian 12, Ubuntu 24.04 y 22.04

Para el simple establecimiento de la conexión, los cuatro se comportan igual. En cuanto cambias algo en el servidor, se separan.

Activación por socket en lugar de servicio permanente

Ubuntu ya no arranca el servicio SSH de forma permanente desde la 22.10, sino solo con la primera conexión entrante. De ello se encarga ssh.socket, no ssh.service. Esto vale para Ubuntu 24.04 y, en sistemas recién instalados, también para Debian 13. Debian 12 sigue usando el clásico servicio permanente.

Dos consecuencias. Primera: allí, un Port 2222 en /etc/ssh/sshd_config no cambia nada, porque ya no es sshd quien escucha en el puerto, sino systemd. El puerto va entonces en un archivo complementario que creas con systemctl edit ssh.socket, con ListenStream= para restablecer el valor predeterminado y una segunda línea ListenStream=2222. Segunda: systemctl reload ssh puede abortar con fatal: Cannot bind any address en sistemas Debian 13 recién instalados. En ese caso usa systemctl restart ssh.service o desactiva del todo la activación por socket con systemctl disable --now ssh.socket.

Algoritmos y lastres del pasado

Debian 13 trae OpenSSH 10.0 y ya no conoce en absoluto las claves DSA, ni siquiera mediante opciones de compatibilidad. Quien todavía use una clave antiquísima, tiene que generar antes una nueva. Los clientes muy recientes (macOS 26.3 y posteriores con OpenSSH 10.1 o superior) muestran además un aviso cuando el servidor no ofrece un intercambio de claves resistente a la computación cuántica:

** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.

Es un aviso, no un error, y la conexión se establece igualmente. Desaparece en cuanto el servidor es lo bastante reciente. Debian 12 y Ubuntu 24.04 cumplen el requisito; Ubuntu 22.04 con OpenSSH 8.9, en la configuración estándar, no.

Unas palabras sobre versiones antiguas

Debian 10 está sin soporte desde junio de 2024 y Ubuntu 20.04 desde mayo de 2025. Ninguno de los dos recibe ya actualizaciones de seguridad para OpenSSH. Un servidor accesible por SSH desde internet no debería seguir ahí.

Escribir menos con ~/.ssh/config

En cuanto administras más de un servidor, el archivo de configuración compensa. Créalo y ajusta los permisos, porque si no SSH lo rechaza:

mkdir -p ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/config
chmod 600 ~/.ssh/config

Una entrada dentro del archivo tiene este aspecto:

Host web1
    HostName 203.0.113.10
    User root
    Port 2222
    ServerAliveInterval 60

Después basta con ssh web1, y también funciona así scp archivo web1:/root/. El cliente de Windows entiende el mismo archivo, que allí está en %USERPROFILE%\.ssh\config.

No hace falta adivinar si tu bloque surte efecto de verdad. ssh -G muestra la configuración definitiva sin establecer ninguna conexión:

ssh -G localhost

Sustituye localhost por tu nombre corto y verás negro sobre blanco, en las líneas hostname, user y port, lo que SSH va a usar. Una errata en el nombre de Host salta así en dos segundos, en lugar de después de veinte minutos buscando el fallo.

Cómo notas que realmente ha funcionado

Que aparezca un prompt todavía no es ninguna prueba. Con varias ventanas abiertas, más de uno ha lanzado un rm en el servidor equivocado. Cuatro comandos cortos aclaran la situación:

hostname
id
cat /etc/os-release
uptime

hostname tiene que mostrar el nombre de tu servidor, no el de tu portátil. id muestra uid=0(root) cuando trabajas como root. cat /etc/os-release indica la distribución y la versión, por ejemplo Debian GNU/Linux 13 (trixie) o Ubuntu 24.04.3 LTS. Y uptime encaja con el tiempo de funcionamiento de un servidor, no con el de un equipo de trabajo que se apaga cada noche.

La prueba más rápida para saber si estás realmente por SSH y no en un terminal local:

echo $SSH_CONNECTION

Si aparece una línea con cuatro valores (tu IP, tu puerto de origen, la IP del servidor y el puerto de destino), has iniciado sesión. Si queda vacía, estás escribiendo en tu propio equipo. La sesión se termina con exit o con la combinación de teclas Ctrl y D.

Cómo seguir a partir de aquí

El siguiente paso razonable es pasar de las contraseñas a las claves. Una clave SSH no se puede adivinar y, además, después puedes desactivar por completo el inicio de sesión con contraseña, con lo que la mayor parte de los intentos de ataque automatizados se queda sin efecto. Cómo se hace está en Configurar la autenticación por clave SSH. Después vienen el firewall y el bloqueo automático, descritos en Asegurar el servidor después de la instalación.

Para empezar vale esto: si ya has entrado una vez, has comprobado la huella digital y sabes cómo volver a entrar tras una reinstalación, la parte más difícil está hecha. Todo lo demás ocurre en una ventana que ya puedes abrir.

Preguntas frecuentes

¿Cómo me conecto por SSH en Windows sin instalar PuTTY?
Windows 10 a partir de la versión 1809 y Windows 11 incluyen el mismo cliente OpenSSH que usan Linux y macOS. Abre PowerShell o Windows Terminal y escribe ssh root@DIRECCION_IP. Si el comando no existe, lo instalas en una PowerShell con permisos de administrador mediante Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 o desde Configuración, Sistema, Características opcionales.
¿Qué significa la pregunta por la huella digital en la primera conexión?
SSH todavía no conoce el servidor y no puede garantizar que al otro extremo esté realmente el tuyo. La huella digital es una suma de verificación de la clave del servidor. Si confirmas con yes, se guarda en ~/.ssh/known_hosts y se comprueba automáticamente en cada conexión posterior. Puedes contrastarla desde la consola del área de cliente con ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub.
Tras la reinstalación, SSH avisa de REMOTE HOST IDENTIFICATION HAS CHANGED. ¿Qué hago?
En una reinstalación el servidor genera nuevas claves de host, así que la entrada guardada ya no encaja. Elimínala con ssh-keygen -R DIRECCION_IP, y con ssh-keygen -R "[DIRECCION_IP]:2222" cuando el puerto es distinto. En el siguiente intento de conexión SSH vuelve a preguntar por la huella digital, que entonces contrastas con la salida de la consola del servidor. PuTTY, en cambio, guarda las claves de host en el registro, bajo HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys.
¿Por qué ssh usa -p y scp usa -P, pero no al revés?
Es una peculiaridad histórica de OpenSSH: ssh espera el puerto como -p en minúscula y scp como -P en mayúscula, porque scp ya utiliza el -p minúsculo para conservar marcas de tiempo y permisos. Si confundes los dos, scp informa de una opción desconocida o intenta conectarse al puerto 22.
scp aborta con subsystem request failed on channel 0. ¿A qué se debe?
Desde OpenSSH 9.0, scp transfiere internamente por SFTP en lugar de por el viejo protocolo SCP. Esto afecta a Debian 13, Debian 12 y Ubuntu 24.04, mientras que Ubuntu 22.04 con OpenSSH 8.9 todavía usa el procedimiento antiguo. Si el otro extremo no ofrece SFTP, a corto plazo ayuda scp -O y de forma permanente la línea Subsystem activa en /etc/ssh/sshd_config.
¿Por qué no surte efecto el cambio de puerto en sshd_config bajo Ubuntu 24.04?
Ubuntu arranca SSH mediante activación por socket desde la 22.10, igual que los sistemas Debian 13 recién instalados. En el puerto escucha entonces systemd, no sshd, y por eso se ignora la entrada de sshd_config. El puerto va en un archivo complementario que creas con systemctl edit ssh.socket: una línea vacía ListenStream= para restablecer el valor predeterminado y debajo ListenStream=2222. Debian 12 sigue usando el servicio clásico, ahí basta con sshd_config.
¿En qué noto que he llegado realmente al servidor correcto?
Comprueba con hostname el nombre del servidor, con id la cuenta de usuario, con cat /etc/os-release la distribución y con uptime el tiempo de funcionamiento. Si estás conectado por SSH y no escribiendo en un terminal local te lo dice echo $SSH_CONNECTION: si ahí aparecen cuatro valores, la sesión es una conexión SSH real.

SSH Linux Windows macOS Debian Ubuntu PuTTY scp sftp Administración de servidores