23/09/2026

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 (paquete openssh-server), escucha en el puerto 22/tcp.
  • Cliente: ssh (paquete openssh-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):

  1. Apaga la VM → Configuración → Red → Adaptador 1.
  2. Conectado a: Adaptador puente; en Nombre elige la interfaz real del host (la que usa tu Ubuntu para salir a la red).
  3. 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 ping falla, 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 sudo ni mete a tu usuario en el grupo sudo. Si dejaste la contraseña de root en blanco, sí lo hace. Por eso en el punto 5 empezamos con su -.


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é compa y no compañero? adduser valida 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 grupo sudo ya 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 sudoers existe una etiqueta llamada NOPASSWD:. 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 ssh en Debian y Ubuntu (sshd funciona 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 (d de 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 el Port del 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

  1. Existe el usuario compa (creado con adduser).
  2. pepa y compa tienen sudo mediante visudo (/etc/sudoers.d/aula).
  3. compa genera 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.)
  4. La pública está en /home/compa/.ssh/authorized_keys con los permisos correctos.
  5. sshd configurado con el drop-in 10-aula.conf de arriba.
  6. 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

  1. Red y primera conexión. Configura el adaptador puente, averigua IP_VM, haz ping y conéctate. Comprobación: ssh pepa@IP_VM 'hostname' devuelve el nombre de tu VM.
  2. Huella. Compara la huella que muestra el cliente con la de ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub en la VM. ¿Qué ataque evita esta comprobación?
  3. Provoca el aviso HOST IDENTIFICATION HAS CHANGED. (Pista: borra las claves de host en la VM con rm /etc/ssh/ssh_host_* y regénralas con dpkg-reconfigure openssh-server.) Resuélvelo con ssh-keygen -R.
  4. Alias. Crea Host vm en ~/.ssh/config y comprueba ssh vm. (Lo usaremos en las guías 2 y 3.)
  5. sudo. Como compa: sudo whoamiroot. Sin sudo, cat /etc/shadowPermission denied. Explica por qué.
  6. Investiga NOPASSWD (Pro Tip del punto 5) y escribe en tu cuaderno 3 riesgos y 1 caso de uso legítimo.
  7. Blindaje. Aplica el drop-in y verifica con sshd -T que cada directiva está activa. Rompe algo a propósito (una directiva mal escrita) y observa qué dice sshd -t.
  8. 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 sudovisudo -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 enso.png

servidor-ssh