RETO 1 en parejas (vlb36): tu compañero entra en tu servidor de Internet
🏁 RETO 1 en parejas (vlb36): tu compañero entra en tu servidor de Internet
2º ASIR · Cliente SSH: tu MADLinuX · Servidor SSH: tu contenedor LXC en ValdeLAB36 (
valdelab36.art) Guías: 1 servidor ssh · RETO 1 VirtualBox · RETO 1 vlb36 (este) · 2 scp y rsync (próximamente)
Objetivo: dar acceso a tu servidor a un compañero de verdad, con su clave, sin darle más poder del necesario, y después quitárselo. Todo en un servidor expuesto a Internet.
Requisito previo: tener hecha la práctica P0, con tu clave vlb36 en tu USB y el ritual de inicio de clase hecho (P0, apartado 2.1 «🎒 Tu clave va contigo»). Compruébalo:
PC_A$ ssh-add -l # debe aparecer tu clave
PC_A$ ssh -o PasswordAuthentication=no -p PUERTO_A apellidoA@valdelab36.art # debe entrar SIN pedir contraseña
⛔ Si esto no funciona, no sigas: arregla primero tu clave (P0) o pide ayuda.
0. Escenario y convenciones
En esta ocasión, en vez de conectarnos a nuestra máquina virtual (VirtualBox) en MAX en local (en Pinto, en el aula vaya), nos conectamos al servidor aldebaran / Valdelab36.art , allá por Valdezarza (en Madrid). Para las mentes curiosas, dicho servidor usa la tecnología LinuX Containers (LXC), es decir, de alguna manera un entorno también aislado pero a la vez conectado a Internet.
Trabajáis en parejas: A pone su contenedor, B se conecta. Después, cambiáis los papeles.
PC de B aldebaran (valdelab36.art) LXC de A
┌─────────────┐ ┌──────────────────────────┐ ┌───────────────────┐
│ cliente ssh │ ─────► │ proxy de Incus :PUERTO_A │ ─────────► │ sshd 127.0.0.1:22│
│ (B) │Internet│ (un puerto por alumno) │ │ apellidoA, B, fenix│
└─────────────┘ └──────────────────────────┘ └───────────────────┘
| Símbolo | Significa |
|---|---|
PC_A$ / PC_B$ |
terminal del MADLinuX de A / de B |
LXC_A$ |
terminal dentro del contenedor de A (entrando por SSH desde PC_A) |
PUERTO_A |
el puerto SSH de A (tabla de clase: 22XX, donde XX es su número) |
apellidoA / apellidoB |
vuestros usuarios (apellido en minúsculas, sin acentos) |
🗺️ La puerta ya está abierta. Tu contenedor no tiene IP pública: aldebaran recibe la conexión en tu puerto y el proxy de Incus la entrega al
sshdde tu contenedor. Por eso el puerto es la dirección: con el puerto de otro, llamas a su puerta.
⚠️ Estás en Internet. Bots de todo el mundo prueban estos puertos a diario. Todo lo que configures aquí es de verdad.
1. 🅱️ Enviar tu clave pública
Usa la clave de la práctica P0:
PC_B$ cat ~/.ssh/vlb36.pub
# ssh-ed25519 AAAAC3Nza...muy larga... b@madlinux
Envía esa línea completa a A por el chat o el correo de EducaMadrid. Es pública: no pasa nada si alguien más la ve.
⛔ Nunca envíes
~/.ssh/vlb36(sin.pub): es tu clave privada. Quien la tenga, es tú.
2. 🅰️ Crear la cuenta de B (con lo mínimo)
LXC_A$ sudo adduser --disabled-password --comment "" apellidoB
--disabled-password: la cuenta no tiene contraseña. B solo podrá entrar con su clave.- No le damos
sudo: B es un invitado, no un administrador. Es el principio de mínimo privilegio: a cada uno, solo el poder que necesita.
3. 🅰️ Instalar la clave de B
En tu sesión SSH (desde PC_A puedes pegar la línea que te envió B):
LXC_A$ sudo -u apellidoB mkdir -p -m 700 /home/apellidoB/.ssh
LXC_A$ echo 'ssh-ed25519 AAAAC3Nza...PEGA-AQUÍ... b@madlinux' | sudo -u apellidoB tee -a /home/apellidoB/.ssh/authorized_keys
LXC_A$ sudo -u apellidoB chmod 600 /home/apellidoB/.ssh/authorized_keys
💡
sudo -u apellidoBejecuta el comando como B: la carpeta y el archivo ya son suyos, sinchown. La clave debe quedar en una sola línea.
4. 🅰️ Blindar el servidor
Primero, tu plan B: los PCs del aula se borran en cada reinicio, y algún día olvidarás el USB. Por eso tú (el dueño) conservarás la contraseña como plan B. Pero estás en Internet: cambia la contraseña que te dio el profesor por una robusta (larga, que no uses en ningún otro sitio):
LXC_A$ passwd
Ahora el blindaje:
LXC_A$ sudo nano /etc/ssh/sshd_config.d/10-aula.conf
PermitRootLogin no
PasswordAuthentication no
AllowUsers apellidoA apellidoB fenix
Match User apellidoA
PasswordAuthentication yes
| Directiva | Para qué sirve |
|---|---|
PasswordAuthentication no |
nadie entra con contraseña… |
Match User apellidoA + PasswordAuthentication yes |
…excepto tú: tu plan B si olvidas el USB. B solo puede entrar con su clave |
💡 El bloque
Matchva siempre al final del fichero: todo lo que escribas debajo solo se aplica a ese usuario.
⚠️ Tres usuarios en
AllowUsers, obligatorio:
apellidoA: tú. Si te olvidas, te quedas fuera.apellidoB: tu compañero.fenix: el profesor, que administra todos los contenedores. Si falta, el profesor no puede entrar a ayudarte.
Aplicar, siempre en este orden y sin cerrar tu sesión:
LXC_A$ sudo sshd -t # 1) sintaxis (sin mensajes = OK)
LXC_A$ sudo systemctl reload ssh # 2) recargar
PC_A$ ssh -p PUERTO_A apellidoA@valdelab36.art # 3) en OTRA terminal: ¿sigues entrando (con clave)?
PC_A$ ssh -o PubkeyAuthentication=no -p PUERTO_A apellidoA@valdelab36.art # 4) ¿y tu plan B (contraseña)?
🆘 Si en las pruebas 3 o 4 no entras: no cierres la sesión que tienes abierta. Desde ella, corrige
10-aula.conf,sshd -tyreload. Si ya la cerraste, solo el profesor puede rescatarte.
5. 🅱️ Primera conexión: ¿es la puerta correcta?
PC_B$ ssh -i ~/.ssh/vlb36 -p PUERTO_A apellidoB@valdelab36.art
# The authenticity of host '[valdelab36.art]:PUERTO_A' can't be established.
# ED25519 key fingerprint is SHA256:xxxxxxxx...
Antes de escribir yes, A lee en voz alta la huella de su servidor:
LXC_A$ ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
Si coincide carácter a carácter, yes. Cada servidor tiene su propia huella (su «DNI»): si coincide, estás en la puerta de A.
6. ✅ Pruebas (desde el PC de B)
| Prueba | Resultado esperado |
|---|---|
ssh -i ~/.ssh/vlb36 -p PUERTO_A apellidoB@valdelab36.art 'hostname' |
✅ entra sin contraseña y responde el apellido de A (el nombre del contenedor) |
Dentro: groups |
✅ no aparece sudo |
Dentro: cat /etc/shadow |
❌ Permission denied: B no es administrador |
ssh -p PUERTO_A root@valdelab36.art |
❌ Permission denied |
ssh -p PUERTO_A intruso@valdelab36.art |
❌ Permission denied |
ssh -o PubkeyAuthentication=no -p PUERTO_A apellidoB@valdelab36.art |
❌ Permission denied (publickey): B sin clave no tiene forma de entrar |
(desde el PC de A) ssh -o PubkeyAuthentication=no -p PUERTO_A apellidoA@valdelab36.art |
✅ pide contraseña: el plan B del dueño funciona |
Y desde el contenedor de A, mirad quién ha entrado:
LXC_A$ who
LXC_A$ sudo journalctl -u ssh | grep apellidoB # busca: Accepted publickey for apellidoB from ...
7. 🔒 Revocar el acceso
La visita ha terminado. Un buen administrador retira los accesos que ya no hacen falta:
LXC_A$ sudo nano /etc/ssh/sshd_config.d/10-aula.conf # AllowUsers apellidoA fenix (quita a B)
LXC_A$ sudo sshd -t && sudo systemctl reload ssh
LXC_A$ sudo deluser --remove-home apellidoB # borra la cuenta y su clave
B lo comprueba: ssh -i ~/.ssh/vlb36 -p PUERTO_A apellidoB@valdelab36.art → ❌ Permission denied.
8. 🔄 Cambiad los papeles
Ahora B pone su contenedor y A se conecta. Repetid los pasos 1 a 7.
🤔 Preguntas para reflexionar (en el cuaderno)
- En el
journalctldel paso 6, ¿desde qué IP dice tu contenedor que entró B? ¿Por qué no es la IP real de B? (Pista: ¿quién abre la conexión hacia tusshd?) Si quisieras bloquear a un atacante por su IP dentro de tu contenedor, ¿podrías? - ¿Por qué no le dimos
sudoa B? ¿Qué podría hacer B consudoen tu contenedor? - ¿Por qué es más seguro que B te envíe su clave pública que darle una contraseña?
- El dueño (A) se permite entrar con contraseña y el invitado (B) no. ¿Por qué esa excepción? ¿Qué riesgo asume A a cambio, y cómo lo reduce?
🕵️ Extra: análisis de logs de tu servidor
Tu contenedor lleva semanas en Internet. Mira quién ha llamado a tu puerta:
LXC_A$ sudo journalctl -u ssh --no-pager | grep -E "Invalid user|Failed|banner exchange|Unable to negotiate|Accepted"
Clasifica cada línea: ¿eres tú, un compañero que se equivocó de puerto, un bot probando usuarios o un escáner? (Pista: fíjate en la hora, en el ritmo entre intentos y en el nombre de usuario.)
⚠️ Errores frecuentes
| Síntoma (en B) | Causa probable | Solución |
|---|---|---|
Permission denied con usuario y clave correctos |
estás llamando a otra puerta (puerto equivocado) | revisa PUERTO_A en la tabla; ssh … 'hostname' debe decir el apellido de A |
Permission denied (publickey) |
clave mal pegada (partida en varias líneas), permisos, o B no está en AllowUsers |
pasos 3 y 4 |
REMOTE HOST IDENTIFICATION HAS CHANGED |
el profesor renovó las claves de host de todos los servidores (24-sep) | si lo confirma el profesor: ssh-keygen -R "[valdelab36.art]:PUERTO" |
Connection refused |
puerto que no existe, o sshd de A parado |
revisa el puerto; A: systemctl status ssh |
UNPROTECTED PRIVATE KEY FILE! |
usas la clave directamente desde el USB (FAT/exFAT no guarda permisos) | cópiala a ~/.ssh y chmod 600 ~/.ssh/vlb36 (P0, 2.1) |
| A se ha quedado fuera | falta apellidoA en AllowUsers, o el bloque Match está mal |
plan B con contraseña; si tampoco: sesión abierta → corrige; si no, avisa al profesor |
▶ Ver solución (resumen de comandos)
# 1) B: enviar la pública
PC_B$ cat ~/.ssh/vlb36.pub
# 2-3) A: cuenta sin contraseña ni sudo + clave de B
LXC_A$ sudo adduser --disabled-password --comment "" apellidoB
LXC_A$ sudo -u apellidoB mkdir -p -m 700 /home/apellidoB/.ssh
LXC_A$ echo 'ssh-ed25519 AAAA... b@madlinux' | sudo -u apellidoB tee -a /home/apellidoB/.ssh/authorized_keys
LXC_A$ sudo -u apellidoB chmod 600 /home/apellidoB/.ssh/authorized_keys
# 4) A: contraseña robusta (plan B) y blindar:
# PermitRootLogin no / PasswordAuthentication no / AllowUsers apellidoA apellidoB fenix
# + al final: Match User apellidoA → PasswordAuthentication yes
LXC_A$ passwd
LXC_A$ sudo nano /etc/ssh/sshd_config.d/10-aula.conf
LXC_A$ sudo sshd -t && sudo systemctl reload ssh
# 5-6) B: conectar verificando la huella, y probar
PC_B$ ssh -i ~/.ssh/vlb36 -p PUERTO_A apellidoB@valdelab36.art 'hostname'
# 7) A: revocar
LXC_A$ sudo nano /etc/ssh/sshd_config.d/10-aula.conf # AllowUsers apellidoA fenix
LXC_A$ sudo sshd -t && sudo systemctl reload ssh
LXC_A$ sudo deluser --remove-home apellidoB
Pregunta 1: tu contenedor ve 127.0.0.1. El proxy de Incus recibe la conexión en aldebaran y abre otra conexión, desde dentro de tu contenedor, hacia tu sshd. Todos (B, tú, los bots) parecéis venir de 127.0.0.1: bloquear esa IP te bloquearía a ti también.
Pregunta 2: cualquiera con sudo en su contenedor podía copiar la clave privada de host y hacerse pasar por el servidor de cualquier compañero (ataque man-in-the-middle) sin que saltara ningún aviso.
Pregunta 5: los PCs del aula se borran en cada reinicio: si A olvida el USB, sin contraseña se quedaría fuera de su propio servidor. A cambio, los bots pueden probar contraseñas contra el usuario de A. Se reduce con una contraseña robusta (passwd). (¿Serviría fail2ban dentro del contenedor? Recuerda la pregunta 1.)
➡️ Siguiente: Guía 2: scp y rsync (próximamente)