Skip to content

SSH y llaves ​

SSH (Secure Shell) es la puerta por la que entras a administrar tu servidor. Todo lo que viaja por SSH va cifrado. En esta lección aprenderás a conectarte, a usar llaves en lugar de contraseñas (más seguro y más cómodo) y a transferir archivos.

Concepto ​

Con SSH abres una terminal remota: escribes comandos en tu computadora y se ejecutan en el servidor.

bash
ssh usuario@203.0.113.10

Hay dos formas de autenticarte:

  1. Contraseña: fácil, pero vulnerable a ataques de fuerza bruta (los bots intentan miles de contraseñas por hora en cualquier servidor público).
  2. Llaves SSH: un par de archivos generados en tu computadora.
    • Llave privada (id_ed25519): se queda en tu computadora. Es como la llave física de tu casa: nunca la compartas.
    • Llave pública (id_ed25519.pub): la copias al servidor. Es como la cerradura: puedes ponerla en todas las puertas que quieras.

El servidor solo deja entrar a quien tenga la llave privada que corresponde a una pública registrada en ~/.ssh/authorized_keys.

Paso 1: generar tu par de llaves ​

Funciona igual en Linux, macOS y Windows 10/11 (PowerShell trae OpenSSH):

bash
ssh-keygen -t ed25519 -C "tu-correo@ejemplo.com"
  • Acepta la ruta por defecto (~/.ssh/id_ed25519, en Windows C:\Users\TU_USUARIO\.ssh\id_ed25519).
  • Escribe una frase de contraseña (passphrase). Protege la llave si alguien roba tu laptop.

Ver tu llave pública:

bash
cat ~/.ssh/id_ed25519.pub
powershell
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub

Verás algo como ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... tu-correo@ejemplo.com.

¿Y RSA?

ed25519 es moderna, corta y segura. Si algún sistema viejo no la acepta, usa ssh-keygen -t rsa -b 4096.

Paso 2: copiar la llave pública al servidor ​

bash
ssh-copy-id usuario@203.0.113.10
powershell
# Windows no trae ssh-copy-id: lo hacemos en una línea
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh usuario@203.0.113.10 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Muchos proveedores de VPS (DigitalOcean, Hetzner, Vultr) te dejan pegar la llave pública al crear el servidor: hazlo y te ahorras este paso.

Prueba: ssh usuario@203.0.113.10 ya no debería pedir la contraseña del servidor (solo la passphrase de tu llave, si pusiste una).

Paso 3: archivo ~/.ssh/config (alias) ​

Escribir IPs y usuarios cada vez es tedioso. Crea ~/.ssh/config (en Windows C:\Users\TU_USUARIO\.ssh\config, sin extensión):

txt
# Servidor de producción de un cliente
Host cliente-prod
    HostName 203.0.113.10
    User deploy
    Port 22
    IdentityFile ~/.ssh/id_ed25519

# Mi VPS personal con puerto SSH distinto
Host mivps
    HostName mivps.ejemplo.com
    User erick
    Port 2222
    IdentityFile ~/.ssh/id_ed25519

# GitHub
Host github.com
    User git
    IdentityFile ~/.ssh/id_ed25519

Ahora basta con:

bash
ssh cliente-prod

Transferir archivos: scp y rsync ​

bash
# Subir un archivo
scp respaldo.sql cliente-prod:/home/deploy/

# Descargar un archivo
scp cliente-prod:/var/log/nginx/error.log ./

# Subir una carpeta completa
scp -r dist/ cliente-prod:/var/www/misitio/

# rsync: solo copia lo que cambió (ideal para desplegar)
# -a conserva permisos, -v muestra detalle, -z comprime, --delete borra lo que ya no existe en origen
rsync -avz --delete dist/ cliente-prod:/var/www/misitio/public/

La barra final importa en rsync

rsync dist/ destino/ copia el contenido de dist. rsync dist destino/ copia la carpeta dist dentro de destino. Usa --dry-run para ver qué haría antes de ejecutarlo de verdad.

Paso 4: endurecer el servidor SSH ​

Una vez que entras con llave, desactiva el acceso por contraseña y el login directo de root. Edita en el servidor:

bash
sudo nano /etc/ssh/sshd_config

Asegúrate de tener estas líneas (descomentadas):

txt
# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
MaxAuthTries 3

En Ubuntu revisa también /etc/ssh/sshd_config.d/: algunos proveedores dejan ahí un archivo (p. ej. 50-cloud-init.conf) con PasswordAuthentication yes que sobrescribe tu cambio.

bash
# Comprobar la sintaxis antes de aplicar
sudo sshd -t

# Aplicar (en Ubuntu 24.04 el servicio se llama "ssh")
sudo systemctl restart ssh

No te quedes fuera

Antes de desactivar las contraseñas, abre una segunda terminal y comprueba que entras con llave. Mantén la sesión original abierta hasta confirmarlo. Si te bloqueas, solo podrás entrar por la consola web del proveedor.

Agente SSH: escribir la passphrase una sola vez ​

bash
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
powershell
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519

Llaves para GitHub ​

  1. Copia tu llave pública.
  2. GitHub → Settings → SSH and GPG keys → New SSH key → pégala.
  3. Prueba:
bash
ssh -T git@github.com
# Hi tu-usuario! You've successfully authenticated...

Ahora puedes clonar con git clone git@github.com:usuario/repo.git.

Llaves de despliegue

Para que un servidor haga git pull de un repo privado, genera en el servidor una llave propia y agrégala en el repo como Deploy key (Settings → Deploy keys) con permiso solo de lectura. Así no expones tu llave personal.

Fail2ban: bloquear intentos de fuerza bruta ​

bash
sudo apt install fail2ban -y

# Configuración local (no edites jail.conf directamente)
sudo tee /etc/fail2ban/jail.local > /dev/null <<'EOF'
[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5

[sshd]
enabled = true
EOF

sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd   # ver IPs bloqueadas

Ejercicios ​

  1. Genera una llave ed25519, muéstrala y explica qué archivo nunca debes compartir.
  2. Escribe una entrada de ~/.ssh/config llamada tienda para el host 198.51.100.20, usuario deploy, puerto 2222.
  3. Escribe el comando rsync que sube build/ a /var/www/tienda/public/ en el host tienda, borrando archivos viejos, y primero en modo de prueba.
Ver solución
  1. ssh-keygen -t ed25519 -C "correo" y cat ~/.ssh/id_ed25519.pub. Nunca compartas id_ed25519 (sin .pub).
txt
Host tienda
    HostName 198.51.100.20
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_ed25519
bash
rsync -avz --delete --dry-run build/ tienda:/var/www/tienda/public/
# si todo se ve bien, quita --dry-run
rsync -avz --delete build/ tienda:/var/www/tienda/public/

Resumen ​

  • SSH cifra la conexión con tu servidor; usa llaves en lugar de contraseñas.
  • ssh-keygen -t ed25519 genera el par; la pública va a ~/.ssh/authorized_keys.
  • ~/.ssh/config te da alias cómodos; scp y rsync transfieren archivos.
  • Desactiva PasswordAuthentication y PermitRootLogin después de probar tu llave.
  • Fail2ban bloquea a quien intenta adivinar contraseñas.
  • Siguiente: Configurar un VPS desde cero.

Academia Web — aprende, copia y construye.