servidor-ssh
🔐 SSH en Debian (1/3): el servidor sshd, usuarios y sudo
2º ASIR · Cliente SSH: Ubuntu (host) · Servidor SSH: Debian (VM en VirtualBox) Guías: 1 (esta) · 2 scp y rsync · 3 sftp, túneles y fail2ban
Objetivo: dejar la VM Debian accesible por SSH solo por clave, con dos usuarios con sudo (pepa y compa), y entender cada línea que tocamos en sshd_config.
0. Escenario y convenciones
Ubuntu (HOST) Debian (VM VirtualBox)
┌──────────────┐ ┌──────────────────────┐
│ cliente: ssh │ ───── red ──────────► │ servidor: sshd (:22) │
│ tú │ │ usuarios: pepa/compa │
└──────────────┘ └──────────────────────┘
| Prompt | Significa |
|---|---|
HOST$ |
usuario normal en el Ubuntu (cliente) |
VM$ |
usuario normal en la Debian (servidor) |
VM# |
root en la Debian (con su - o sudo) |
IP_VM |
la IP de tu VM (la averiguamos en el punto 2) |
Regla de oro del administrador: nunca cierres tu única sesión sin haber probado otra nueva. Con una VM tienes red de seguridad extra: la consola de VirtualBox siempre entra, aunque SSH esté roto.
1. ¿Qué es SSH? (2 minutos)
SSH (Secure Shell) es un protocolo que cifra la comunicación entre dos máquinas. Nació en 1995 (Tatu Ylönen) para sustituir a telnet, rlogin y rsh, que enviaban todo en texto plano, contraseñas incluidas.
- Servidor:
sshd(paqueteopenssh-server), escucha en el puerto 22/tcp. - Cliente:
ssh(paqueteopenssh-client, ya instalado en Ubuntu y Debian). - Sirve para: shell remota, copiar archivos (
scp,sftp,rsync) y túneles. Todo eso lo veremos en las guías 2 y 3.
2. Preparar la red de la VM
VirtualBox crea las VMs en modo NAT por defecto. Para practicar SSH cómodamente usaremos Adaptador puente (Bridged).
Bridged (camino principal):
- Apaga la VM → Configuración → Red → Adaptador 1.
- Conectado a: Adaptador puente; en Nombre elige la interfaz real del host (la que usa tu Ubuntu para salir a la red).
- Arranca la VM y averigua su IP:
VM$ ip -br a
# lo UNKNOWN 127.0.0.1/8 ...
# enp0s3 UP 192.168.1.57/24 ... ← esta es IP_VM
HOST$ ping -c 2 IP_VM # debe responder
⚠️ En algunas redes WiFi (aulas, hoteles) el puente no funciona porque el punto de acceso no admite varias MAC. Si
pingfalla, usa el Plan B.
Plan B: NAT + reenvío de puertos
Configuración → Red → Adaptador 1 (NAT) → Avanzadas → Reenvío de puertos y añade la regla:
| Nombre | Protocolo | IP host | Puerto host | IP invitado | Puerto invitado |
|---|---|---|---|---|---|
| ssh | TCP | 127.0.0.1 | 2222 | (vacío) | 22 |
Por línea de comandos (con la VM apagada): VBoxManage modifyvm "NOMBRE_VM" --natpf1 "ssh,tcp,127.0.0.1,2222,,22"
Con NAT, en toda la guía sustituye IP_VM por 127.0.0.1 y añade el puerto: ssh -p 2222 pepa@127.0.0.1 (ssh usa -p minúscula, scp usa -P mayúscula).
3. Punto de partida: el usuario pepa
Durante la instalación gráfica de Debian ya creaste tu usuario normal (aquí, pepa). Compruébalo:
VM$ id pepa
# uid=1000(pepa) gid=1000(pepa) groups=1000(pepa),24(cdrom),...
VM$ getent passwd pepa
# pepa:x:1000:1000:Pepa,,,:/home/pepa:/bin/bash
Los campos de /etc/passwd: usuario:x:UID:GID:comentario:home:shell.
💡 Detalle del instalador de Debian: si al instalar pusiste contraseña de root, el instalador no instala
sudoni mete a tu usuario en el gruposudo. Si dejaste la contraseña de root en blanco, sí lo hace. Por eso en el punto 5 empezamos consu -.
4. Crear el usuario compa
VM$ su - # pasamos a root (pide la contraseña de root)
VM# adduser compa # asistente interactivo: contraseña, nombre...
VM# id compa
adduser (script de Debian) es más amigable que useradd (herramienta de bajo nivel): crea el home, copia /etc/skel y pide la contraseña.
🤔 ¿Por qué
compay nocompañero?adduservalida el nombre con una expresión regular (NAME_REGEX) que solo admite letras ASCII, dígitos,_,.,-… Lañno pasa. Moraleja de administrador: nombres de usuario en ASCII, minúsculas, sin acentos.
5. Dar sudo a ambos con visudo
VM# apt update && apt install sudo # por si no estaba
VM# visudo -f /etc/sudoers.d/aula
Contenido del archivo:
pepa ALL=(ALL:ALL) ALL
compa ALL=(ALL:ALL) ALL
Se lee: «el usuario pepa, en cualquier host, puede ejecutar como cualquier usuario:grupo cualquier comando».
¿Por qué visudo y no un editor cualquiera? Bloquea el archivo mientras editas y comprueba la sintaxis al guardar. Un error de sintaxis en sudoers puede dejarte sin sudo para todos. Si prefieres otro editor: VM# update-alternatives --config editor.
Comprobación:
VM# sudo -l -U compa # qué puede hacer compa
VM# su - compa -c 'sudo whoami' # debe imprimir: root
Alternativa equivalente:
usermod -aG sudo compa(en Debian el gruposudoya tiene permiso en/etc/sudoers). Con/etc/sudoers.d/es explícito y auditable, por eso lo usamos en clase.
💡 Pro Tip (a investigar 😉): en
sudoersexiste una etiqueta llamadaNOPASSWD:. Pistas:man sudoers(busca NOPASSWD). Preguntas para el debate en clase: ¿qué comodidad aporta? ¿qué pasa si roban tu clave SSH y tu usuario la tiene? ¿en qué casos legítimos se usa (scripts,cron, automatización…)? ¿se puede limitar a un solo comando? No la pongas en tu servidor de prácticas hasta que sepas responder. Volveremos a ella en la guía 2.
6. Instalar y comprobar sshd
En el instalador de Debian hay una casilla «servidor SSH»; si no la marcaste:
VM# apt install openssh-server
VM# systemctl enable --now ssh # arrancar ahora y en cada arranque
VM# systemctl status ssh # debe poner: active (running)
VM# ss -tlnp | grep :22 # ¿quién escucha en el 22?
El servicio se llama
sshen Debian y Ubuntu (sshdfunciona como alias en Debian).
7. Primera conexión
HOST$ ssh pepa@IP_VM
# The authenticity of host '192.168.1.57' can't be established.
# ED25519 key fingerprint is SHA256:xxxxxxxx...
# Are you sure you want to continue connecting (yes/no/[fingerprint])?
Esa huella identifica al servidor. Un administrador serio la verifica por otro canal: en la consola de la VM,
VM$ ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
Si coinciden, escribe yes. La huella se guarda en ~/.ssh/known_hosts del cliente.
Otras formas de usar ssh:
HOST$ ssh pepa@IP_VM 'hostname; uptime' # ejecutar un comando y salir
HOST$ ssh -v pepa@IP_VM # verbose: la herramienta de depuración nº 1 (-vvv más aún)
⚠️ Si aparece WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!: o has reinstalado/clonado la VM (legítimo) o alguien se interpone (ataque man-in-the-middle). Verifica antes de borrar nada; si es legítimo: ssh-keygen -R IP_VM.
8. Autenticación por clave pública
Una contraseña se puede adivinar por fuerza bruta. Con un par de claves demuestras quién eres sin enviar ningún secreto: la privada nunca sale de tu máquina; la pública se copia al servidor.
HOST$ ssh-keygen -t ed25519 -C "pepa@ubuntu-host" # pon una passphrase
HOST$ ssh-copy-id pepa@IP_VM # copia la pública (pide la contraseña esta vez)
HOST$ ssh pepa@IP_VM # ya entra con la clave
Resultado en cada lado:
| Dónde | Archivo | Qué es |
|---|---|---|
HOST ~/.ssh/id_ed25519 |
clave privada | ¡NUNCA se comparte! |
HOST ~/.ssh/id_ed25519.pub |
clave pública | se puede repartir |
VM ~/.ssh/authorized_keys |
lista de públicas autorizadas | una por línea |
Ed25519 es el tipo recomendado hoy (moderno, rápido, claves cortas). rsa de 4096 bits solo si necesitas compatibilidad con sistemas muy viejos; dsa está muerto.
Para no teclear la passphrase en cada conexión, usa el agente: HOST$ ssh-add (en Ubuntu con escritorio ya suele haber uno en marcha).
Alias cómodo en ~/.ssh/config del HOST (chmod 600 ~/.ssh/config):
Host vm
HostName IP_VM
User pepa
IdentityFile ~/.ssh/id_ed25519
HOST$ ssh vm # ¡mucho mejor que recordar IP y usuario!
9. Configurar el servidor: sshd_config
⚠️ No confundir:
/etc/ssh/sshd_config= servidor (dde daemon) ·/etc/ssh/ssh_config= cliente.
Truco de Debian/Ubuntu: el sshd_config principal empieza con Include /etc/ssh/sshd_config.d/*.conf. Y en sshd_config gana el primer valor que se lee. Por tanto, lo limpio es no tocar el archivo principal y escribir nuestro drop-in (se lee antes y manda):
VM# nano /etc/ssh/sshd_config.d/10-aula.conf
# 10-aula.conf: configuración de las prácticas de ASIR
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
AllowUsers pepa compa
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
| Directiva | Para qué sirve |
|---|---|
PermitRootLogin no |
nadie entra como root por SSH; se entra como usuario y se escala con sudo (así además queda registro de quién hizo qué) |
PubkeyAuthentication yes |
permite entrar con clave pública |
PasswordAuthentication no |
prohíbe contraseñas: la fuerza bruta deja de tener sentido |
KbdInteractiveAuthentication no |
cierra la «puerta trasera» de contraseñas vía PAM (Debian 12+; en versiones antiguas se llamaba ChallengeResponseAuthentication) |
AllowUsers pepa compa |
lista blanca: solo estos usuarios pueden entrar |
MaxAuthTries 3 |
intentos por conexión antes de cortar |
LoginGraceTime 30 |
segundos para autenticarse antes de que corte |
ClientAliveInterval/CountMax |
el servidor «pregunta» al cliente cada 300 s; tras 2 sin respuesta cierra. Detecta conexiones muertas, no sesiones inactivas (para eso, TMOUT en el shell) |
X11Forwarding no |
sin reenvío gráfico si no se necesita |
💬 Cambiar el puerto (
Port 2222) reduce el ruido en los logs, no la seguridad real (un escaneo lo encuentra). Es opcional. Si lo haces: actualiza cliente (-p), firewall y fail2ban. En Ubuntu 22.10+ el servicio arranca por socket activation (ssh.socket) y elPortdel fichero puede ignorarse: aviso para cuando administres Ubuntu Server.Tampoco fijes a mano listas de
Ciphers/KexAlgorithms: los valores por defecto de OpenSSH actual son buenos, y las listas fijas envejecen mal.
Flujo seguro para aplicar cambios
VM# sshd -t # 1) ¿sintaxis correcta? (silencio = OK)
VM# sshd -T | grep -Ei 'permitrootlogin|passwordauthentication|allowusers'
# 2) ¿qué valores están realmente activos?
VM# systemctl reload ssh # 3) recargar (no corta sesiones abiertas)
HOST$ ssh vm # 4) probar en OTRA terminal, sin cerrar la actual
VM# journalctl -u ssh -f # 5) mirar el log en vivo mientras pruebas
🏁 RETO DE INICIACIÓN 1: dar acceso SSH a compa
Enunciado: tu compañero de clase (compa) necesita entrar por SSH a tu VM Debian con su clave y con sudo. Tú y él sois los únicos con acceso, y no se admiten contraseñas ni root.
Requisitos
- Existe el usuario
compa(creado conadduser). pepaycompatienensudomediantevisudo(/etc/sudoers.d/aula).compagenera su par de claves en su máquina y te pasa solo la pública. (Simúlalo:HOST$ ssh-keygen -t ed25519 -f ~/.ssh/id_compa.)- La pública está en
/home/compa/.ssh/authorized_keyscon los permisos correctos. sshdconfigurado con el drop-in10-aula.confde arriba.- Pruebas que deben cumplirse:
| Prueba | Resultado esperado |
|---|---|
ssh -i ~/.ssh/id_compa compa@IP_VM |
✅ entra |
ssh pepa@IP_VM |
✅ entra |
ssh root@IP_VM |
❌ Permission denied |
ssh intruso@IP_VM |
❌ Permission denied |
ssh -o PubkeyAuthentication=no compa@IP_VM |
❌ Permission denied (publickey) |
⚠️ El orden importa: instala las claves de ambos antes de poner
PasswordAuthentication no, o te quedarás fuera (la consola de VirtualBox te rescata).
# 1-2) Usuario y sudo (en la VM, como root)
VM# adduser compa
VM# visudo -f /etc/sudoers.d/aula
# pepa ALL=(ALL:ALL) ALL
# compa ALL=(ALL:ALL) ALL
# 3) En el HOST: el "compañero" genera su par y te da la pública
HOST$ ssh-keygen -t ed25519 -f ~/.ssh/id_compa -C "compa@su-pc"
HOST$ cat ~/.ssh/id_compa.pub # esto es lo único que se comparte
# 4a) Con contraseña todavía activa: lo más fácil
HOST$ ssh-copy-id -i ~/.ssh/id_compa.pub compa@IP_VM
# 4b) Como administrador (sin que compa participe): a mano
VM# install -d -m 700 -o compa -g compa /home/compa/.ssh
VM# echo 'ssh-ed25519 AAAA...pegar-aquí... compa@su-pc' >> /home/compa/.ssh/authorized_keys
VM# chown compa:compa /home/compa/.ssh/authorized_keys
VM# chmod 600 /home/compa/.ssh/authorized_keys
# 5) Endurecer sshd
VM# nano /etc/ssh/sshd_config.d/10-aula.conf # (contenido del punto 9)
VM# sshd -t && systemctl reload ssh
# 6) Probar (en otra terminal)
HOST$ ssh -i ~/.ssh/id_compa compa@IP_VM 'sudo whoami'
HOST$ ssh root@IP_VM
HOST$ ssh -o PubkeyAuthentication=no compa@IP_VM
✏️ Ejercicios prácticos
- Red y primera conexión. Configura el adaptador puente, averigua
IP_VM, hazpingy conéctate. Comprobación:ssh pepa@IP_VM 'hostname'devuelve el nombre de tu VM. - Huella. Compara la huella que muestra el cliente con la de
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.puben la VM. ¿Qué ataque evita esta comprobación? - Provoca el aviso
HOST IDENTIFICATION HAS CHANGED. (Pista: borra las claves de host en la VM conrm /etc/ssh/ssh_host_*y regénralas condpkg-reconfigure openssh-server.) Resuélvelo conssh-keygen -R. - Alias. Crea
Host vmen~/.ssh/configy compruebassh vm. (Lo usaremos en las guías 2 y 3.) - sudo. Como
compa:sudo whoami→root. Sinsudo,cat /etc/shadow→ Permission denied. Explica por qué. - Investiga
NOPASSWD(Pro Tip del punto 5) y escribe en tu cuaderno 3 riesgos y 1 caso de uso legítimo. - Blindaje. Aplica el drop-in y verifica con
sshd -Tque cada directiva está activa. Rompe algo a propósito (una directiva mal escrita) y observa qué dicesshd -t. - RETO 1 completo, con la tabla de pruebas en verde.
⚠️ Errores frecuentes y soluciones
| Síntoma | Causa probable | Solución |
|---|---|---|
Connection refused |
sshd parado o no instalado |
systemctl status ssh; ss -tlnp | grep :22 |
Connection timed out / No route to host |
IP equivocada, red puente que no funciona, NAT sin reenvío, firewall | ip -br a en la VM; ping; revisa el punto 2 |
Permission denied (publickey) |
pública no instalada, permisos mal, usuario no está en AllowUsers, usuario equivocado |
ssh -v; journalctl -u ssh; revisa ~/.ssh (700) y authorized_keys (600) |
Permission denied, please try again. |
contraseña mal, o PasswordAuthentication no |
comprueba con sshd -T; ¿está el usuario en AllowUsers? |
REMOTE HOST IDENTIFICATION HAS CHANGED |
VM reinstalada/clonada, o ataque | verifica la huella; si es legítimo ssh-keygen -R IP_VM |
Too many authentication failures |
el agente ofrece demasiadas claves | ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 ... |
Bad owner or permissions on ~/.ssh/config |
permisos laxos | chmod 600 ~/.ssh/config; chmod 700 ~/.ssh |
pepa is not in the sudoers file / sudo: command not found |
instalaste con contraseña de root: no hay sudo |
su - → apt install sudo → visudo -f /etc/sudoers.d/aula |
visudo avisa de syntax error |
error al escribir la regla | elige e (editar de nuevo); nunca guardes con error |
adduser: ... username should consist only of letters, digits... |
nombre con ñ, mayúsculas o acentos |
usa nombres ASCII (compa) |
Cambio en sshd_config «no hace nada» |
otro archivo de sshd_config.d/ se lee antes, o falta reload |
sshd -T muestra el valor real; systemctl reload ssh |
| Me he quedado fuera del servidor | config rota / sin claves instaladas | consola de VirtualBox, entra como usuario local, corrige, sshd -t, reload |
🧾 Chuleta
ssh usuario@host ssh -p PUERTO usuario@host ssh -i clave usuario@host
ssh-keygen -t ed25519 ssh-copy-id usuario@host ssh-keygen -R host
sshd -t sshd -T systemctl reload ssh
journalctl -u ssh -f visudo -f /etc/sudoers.d/aula adduser NOMBRE
Documentación: man ssh, man sshd_config, man sudoers, man ssh-keygen (y https://www.openssh.com/manual.html).
➡️ Siguiente: Guía 2: scp y rsync