1. Autenticación con claves SSH
¿Por qué usar claves en lugar de contraseña?
La autenticación por clave pública/privada es más segura que una contraseña: la clave privada nunca viaja por la red, es prácticamente imposible de forzar por fuerza bruta, y permite automatizar conexiones (scripts, backups, CI/CD) sin escribir una contraseña cada vez.
El algoritmo ed25519 es el estándar recomendado hoy en día frente a RSA: genera claves más cortas, es más rápido de calcular, y ofrece un nivel de seguridad equivalente o superior a RSA de 3072/4096 bits. Solo deberías usar RSA si te conectas a sistemas muy antiguos que no soportan ed25519 (poco común en 2026).
Generar el par de claves
ssh-keygen -t ed25519 -C "tu_email@ejemplo.com"
El proceso te pedirá tres cosas:
- Ubicación del archivo. Por defecto es
~/.ssh/id_ed25519. Presiona Enter para aceptar, o especifica una ruta distinta si vas a manejar varias claves (ver sección de nombramiento más abajo). - Passphrase (frase de contraseña). Es una capa extra de seguridad: aunque alguien robe tu archivo de clave privada, no podrá usarla sin esta frase. Se recomienda fuertemente no dejarla vacía, salvo en casos muy específicos como automatizaciones no interactivas donde se gestiona la clave de otra forma (por ejemplo, con
ssh-agento un gestor de secretos). - Confirmación de la passphrase.
Al finalizar obtienes dos archivos:
| Archivo | Descripción | ¿Se comparte? |
|---|---|---|
id_ed25519 | Clave privada | Nunca, bajo ninguna circunstancia |
id_ed25519.pub | Clave pública | Sí, es la que se copia al servidor remoto |
Nombrando y organizando múltiples claves
Si te conectas a varios servidores o servicios (trabajo, GitHub, servidor personal, clientes), es una buena práctica no reutilizar la misma clave para todo. Generar claves con nombres descriptivos facilita la organización y limita el impacto si una clave se ve comprometida.
# Clave para un servidor de trabajo ssh-keygen -t ed25519 -C "trabajo@empresa.com" -f ~/.ssh/id_ed25519_trabajo # Clave para un servidor personal ssh-keygen -t ed25519 -C "personal@midominio.com" -f ~/.ssh/id_ed25519_personal # Clave para GitHub ssh-keygen -t ed25519 -C "github@midominio.com" -f ~/.ssh/id_ed25519_github
La flag -f (file) define la ruta y el nombre del archivo. Un patrón común y legible es:
id_ed25519_<proposito>
Esto evita confusiones cuando tienes el archivo ~/.ssh/config con múltiples hosts (lo veremos en la sección 1.3), ya que cada entrada puede apuntar a una clave distinta con IdentityFile.
Buena práctica adicional: incluye siempre un comentario significativo con -C (como el correo o el propósito de la clave). Este comentario queda visible al final de la clave pública y te ayuda a identificar a qué corresponde cada clave cuando revises authorized_keys en el servidor remoto.
Copiar la clave pública al servidor remoto
La forma más simple es con ssh-copy-id:
ssh-copy-id -i ~/.ssh/id_ed25519_trabajo.pub usuario@ip-o-dominio-remoto
- La flag
-iindica qué clave pública copiar (importante si tienes varias). - Te pedirá la contraseña del usuario remoto una última vez; después de esto, ya no la necesitarás.
Este comando agrega automáticamente el contenido de tu clave pública al final del archivo ~/.ssh/authorized_keys en el servidor remoto, creando el archivo y el directorio .ssh si no existen.
Método manual (si ssh-copy-id no está disponible, común en sistemas mínimos o BSD):
cat ~/.ssh/id_ed25519_trabajo.pub | ssh usuario@remoto "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Este comando crea el directorio .ssh con los permisos correctos, agrega la clave pública, y ajusta los permisos del archivo authorized_keys, todo en un solo paso.
Configurar alias corto en ~/.ssh/config
Escribir ssh usuario@192.168.1.50 -p 2222 -i ~/.ssh/id_ed25519_trabajo cada vez es tedioso. El archivo de configuración de SSH permite resumir todo esto en un alias.
nano ~/.ssh/config
Ejemplo con múltiples servidores:
# Servidor de trabajo
Host mi-servidor
HostName 192.168.1.50
User usuario
Port 22
IdentityFile ~/.ssh/id_ed25519_trabajo
# Servidor personal, con puerto no estándar
Host servidor-personal
HostName midominio.com
User admin
Port 2222
IdentityFile ~/.ssh/id_ed25519_personal
# GitHub (útil también para git sobre SSH)
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_github
Con esto, conectarte se reduce a:
ssh mi-servidor ssh servidor-personal
Opciones útiles adicionales dentro de un bloque Host:
Host mi-servidor
HostName 192.168.1.50
User usuario
IdentityFile ~/.ssh/id_ed25519_trabajo
ServerAliveInterval 60 # evita que la conexión se caiga por inactividad
ForwardAgent no # no reenvíes tu agente SSH salvo que lo necesites explícitamente
2. Transferencia de archivos bidireccional
Una vez configurado el acceso por clave y el alias, transferir archivos es sencillo porque tanto scp como rsync reutilizan la configuración de ~/.ssh/config.
2.1 Con scp (Secure Copy)
scp es ideal para transferencias puntuales y simples, cuando no necesitas sincronizar carpetas grandes de forma repetida.
Local → Remoto (subir archivos):
# Un solo archivo scp archivo.txt mi-servidor:/ruta/destino/ # Varios archivos a la vez scp archivo1.txt archivo2.txt mi-servidor:/ruta/destino/ # Una carpeta completa (-r = recursivo, necesario para directorios) scp -r carpeta_local/ mi-servidor:/ruta/destino/
Remoto → Local (bajar archivos):
# Un solo archivo scp mi-servidor:/ruta/remota/archivo.txt ./ # Una carpeta completa scp -r mi-servidor:/ruta/remota/carpeta/ ./destino_local/
Remoto → Remoto (entre dos servidores, desde tu máquina local que actúa de intermediaria):
scp -r servidor-a:/ruta/carpeta/ servidor-b:/ruta/destino/
Flags útiles de scp:
| Flag | Significado |
|---|---|
-r | Copia recursiva (necesaria para carpetas) |
-P | Puerto (en mayúscula, distinto a ssh -p) |
-C | Comprime los datos durante la transferencia |
-p | Preserva permisos y fechas de modificación |
2.2 Con rsync (recomendado para uso frecuente)
rsync es más potente que scp: solo transfiere las diferencias entre origen y destino, puede reanudar transferencias interrumpidas, y preserva metadatos de forma más completa. Es la herramienta ideal para backups, sincronización de proyectos, o carpetas grandes.
Local → Remoto:
rsync -avz carpeta_local/ mi-servidor:/ruta/destino/
Remoto → Local:
rsync -avz mi-servidor:/ruta/remota/ ./destino_local/
Significado de las flags principales:
| Flag | Significado |
|---|---|
-a | archive: modo archivo, conserva permisos, fechas, enlaces simbólicos y estructura de carpetas |
-v | verbose: muestra detalle de lo que se transfiere |
-z | compress: comprime los datos en tránsito (útil en redes lentas) |
-P | Combina --progress (barra de avance) y --partial (permite reanudar transferencias cortadas) |
-n o --dry-run | Simula la transferencia sin copiar nada, útil para verificar antes de ejecutar |
--delete | Elimina en destino los archivos que ya no existen en origen (sincronización exacta, usar con cuidado) |
Ejemplo con progreso y simulación previa:
# Primero, simula para ver qué se transferiría rsync -avzn --progress carpeta_local/ mi-servidor:/ruta/destino/ # Si todo se ve bien, ejecuta de verdad quitando la -n rsync -avz --progress carpeta_local/ mi-servidor:/ruta/destino/
⚠️ Detalle importante sobre la barra final (/):
# Copia el CONTENIDO de carpeta_local dentro de destino/ rsync -avz carpeta_local/ mi-servidor:/ruta/destino/ # Copia la CARPETA carpeta_local como subdirectorio dentro de destino/ rsync -avz carpeta_local mi-servidor:/ruta/destino/
Esta es una de las confusiones más comunes al empezar con rsync: la barra al final del origen decide si se copia el contenido o la carpeta completa como subdirectorio.
Especificar un puerto o clave distinta con rsync (cuando no usas ~/.ssh/config):
rsync -avz -e "ssh -p 2222 -i ~/.ssh/id_ed25519_personal" carpeta_local/ usuario@remoto:/ruta/destino/
La flag -e define el comando SSH que rsync usará por debajo.
2.3 ¿scp o rsync?
| Situación | Herramienta recomendada |
|---|---|
| Copiar un archivo suelto, una sola vez | scp |
| Sincronizar carpetas grandes repetidamente | rsync |
| Red inestable o transferencias largas | rsync (soporta reanudar) |
| Backups automatizados/programados | rsync |
| Simplicidad para tareas rápidas | scp |
3. Buenas prácticas: permisos correctos
SSH rechaza silenciosamente (o con errores poco claros) las conexiones por clave si los permisos de los archivos son demasiado abiertos. Esto es una medida de seguridad del propio protocolo: si cualquier usuario del sistema pudiera leer tu clave privada o modificar authorized_keys, la autenticación por clave perdería su propósito.
Ajusta los permisos así, tanto en local como en el servidor remoto:
chmod 700 ~/.ssh # Solo el dueño puede entrar a la carpeta chmod 600 ~/.ssh/id_ed25519* # Claves privadas: solo lectura/escritura del dueño chmod 644 ~/.ssh/*.pub # Claves públicas: pueden ser legibles por otros chmod 600 ~/.ssh/authorized_keys # Lista de claves autorizadas: privada chmod 600 ~/.ssh/config # Configuración: privada (puede contener rutas e IPs internas)
Resumen de por qué:
~/.sshcon700: nadie más que el dueño puede siquiera listar su contenido.- Clave privada con
600: si tuviera permisos de lectura para grupo u otros, SSH se niega a usarla y muestra un error de “permisos demasiado abiertos” (UNPROTECTED PRIVATE KEY FILE). authorized_keyscon600: evita que otro usuario del sistema remoto agregue su propia clave y obtenga acceso a tu cuenta.
Verificación y diagnóstico
Si una conexión por clave falla sin motivo aparente, el modo verbose es la primera herramienta de diagnóstico:
ssh -v mi-servidor # Nivel básico de detalle ssh -vvv mi-servidor # Máximo detalle, útil para depurar a fondo
Esto muestra paso a paso qué claves intenta el cliente, cuáles rechaza el servidor y por qué, permitiendo identificar rápidamente si el problema es de permisos, de ruta incorrecta en IdentityFile, o de configuración del propio servidor SSH.
Checklist rápido si algo no conecta:
- ¿Los permisos de
.sshy las claves son correctos en ambos equipos? (ver arriba) - ¿El usuario dueño de
~/.sshes el mismo que el usuario con el que te conectas? - ¿La clave pública correcta está realmente en
authorized_keysdel remoto? - ¿El archivo
~/.ssh/configapunta alIdentityFilecorrecto para eseHost? - ¿El servicio SSH del servidor remoto permite autenticación por clave? (revisar
/etc/ssh/sshd_config, directivaPubkeyAuthentication yes)