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:

  1. 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).
  2. 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-agent o un gestor de secretos).
  3. Confirmación de la passphrase.

Al finalizar obtienes dos archivos:

ArchivoDescripción¿Se comparte?
id_ed25519Clave privadaNunca, bajo ninguna circunstancia
id_ed25519.pubClave públicaSí, 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 -i indica 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:

FlagSignificado
-rCopia recursiva (necesaria para carpetas)
-PPuerto (en mayúscula, distinto a ssh -p)
-CComprime los datos durante la transferencia
-pPreserva 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:

FlagSignificado
-aarchive: modo archivo, conserva permisos, fechas, enlaces simbólicos y estructura de carpetas
-vverbose: muestra detalle de lo que se transfiere
-zcompress: comprime los datos en tránsito (útil en redes lentas)
-PCombina --progress (barra de avance) y --partial (permite reanudar transferencias cortadas)
-n o --dry-runSimula la transferencia sin copiar nada, útil para verificar antes de ejecutar
--deleteElimina 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ónHerramienta recomendada
Copiar un archivo suelto, una sola vezscp
Sincronizar carpetas grandes repetidamentersync
Red inestable o transferencias largasrsync (soporta reanudar)
Backups automatizados/programadosrsync
Simplicidad para tareas rápidasscp

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é:

  • ~/.ssh con 700: 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_keys con 600: 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:

  1. ¿Los permisos de .ssh y las claves son correctos en ambos equipos? (ver arriba)
  2. ¿El usuario dueño de ~/.ssh es el mismo que el usuario con el que te conectas?
  3. ¿La clave pública correcta está realmente en authorized_keys del remoto?
  4. ¿El archivo ~/.ssh/config apunta al IdentityFile correcto para ese Host?
  5. ¿El servicio SSH del servidor remoto permite autenticación por clave? (revisar /etc/ssh/sshd_config, directiva PubkeyAuthentication yes)