Autor: ciberkaos

  • 2.5 – Práctica guiada: “La estación orbital Andrómeda”

    2.5 – Práctica guiada: “La estación orbital Andrómeda”

    La estación espacial Andrómeda necesita organizar a su tripulación.
    Hay tres equipos principales:

    • pilotos
    • ingenieros
    • cientificos

    Cada miembro de la tripulación tendrá acceso solo a determinadas carpetas según su grupo.
    Además, el comandante de la estación deberá poder reorganizar la tripulación, cambiar usuarios de grupo y ajustar propietarios y permisos de archivos.

    Tu misión será convertirte en el administrador del sistema de la estación.


    1. Objetivos de la práctica

    Al finalizar esta práctica, el alumno será capaz de:

    • crear usuarios en Ubuntu,
    • crear grupos de usuarios,
    • añadir usuarios a grupos,
    • cambiar un usuario de grupo,
    • comprobar a qué grupos pertenece un usuario,
    • crear carpetas para distintos equipos,
    • asignar propietario y grupo a carpetas y archivos,
    • modificar permisos con chmod,
    • utilizar chown para cambiar propietario y grupo,
    • verificar que los permisos funcionan correctamente.

    2. Qué vas a aprender

    En Linux, cada archivo y carpeta tiene asociado:

    • un propietario,
    • un grupo,
    • unos permisos.

    Los permisos se pueden definir para:

    • u → usuario propietario,
    • g → grupo,
    • o → otros usuarios.

    Y los permisos básicos son:

    • r → lectura,
    • w → escritura,
    • x → ejecución o acceso.

    3. Preparación inicial

    Antes de empezar, abre una terminal y asegúrate de trabajar con un usuario con permisos de administración.

    Puedes comprobarlo con:

    whoami

    Y probar que tienes permisos de sudo con:

    sudo -v

    4. Crear los grupos de la estación

    Vamos a crear los tres grupos principales de la tripulación.

    sudo groupadd pilotos
    sudo groupadd ingenieros
    sudo groupadd cientificos

    Comprobar que los grupos existen

    getent group pilotos
    getent group ingenieros
    getent group cientificos

    Esto mostrará información del grupo si se ha creado correctamente.


    5. Crear los usuarios de la tripulación

    Ahora vamos a crear varios usuarios.

    Equipo de pilotos

    sudo useradd -m -s /bin/bash luke
    sudo useradd -m -s /bin/bash leia

    Equipo de ingenieros

    sudo useradd -m -s /bin/bash data
    sudo useradd -m -s /bin/bash scotty

    Equipo de científicos

    sudo useradd -m -s /bin/bash ripley
    sudo useradd -m -s /bin/bash spock

    Explicación

    • useradd crea el usuario.
    • -m crea su carpeta personal en /home.
    • -s /bin/bash asigna Bash como shell.

    6. Asignar contraseña a los usuarios

    Para que estos usuarios puedan iniciar sesión, asígnales una contraseña.

    sudo passwd luke
    sudo passwd leia
    sudo passwd data
    sudo passwd scotty
    sudo passwd ripley
    sudo passwd spock

    Puedes usar una contraseña sencilla solo para la práctica, por ejemplo:

    Clave123*

    7. Añadir usuarios a sus grupos

    Ahora asignamos cada usuario a su equipo.

    sudo usermod -aG pilotos luke
    sudo usermod -aG pilotos leia
    
    sudo usermod -aG ingenieros data
    sudo usermod -aG ingenieros scotty
    
    sudo usermod -aG cientificos ripley
    sudo usermod -aG cientificos spock

    Explicación importante

    • usermod modifica un usuario.
    • -aG añade el usuario a uno o varios grupos sin borrar los grupos anteriores.

    8. Comprobar a qué grupos pertenece cada usuario

    Usa alguno de estos comandos:

    groups luke
    groups leia
    groups data
    groups scotty
    groups ripley
    groups spock

    O también:

    id luke
    id data
    id spock

    Esto permite ver:

    • el UID del usuario,
    • el GID principal,
    • los grupos a los que pertenece.

    9. Crear la estructura de carpetas de la estación

    Vamos a crear una zona común de trabajo para la estación.

    sudo mkdir -p /srv/andromeda/pilotos
    sudo mkdir -p /srv/andromeda/ingenieros
    sudo mkdir -p /srv/andromeda/cientificos
    sudo mkdir -p /srv/andromeda/comun

    Verificar la estructura creada

    ls -l /srv
    ls -l /srv/andromeda

    10. Asignar propietario y grupo a las carpetas

    Ahora vamos a asociar cada carpeta con su grupo correspondiente.

    sudo chown root:pilotos /srv/andromeda/pilotos
    sudo chown root:ingenieros /srv/andromeda/ingenieros
    sudo chown root:cientificos /srv/andromeda/cientificos
    sudo chown root:root /srv/andromeda/comun

    Explicación

    Con chown puedes cambiar:

    • el propietario,
    • el grupo,
    • o ambos.

    En este caso:

    • el propietario será root,
    • el grupo será el del equipo correspondiente.

    La sintaxis es:

    sudo chown propietario:grupo ruta

    NOTA: El Comando chgrp

    El comando chgrp se utiliza en Linux para cambiar el grupo asociado a un archivo o carpeta.

    Mientras que chown puede cambiar el propietario y también el grupo, chgrp está pensado específicamente para modificar solo el grupo.

    chgrp grupo archivo_o_carpeta

    sudo chgrp pilotos /srv/andromeda/ruta_estelar.txt

    Con este comando, el archivo ruta_estelar.txt pasará a pertenecer al grupo pilotos.


    ¿Para qué sirve?

    chgrp es útil cuando:

    • queremos que varios usuarios de un mismo grupo puedan acceder a un archivo,
    • no necesitamos cambiar el propietario,
    • queremos reorganizar permisos por grupos de trabajo.

    En una práctica como la de la estación orbital, puede servir para decidir qué equipo debe compartir un documento sin cambiar quién es su dueño.


    Diferencia entre chown y chgrp

    • chown cambia el propietario y, si se quiere, también el grupo.
    • chgrp cambia solo el grupo.


    Por ejemplo:

    sudo chown luke:pilotos archivo.txt

    cambia propietario y grupo.


    En cambio:

    sudo chgrp pilotos archivo.txt

    solo cambia el grupo, manteniendo el mismo propietario.

    11. Asignar permisos a las carpetas

    Queremos que cada grupo pueda entrar en su carpeta, leer y escribir en ella, pero que otros no puedan acceder.

    sudo chmod 770 /srv/andromeda/pilotos
    sudo chmod 770 /srv/andromeda/ingenieros
    sudo chmod 770 /srv/andromeda/cientificos
    sudo chmod 777 /srv/andromeda/comun

    Explicación de los permisos

    770

    • propietario: rwx
    • grupo: rwx
    • otros: ---

    777

    • propietario: rwx
    • grupo: rwx
    • otros: rwx

    La carpeta comun será accesible para todos, mientras que las otras estarán restringidas.


    12. Comprobar los permisos

    ls -ld /srv/andromeda/pilotos
    ls -ld /srv/andromeda/ingenieros
    ls -ld /srv/andromeda/cientificos
    ls -ld /srv/andromeda/comun

    Fíjate en algo como esto:

    drwxrwx--- 2 root pilotos ...

    Eso significa:

    • d → es una carpeta,
    • rwx → permisos del propietario,
    • rwx → permisos del grupo,
    • --- → permisos del resto.

    13. Probar acceso con distintos usuarios

    Ahora toca comprobar si realmente funciona.

    Entrar como un usuario concreto

    Puedes cambiar de usuario con:

    su - luke

    O, si prefieres, ejecutar comandos como otro usuario:

    sudo -u luke ls /srv/andromeda/pilotos
    sudo -u luke ls /srv/andromeda/ingenieros

    Qué debería ocurrir

    • luke sí debería poder entrar en /srv/andromeda/pilotos
    • luke no debería poder entrar en /srv/andromeda/ingenieros

    Prueba varios casos:

    sudo -u luke ls /srv/andromeda/pilotos
    sudo -u luke ls /srv/andromeda/ingenieros
    sudo -u data ls /srv/andromeda/ingenieros
    sudo -u ripley ls /srv/andromeda/cientificos
    sudo -u spock ls /srv/andromeda/pilotos
    ¿Que hace? sudo -u luke ls
    Ejecuta el comando ls como si lo estuviera lanzando el usuario luke. 
    -u luke Le dice a sudo que el comando no se ejecute como tu usuario actual, sino como el usuario luke.

    14. Crear archivos dentro de las carpetas

    Vamos a crear documentos de misión dentro de cada zona.

    sudo touch /srv/andromeda/pilotos/ruta_estelar.txt
    sudo touch /srv/andromeda/ingenieros/reactor.txt
    sudo touch /srv/andromeda/cientificos/informe_biologico.txt
    sudo touch /srv/andromeda/comun/avisos_generales.txt

    Añadimos contenido:


    
    echo "Ruta secreta al sector Omega" | sudo tee /srv/andromeda/pilotos/ruta_estelar.txt
    
    echo "Estado del reactor principal" | sudo tee /srv/andromeda/ingenieros/reactor.txt
    
    echo "Análisis de muestras alienígenas" | sudo tee /srv/andromeda/cientificos/informe_biologico.txt
    
    echo "Reunión general a las 18:00" | sudo tee /srv/andromeda/comun/avisos_generales.txt
    ¿Que hace tee?

    sirve para escribir un texto dentro de un archivo con permisos de administrador.
    El comando tee recoge lo que le llega por la entrada estándar y lo:

    • muestra por pantalla,
    • y además lo guarda en un archivo.

    Como va precedido de sudo, tee se ejecuta con permisos de administrador, por lo que puede escribir en una ruta protegida.

    Saber más

    15. Cambiar propietario de un archivo con chown

    Ahora vamos a usar chown de forma más clara sobre archivos.

    Por ejemplo, el archivo del reactor lo va a gestionar el ingeniero data.

    sudo chown data:ingenieros /srv/andromeda/ingenieros/reactor.txt

    Y el informe biológico será gestionado por spock.

    sudo chown spock:cientificos /srv/andromeda/cientificos/informe_biologico.txt

    Verificar el cambio

    ls -l /srv/andromeda/ingenieros/reactor.txt
    ls -l /srv/andromeda/cientificos/informe_biologico.txt

    16. Cambiar solo el grupo de un archivo

    También puedes cambiar únicamente el grupo.

    Por ejemplo:

    sudo chown :pilotos /srv/andromeda/comun/avisos_generales.txt

    Eso cambia solo el grupo, manteniendo el propietario actual.

    Compruébalo:

    ls -l /srv/andromeda/comun/avisos_generales.txt

    17. Dar permisos concretos a los archivos

    Vamos a ajustar permisos para que:

    • el propietario pueda leer y escribir,
    • el grupo pueda leer,
    • otros no puedan acceder.
    sudo chmod 640 /srv/andromeda/ingenieros/reactor.txt
    sudo chmod 640 /srv/andromeda/cientificos/informe_biologico.txt
    sudo chmod 664 /srv/andromeda/comun/avisos_generales.txt

    Interpretación

    640

    • propietario: lectura y escritura
    • grupo: lectura
    • otros: sin permisos

    664

    • propietario: lectura y escritura
    • grupo: lectura y escritura
    • otros: lectura

    18. Cambiar un usuario de grupo

    Ahora viene una situación de la historia.

    La comandante decide que leia deja el equipo de pilotos y pasa al equipo de ingenieros.

    Primero la añadimos al nuevo grupo:

    sudo usermod -aG ingenieros leia

    Comprobamos sus grupos:

    groups leia

    Ahora leia pertenece a dos grupos: pilotos e ingenieros.

    Quitarla del grupo de pilotos

    Para hacerlo de forma clara en Ubuntu:

    sudo gpasswd -d leia pilotos

    Volvemos a comprobar:

    groups leia

    Ahora debería quedar solo en ingenieros además de su grupo principal.


    19. Crear un nuevo usuario y asignarlo a un grupo

    La estación recibe a un nuevo tripulante: neo.

    sudo useradd -m -s /bin/bash neo
    sudo passwd neo
    sudo usermod -aG cientificos neo

    Comprobar:

    groups neo

    20. Probar qué puede hacer cada usuario

    Haz pruebas reales con comandos como estos:

    sudo -u data cat /srv/andromeda/ingenieros/reactor.txt
    sudo -u luke cat /srv/andromeda/ingenieros/reactor.txt
    sudo -u spock cat /srv/andromeda/cientificos/informe_biologico.txt
    sudo -u leia touch /srv/andromeda/ingenieros/prueba_leia.txt
    sudo -u neo touch /srv/andromeda/cientificos/muestra_01.txt

    Qué observar

    • Un usuario del grupo correcto debería poder trabajar dentro de su carpeta.
    • Un usuario de otro grupo debería recibir un error de permisos.
    • Los archivos deben respetar los permisos establecidos.

    21. Ver propietarios y permisos de toda la estación

    Para revisar toda la estructura:

    ls -lR /srv/andromeda

    Esto te mostrará:

    • carpetas,
    • archivos,
    • propietarios,
    • grupos,
    • permisos.

    22. Recuerda

    Diferencia entre propietario y grupo

    • El propietario es normalmente el usuario dueño del archivo.
    • El grupo permite que varios usuarios compartan acceso a archivos y carpetas.

    Diferencia entre chown y chmod

    • chown cambia el propietario o grupo.
    • chmod cambia los permisos.

    Comandos clave

    Crear grupo

    sudo groupadd nombre_grupo

    Crear usuario

    sudo useradd -m -s /bin/bash nombre_usuario

    Asignar contraseña

    sudo passwd nombre_usuario

    Añadir usuario a grupo

    sudo usermod -aG grupo usuario

    Ver grupos de un usuario

    groups usuario

    Quitar usuario de un grupo

    sudo gpasswd -d usuario grupo

    Cambiar propietario y grupo

    sudo chown propietario:grupo archivo_o_carpeta

    Cambiar permisos

    sudo chmod permisos archivo_o_carpeta

    23. Actividad

    Ahora que ya sabes manejar usuarios y permisos, realiza estas tareas:

    Tarea 1

    Crea un nuevo grupo llamado:

    seguridad

    Tarea 2

    Crea dos usuarios nuevos:

    • trinity
    • morpheo

    Tarea 3

    Añade ambos al grupo seguridad.

    Tarea 4

    Crea la carpeta:

    /srv/andromeda/seguridad

    Tarea 5

    Haz que:

    • el propietario sea root,
    • el grupo sea seguridad,
    • los permisos sean 770.

    Tarea 6

    Crea dentro un archivo llamado:

    protocolo_defensa.txt

    Tarea 7

    Haz que el archivo pertenezca a trinity:seguridad.

    Tarea 8

    Pon permisos 640 al archivo.

    Tarea 9

    Comprueba que:

    • trinity puede leerlo,
    • morpheo puede leerlo,
    • luke no puede acceder.

    25. Planteate las siguientes preguntas.

    1. ¿Qué diferencia hay entre un usuario y un grupo?
    2. ¿Qué hace el comando chown?
    3. ¿Qué hace el comando chmod?
    4. ¿Qué significa el permiso 770?
    5. ¿Qué significa el permiso 640?
    6. ¿Cómo se comprueba a qué grupos pertenece un usuario?
    7. ¿Qué comando se usa para eliminar a un usuario de un grupo?
    8. ¿Por qué es útil trabajar con grupos en lugar de dar permisos usuario por usuario?

    La estación orbital Andrómeda ya está organizada.
    Cada tripulante pertenece a su equipo, cada carpeta está protegida y los documentos sensibles solo son accesibles por el personal autorizado.
    Has completado con éxito tu primera misión como administrador de sistemas espaciales.


    Tabla de comandos y opciones principales

    ComandoOpción / sintaxisExplicación
    groupaddgroupadd nombre_grupoCrea un grupo nuevo en el sistema.
    useradduseradd nombre_usuarioCrea un usuario.
    useradd-mCrea automáticamente la carpeta personal del usuario en /home.
    useradd-s /bin/bashAsigna la shell Bash al usuario.
    passwdpasswd nombre_usuarioEstablece o cambia la contraseña de un usuario.
    usermodusermod usuarioModifica la configuración de un usuario existente.
    usermod-aG grupo usuarioAñade el usuario a un grupo secundario sin quitarlo de los demás.
    groupsgroups usuarioMuestra los grupos a los que pertenece un usuario.
    idid usuarioMuestra UID, GID y grupos del usuario.
    mkdirmkdir carpetaCrea una carpeta.
    mkdir-pCrea la ruta completa aunque haya varios niveles de carpetas.
    touchtouch archivoCrea un archivo vacío si no existe.
    lslsLista archivos y carpetas.
    ls-lMuestra la lista en formato largo, con permisos, propietario, grupo, tamaño, etc.
    ls-dMuestra información de la carpeta en sí, no de su contenido.
    ls-RLista el contenido de forma recursiva, incluyendo subcarpetas.
    chownchown propietario archivoCambia el propietario de un archivo o carpeta.
    chownchown propietario:grupo archivoCambia propietario y grupo a la vez.
    chownchown :grupo archivoCambia solo el grupo del archivo o carpeta.
    chown-RAplica el cambio de propietario/grupo de forma recursiva.
    chmodchmod permisos archivoCambia los permisos de un archivo o carpeta.
    chmod770Propietario y grupo con todos los permisos; otros sin acceso.
    chmod750Propietario con todos los permisos; grupo puede leer y entrar; otros sin acceso.
    chmod640Propietario puede leer y escribir; grupo solo leer; otros sin acceso.
    chmod664Propietario y grupo pueden leer y escribir; otros solo leer.
    chmod777Todos pueden leer, escribir y ejecutar/entrar.
    chmod-RCambia permisos de forma recursiva.
    gpasswdgpasswd -d usuario grupoElimina un usuario de un grupo.
    susu - usuarioCambia a otro usuario cargando su entorno.
    sudosudo comandoEjecuta un comando con privilegios de administrador.
    sudosudo -u usuario comandoEjecuta un comando como otro usuario.
    getentgetent group nombre_grupoConsulta información de un grupo en la base de datos del sistema.
    whoamiwhoamiMuestra el usuario actual.
    teetee archivoEscribe en un archivo a partir de la entrada estándar. Muy útil junto con echo.
    catcat archivoMuestra el contenido de un archivo.

    Tabla permisos numéricos

    ValorSignificado
    7rwx = lectura, escritura y ejecución
    6rw- = lectura y escritura
    5r-x = lectura y ejecución
    4r-- = solo lectura
    3-wx = escritura y ejecución
    2-w- = solo escritura
    1--x = solo ejecución
    0--- = sin permisos

    Cómo leer un permiso como 770

    PosiciónValorSignificado
    Propietario7rwx
    Grupo7rwx
    Otros0---

    Ejemplos rápidos

    ObjetivoComando
    Crear gruposudo groupadd pilotos
    Crear usuario con home y bashsudo useradd -m -s /bin/bash luke
    Añadir usuario a gruposudo usermod -aG pilotos luke
    Ver grupos de un usuariogroups luke
    Cambiar propietario y gruposudo chown data:ingenieros archivo.txt
    Cambiar solo gruposudo chown :cientificos archivo.txt
    Dar permisos al propietario y gruposudo chmod 770 carpeta
    Quitar a un usuario de un gruposudo gpasswd -d leia pilotos

  • 2.6 – Usuarios y Huellas Digitales en Linux

    2.6 – Usuarios y Huellas Digitales en Linux

    whoami

    El equivalente digital de mirarse al espejo.
    Muestra el usuario efectivo que está ejecutando el comando.
    Perfecto para explicar la diferencia entre:

    • usuario real (el que inicia sesión),
    • usuario efectivo (el que el sistema usa para permisos, especialmente tras un sudo).

    id

    Un pequeño radiotelescopio hacia tu identidad numérica.
    Muestra:

    • UID (identificador del usuario)
    • GID (grupo principal)
    • grupos secundarios
      Es una forma directa de ver permisos y roles dentro del sistema. Ideal para ejercicios de administración y forense.

    who / w / users

    El “quién está ahora mismo en la nave”.
    Sirve para ver sesiones activas y cómo han entrado:

    • tty
    • pts (sesiones remotas)
    • SSH
    • tiempo conectado

    • En ciberseguridad es una herramienta rápida para detectar conexiones sospechosas.

    env

    El baúl entero de variables de entorno.
    Aquí viven cosas como:

    • $USER
    • $HOME
    • $SHELL
    • $PATH

      Además permite explicar a los alumnos por qué una aplicación “sabe” dónde buscar binarios o dónde está su carpeta de configuración.

    echo $USER

    Una forma simple de leer la variable que indica el nombre del usuario que ha iniciado sesión.
    Comparar whoami vs $USER es didáctico:
    $USER → quien inició sesión
    whoami → usuario efectivo (útil para mostrar cómo sudo cambia el contexto)


    echo $HOME

    Viene genial para scripts o explicaciones sobre la organización del sistema.
    Muestra la ruta al directorio personal, que siempre es sagrado en Linux.


    echo $SHELL

    Permite enseñar la diferencia entre bash, zsh, fish…
    Ideal para que entiendan por qué su terminal “se comporta raro” tras instalar algo.


    hostname

    La identidad pública del sistema en la red.
    Junto con hostname -I, sirve para explicar la distinción entre:

    • identidad del equipo,
    • interfaces,
    • direcciones IP que usa para comunicarse.

    logname

    La versión más purista de “quién inició esta sesión”, incluso si has hecho un su o un sudo.
    Muy útil en prácticas de forense porque te permite reconstruir acciones de usuarios.


    tty

    Muestra el dispositivo de terminal actual.
    En remoto se verá algo como /dev/pts/1.
    Perfecto para entender:

    • sesiones locales,
    • sesiones remotas,
    • multiplexación de terminales.

    ps aux | grep $USER

    Una puerta a ver “qué está ejecutando realmente tu identidad”.
    A los alumnos les ayuda a comprender procesos, permisos, señales y contextos.


    finger (si lo instalas)

    Pinta un pequeño perfil del usuario:

    • shell
    • home
    • nombre real

      Antiguo pero didáctico como pocas cosas.

    Actividad: “¿Quién eres en esta máquina?” – Identidad y sesiones en Linux

    Imagina que el sistema es una estación espacial. Cada alumno entra por una compuerta distinta, a veces cambia de traje (sudo), y el objetivo es reconstruir quién hizo qué.


    Todo ocurre en un Ubuntu normal.


    FASE 1 — Identidad básica

    Ejecuta:

    
    
    
    
    
    whoami
    echo $USER
    id
    logname
    

    Descubrir que el sistema te reconoce por varias “capas”.

    Explicación:

    • whoami → usuario efectivo.
    • $USER → usuario que inició sesión.
    • id → UID, GID, grupos.
    • logname → el user original aunque hayan hecho su.

    Pequeño reto:
    Pídeles que intenten entender por qué sudo whoami devuelve root,
    pero echo $USER sigue mostrando su usuario normal.


    FASE 2 — Dónde están realmente

    Ejecutar

    
    
    
    
    
    pwd
    echo $HOME
    echo $SHELL
    tty
    

    Esto muestra:

    • dónde están,
    • cuál es su shell,
    • qué terminal están usando (local, SSH, pts…).

    Ejercicio: Compartir un terminal local (tty1) con una sesión SSH


    FASE 3 — Quién más está en la nave

    Ahora miramos el estado de la estación:

    
    
    
    
    
    who
    w
    users
    hostname
    hostname -I
    

    Objetivo: identificar todas las sesiones activas.
    Puedes entrar desde otra máquina para ver “un intruso”.

    Mini-misión:
    Que usen who para averiguar:

    • quién está conectado,
    • desde qué terminal,
    • desde qué IP si es SSH,
    • desde cuándo.

    Esto introduce sin ruido en análisis forense real.


    FASE 4 — Cambio de identidad

    
    
    
    
    
    sudo -i
    whoami
    echo $USER
    id
    logname
    tty
    

    Aquí ocurre la magia:

    • whoami → root
    • $USER → su usuario original
    • logname → quien realmente abrió la sesión
    • tty → la misma porque no abren una nueva


    FASE 5 — Ver qué hace cada identidad

    En otra terminal, que ejecuten:

    
    
    
    
    
    ps aux | grep $USER
    ps aux | grep root
    

    Fijate que root suele llevar servicios, demonios, etc.

    FASE 6 — Prueba forense

    Prueba a ejecutar con un usuario un comando secreto en su sesión, por ejemplo:

    
    
    
    
    
    mkdir /tmp/estacion-alpha
    echo "Hola profe" > /tmp/mensaje.txt
    touch ~/algo_raro
    

    Luego cambia de usuario :

    “Reconstruid qué usuarios han hecho qué”

    Utilizando:

    
    
    
    
    
    ls -l /tmp
    ls -l /home/*
    who
    logname
    id username
    

    La identidad del sistema queda impregnada en permisos, UID, GID, sesiones y ficheros creados.


    Hackeo benévolo

    Se hace SSH desde otro equipo con:

    
    
    
    
    
    ssh usuario@IP
    

    Luego ejecuta:

    
    
    
    
    
    who
    w
    tty
    hostname -I
    

    Los demás deben encontrar:

    • quién ha entrado
    • desde qué IP
    • en qué terminal
    • cuánto tiempo lleva conectado
      Esta parte siempre les encanta porque parece CSI, pero sin dramatismos digitales.

  • 2.7 – [Reto] Matrix: Controlar el sistema

    2.7 – [Reto] Matrix: Controlar el sistema

    En este pequeño universo, tu Linux hace de Máquina Central, un nodo que controla el flujo de información entre los humanos libres y las máquinas. Los alumnos son “operadores”, encargados de levantar accesos, crear identidades falsas, aislar directorios y conceder privilegios solo a quienes “existen dentro del sistema”.

    El sistema está dividido en dos mundos:

    La Superficie (usuarios sin privilegios)

    El Backdoor (usuarios con acceso sudo)

    La misión avanza en fases, y cada fase tiene su sentido dentro del lore.


    FASE 1 — Generación de identidades (crear usuarios)

    La Resistencia necesita identidades nuevas para infiltrarse en Matrix.

    Cada alumno debe crear:

    • 3 usuarios sin privilegios:
      • trinity
      • apoc
      • switch
    • 1 usuario operador con privilegios sudo:
      • neo

    “neo” deberá ser añadido al grupo sudoers.

    Instrucciones sugeridas (los alumnos deben descubrir qué significan las opciones):

    sudo adduser trinity
    sudo adduser apoc
    sudo adduser switch
    sudo adduser neo
    sudo usermod -aG sudo neo
    
    

    Justificación narrativa:

    Neo es “El Elegido”, así que puede alterar las reglas del sistema.

    Los demás son “agentes infiltrados” con permisos normales.


    FASE 2 — Crear grupos: Escuadrones de la Resistencia

    La Resistencia funciona por células. Necesitamos 2 grupos:

    • zion → humanos libres
    • matrix → identidades falsas dentro del sistema

    Asignación:

    • trinity y neo deben estar en zion
    • apoc y switch deben estar en matrix

    El operador (neo) pertenece a los dos mundos, así que debe estar en ambos grupos.

    sudo groupadd zion
    sudo groupadd matrix
    
    sudo usermod -aG zion neo
    sudo usermod -aG zion trinity
    
    sudo usermod -aG matrix neo
    sudo usermod -aG matrix apoc
    sudo usermod -aG matrix switch
    
    

    Neo vive en el umbral entre los mundos. Sus permisos lo reflejan.


    FASE 3 — Estructura de directorios: Los Distritos de Matrix

    Se pide crear:

    1. /mission-data

    Carpeta para las operaciones de la Resistencia, acceso exclusivo al grupo zion.

    No debe ser visible para los usuarios del grupo matrix.

    2. /simulacion

    Carpeta donde residirán archivos falsos del “mundo simulado”.

    Acceso libre para el grupo matrix, pero solo lectura para zion (ellos no deben ensuciarse demasiado con la ilusión).

    3. /backdoor

    Carpeta secreta, accesible solo por neo. El resto debe recibir un “Acceso denegado”.

    Comandos sugeridos:

    sudo mkdir /mission-data
    sudo mkdir /simulacion
    sudo mkdir /backdoor
    
    # mission-data (solo zion)
    sudo chown :zion /mission-data
    sudo chmod 770 /mission-data
    
    # simulacion (matrix rwx / zion r-x)
    sudo chown :matrix /simulacion
    sudo chmod 775 /simulacion
    
    # backdoor (solo neo)
    sudo chown neo:neo /backdoor
    sudo chmod 700 /backdoor
    
    

    La carpeta backdoor representa la puerta por la que Neo accede al código subyacente de Matrix.


    FASE 4 — Pruebas de acceso: El Oráculo y los obstáculos

    1. Entrar con cada usuario y comprobar qué carpetas ven.
    2. Crear un archivo dentro de /mission-data con usuarios que NO son del grupo → debe fallar.
    3. Intentar listar /backdoor con un usuario que no sea neo → debe fallar.
    4. Que /simulacion permita escribir a matrix, pero no a zion.

    Esto entrena:

    – su comprensión de permisos

    – su uso de su, ls -l, id, touch, mkdir, groups, etc.


    FASE 5 — Mini misión final: Neutralizar al Agente Smith

    smith → representa al Agente Smith

    Este usuario NO debe pertenecer a ningún grupo de la resistencia ni a matrix.

    Debe tener una carpeta personal sin permisos para nadie más:

    sudo adduser smith
    sudo chmod 700 /home/smith
    
    

    Debes demostrar que smith no puede interactuar con las carpetas del sistema (mission-data, simulacion, backdoor) y explicar por qué, usando ls -ld, permisos y grupos.

  • Docker Compose

    Docker Compose

    1. Qué es Docker Compose

    Docker Compose es un orquestador local. Permite definir varios contenedores y sus relaciones en un único archivo docker-compose.yml. Es como dirigir una pequeña obra de teatro donde cada servicio tiene su papel, y Compose levanta el escenario entero con un comando.

    Puntos clave:

    • Escritura declarativa: defines lo que quieres, Compose lo monta.
    • Multi-servicio: web, base de datos, caches, workers… todo junto.
    • Entornos replicables: mismo resultado en cualquier máquina.

    2. Componentes del archivo docker-compose.yml

    Cada service es un contenedor.

    Los atributos más habituales:

    • image: Imagen a usar.
    • build: Directorio donde está el Dockerfile.
    • ports: Mapeo de puertos HOST:CONTAINER.
    • volumes: Persistencia o montajes locales.
    • environment: Variables de entorno.
    • depends_on: Orden de arranque.
    • networks: Redes personalizadas.

    Ejemplo:

    
    
    
    
    
    services:
      web:
        image: nginx
        ports:
          - "8080:80"
      db:
        image: mysql:8
        environment:
          - MYSQL_ROOT_PASSWORD=atriosecreto
        volumes:
          - dbdata:/var/lib/mysql
    
    volumes:
      dbdata:
    

    3. Comandos esenciales de Docker Compose

    • docker compose up → Levanta todo (añade -d para modo demonio).
    • docker compose down → Apaga y borra contenedores, redes.
    • docker compose ps → Ver contenedores activos del proyecto.
    • docker compose logs -f → Logs en directo.
    • docker compose exec <servicio> <cmd> → Ejecutar dentro del contenedor.
    • docker compose build → Construir imágenes indicadas.

    4. Redes y volúmenes en Compose

    Compose crea:

    • Una red por defecto para todos los servicios.
    • Volúmenes declarados que sobreviven a los up/down.

    Beneficio práctico: un contenedor puede llamar a otro simplemente por su nombre de servicio, por ejemplo:

    
    
    
    
    
    mysql://usuario:pass@db:3306
    

    5. Buenas prácticas

    • Evitar meter passwords en el YAML → usar .env.
    • Un contenedor, un rol.
    • Mantener separado docker-compose.yml y docker-compose.override.yml.
    • Versionar siempre el YAML en Git.
    • Usar volúmenes en lugar de bind-mounts para producción.

    PRÁCTICA GUIADA:
    Web + Base de datos con PHPMyAdmin y Apache

    montar un stack clásico LAMP con un archivo docker-compose.yml.

    Paso 1: crear carpeta del proyecto

    
    
    
    
    
    mkdir proyecto_compose
    cd proyecto_compose
    

    Paso 2: Crear el archivo docker-compose.yml

    
    
    
    
    
    services:
      db:
        image: mysql:8
        container_name: mysql_compose
        environment:
          - MYSQL_ROOT_PASSWORD=curso2025
          - MYSQL_DATABASE=tienda
        volumes:
          - dbdata:/var/lib/mysql
    
      phpmyadmin:
        image: phpmyadmin/phpmyadmin
        container_name: pma_compose
        ports:
          - "8081:80"
        environment:
          - PMA_HOST=db
        depends_on:
          - db
    
      web:
        build: ./web
        container_name: apache_compose
        ports:
          - "8080:80"
        volumes:
          - ./web:/var/www/html
        depends_on:
          - db
    
    volumes:
      dbdata:
    

    Paso 3: Crear la carpeta web con un HTML/PHP mínimo

    
    
    
    
    
    mkdir web
    nano web/index.php
    

    Contenido:

    
    
    
    
    
    <?php
    $mysqli = new mysqli("db", "root", "curso2025", "tienda");
    echo $mysqli->connect_error ? "Error de conexión" : "Conexión OK a la BD";
    ?>
    <h1>Hola desde Apache en Docker Compose</h1>
    

    Paso 4: Crear Dockerfile para Apache + PHP

    Dentro de web/:

    
    
    
    
    
    FROM php:8.2-apache
    RUN docker-php-ext-install mysqli
    

    Paso 5: Levantar el proyecto

    
    
    
    
    
    docker compose up -d
    

    Paso 6: Probar que todo funciona

    Entra al web:

    
    
    
    
    
    curl localhost:8080

    En docker:

    
    
    
    
    

    docker compose logs web 
    docker compose exec db mysql -uroot -p

  • WordPress en Docker (CLI/DockerFile/Compose)

    WordPress en Docker (CLI/DockerFile/Compose)

    Montando Wordpres desde la terminal (CLI)


    1) Requisitos previos

    1.1 Verificar Docker instalado

    docker --versiondocker ps

    Si docker ps da error de permisos, añade tu usuario al grupo docker:

    sudo usermod -aG docker $USER
    newgrp docker
    docker ps

    2) Crear la red para comunicar contenedores

    Vamos a crear una red llamada wp-net. Esto permite que WordPress encuentre a MySQL por nombre de contenedor.

    docker network create wp-net
    docker network ls

    3) Crear volúmenes para persistencia

    Necesitamos guardar:

    • Datos de MySQL (bases de datos)
    • Archivos de WordPress (plugins, temas, subidas)
    docker volume create wp-db
    docker volume create wp-html
    docker volume ls

    4) Levantar la base de datos (MySQL)

    4.1 Ejecutar MySQL con variables de entorno

    Crea un contenedor llamado wp-mysql:

    docker run -d \
      --name wp-mysql \
      --network wp-net \
      -v wp-db:/var/lib/mysql \
      -e MYSQL_DATABASE=wordpress \
      -e MYSQL_USER=wpuser \
      -e MYSQL_PASSWORD=wp-pass-123 \
      -e MYSQL_ROOT_PASSWORD=root-pass-123 \
      mysql:8.0

    4.2 Comprobar que está vivo

    docker ps
    docker logs wp-mysql --tail 30

    Si ves mensajes de “ready for connections” (o similar), perfecto.


    5) Levantar WordPress

    5.1 Ejecutar WordPress apuntando a la DB

    Creamos el contenedor wp-web y lo publicamos en el puerto 8080:

    docker run -d \
      --name wp-web \
      --network wp-net \
      -p 8080:80 \
      -v wp-html:/var/www/html \
      -e WORDPRESS_DB_HOST=wp-mysql:3306 \
      -e WORDPRESS_DB_NAME=wordpress \
      -e WORDPRESS_DB_USER=wpuser \
      -e WORDPRESS_DB_PASSWORD=wp-pass-123 \
      wordpress:latest

    5.2 Verificar logs

    docker logs wp-web --tail 30

    6) Acceso por navegador y asistente de instalación

    Abre:

    • http://localhost:8080

    Completa el instalador:

    • Idioma
    • Título del sitio
    • Usuario admin
    • Password
    • Email

    7) Verificación técnica (para alumnos curiosos)

    7.1 Ver la red y quién está conectado

    docker network inspect wp-net

    7.2 Ver volúmenes y dónde se usan

    docker inspect wp-mysql | grep -i mount -n
    docker inspect wp-web   | grep -i mount -n

    8) Parar, arrancar y reiniciar (operaciones típicas)

    8.1 Parar todo

    docker stop wp-web wp-mysql

    8.2 Arrancar todo

    docker start wp-mysql wp-web

    8.3 Reiniciar WordPress

    docker restart wp-web

    9) Limpieza (sin perder datos)

    Si borras contenedores, los datos siguen porque están en volúmenes.

    9.1 Borrar contenedores

    docker rm-f wp-web wp-mysql

    9.2 Volver a crearlos usando los mismos volúmenes

    Repite los docker run de los pasos 4 y 5 y verás que todo sigue.


    10) Limpieza total (borrado completo)

    ⚠️ Esto elimina la web y la base de datos.

    docker rm -f wp-web wp-mysql 2>/dev/null
    docker volume rm wp-db wp-html 2>/dev/null
    docker network rm wp-net 2>/dev/null

    Anexo A: Diagnóstico de fallos típicos

    A1) WordPress no conecta con MySQL

    1. Ver logs de WordPress:
    docker logs wp-web --tail80
    1. Ver logs de MySQL:
    docker logs wp-mysql --tail80
    1. Asegúrate de que WORDPRESS_DB_HOST=wp-mysql:3306 y que ambos están en wp-net.

    A2) Puerto 8080 ocupado

    Cambia el puerto:

    docker rm -f wp-web
    docker run -d \
      --name wp-web \
      --network wp-net \
      -p 8081:80 \
      -v wp-html:/var/www/html \
      -e WORDPRESS_DB_HOST=wp-mysql:3306 \
      -e WORDPRESS_DB_NAME=wordpress \
      -e WORDPRESS_DB_USER=wpuser \
      -e WORDPRESS_DB_PASSWORD=wp-pass-123 \
      wordpress:latest

    Y entra a http://localhost:8081.


    A3) “Access denied” en MySQL

    Suele ser contraseña/usuario mal puestos. Revisa variables. Si ya creaste la base con datos erróneos, recuerda que MySQL guarda usuarios en el volumen: o corriges dentro, o borras volumen (Anexo 10).

    Montando Wordpres usando DokerFile

    los Dockerfiles listos para hacer docker build directamente (sin Compose) y luego docker run.

    Te dejo estructura + archivos y los comandos exactos.

    wp-docker-build/
    ├─ mysql/
    │  └─ Dockerfile
    └─ wordpress/
       └─ Dockerfile

    mysql/Dockerfile (build directo)

    Este Dockerfile crea una imagen de MySQL “lista”, y el usuario/DB/contraseñas las seguirás pasando en el docker run (porque eso es configuración de despliegue, no de imagen).

    FROM mysql:8.0
    
    # Opcional: configuración extra (descomenta si la necesitas)
    # COPY my.cnf /etc/mysql/conf.d/my.cnf
    
    EXPOSE 3306

    Nota: MySQL oficial ya trae su entrypoint; aquí no necesitas más si vas a usar variables en docker run.

    wordpress/Dockerfile (build directo)

    Imagen WordPress basada en la oficial. Si quieres meter ajustes PHP, te lo dejo ya incluido sin depender de un archivo externo (para que sea “build directo” de verdad).

    FROM wordpress:latest
    
    # Ajustes PHP típicos (subidas, memoria, tiempo)
    RUN set -eux; \
      { \
        echo "upload_max_filesize = 64M"; \
        echo "post_max_size = 64M"; \
        echo "memory_limit = 256M"; \
        echo "max_execution_time = 120"; \
      } > /usr/local/etc/php/conf.d/zzz-custom.ini
    
    EXPOSE 80

    Builds

    Desde la carpeta wp-docker-build/:

    docker build -t wp-mysql:local ./mysql
    docker build -t wp-web:local ./wordpress

    Run (igual que tu artículo, sin Compose)

    Red + volúmenes

    docker network create wp-net
    docker volume create wp-db
    docker volume create wp-html

    MySQL

    docker run -d \
    --name wp-mysql \
    --network wp-net \
    -v wp-db:/var/lib/mysql \
    -e MYSQL_DATABASE=wordpress \
    -e MYSQL_USER=wpuser \
    -e MYSQL_PASSWORD=wp-pass-123 \
    -e MYSQL_ROOT_PASSWORD=root-pass-123 \
    wp-mysql:local

    WordPress

    docker run -d \
    --name wp-web \
    --network wp-net \
    -p 8080:80 \
    -v wp-html:/var/www/html \
    -e WORDPRESS_DB_HOST=wp-mysql:3306 \
    -e WORDPRESS_DB_NAME=wordpress \
    -e WORDPRESS_DB_USER=wpuser \
    -e WORDPRESS_DB_PASSWORD=wp-pass-123 \
    wp-web:local

    Verificación rápida

    docker ps
    docker logs wp-mysql --tail 30
    docker logs wp-web --tail 30

    Y navega a:

    • http://localhost:8080

    Montando Wordpres con Docker Compose

    un docker-compose.yml (WordPress + MySQL) bien comentado para alumnos, con red y volúmenes, y usando las imágenes oficiales (lo más limpio para clase).

    docker-compose.yml

    version: "3.9"
    
    services:
      db:
        image: mysql:8.0
        container_name: wp-mysql
        restart: unless-stopped
    
        # Variables de entorno que MySQL usa para inicializar la BD
        environment:
          MYSQL_DATABASE: wordpress
          MYSQL_USER: wpuser
          MYSQL_PASSWORD: wp-pass-123
          MYSQL_ROOT_PASSWORD: root-pass-123
    
        # Volumen para que la base de datos NO se pierda al borrar el contenedor
        volumes:
          - wp-db:/var/lib/mysql
    
        # Conectamos el servicio a una red privada de Docker
        networks:
          - wp-net
    
      wordpress:
        image: wordpress:latest
        container_name: wp-web
        restart: unless-stopped
    
        # Mapeo de puertos: HOST:CONTENEDOR
        # En el navegador: http://localhost:8080
        ports:
          - "8080:80"
    
        # Variables de entorno para que WordPress sepa cómo conectar con MySQL
        environment:
          WORDPRESS_DB_HOST: db:3306
          WORDPRESS_DB_NAME: wordpress
          WORDPRESS_DB_USER: wpuser
          WORDPRESS_DB_PASSWORD: wp-pass-123
    
        # Volumen para que WordPress (wp-content, plugins, uploads…) se mantenga
        volumes:
          - wp-html:/var/www/html
    
        # Dependencia: arranca db antes (no garantiza “lista”, pero sí orden)
        depends_on:
          - db
    
        networks:
          - wp-net
    
    # Definimos volúmenes "named" (persisten aunque pares/borras contenedores)
    volumes:
      wp-db:
      wp-html:
    
    # Red interna para que los contenedores se vean por nombre (db, wordpress)
    networks:
      wp-net:
        driver: bridge

    Ahora

    docker compose up -d
    docker compose ps
    docker compose logs -f

    Parar y limpiar (sin borrar volúmenes)

    docker compose down

    Borrar TODO incluyendo datos (cuidado)

    docker compose down -v
  • Actividad – La Red del Dictador: La ley de la censura.

    Actividad – La Red del Dictador: La ley de la censura.

    Ya hemos llegado, la democracia se ha convertido en un recuerdo, poco a poco los organismos oficiales han implementado diferentes sistemas de control a la población, primero en las calles, luego en la prensa y televisión y ahora le toca a internet.

    Tú anque estas infiltrado en el Incibe, demomento tienes que hacerte pasar por un escoria-censurador. 

    Te han encargado hacerel prototipo. Como deberas instalar diferentes tipos de herramientas de control y vigilancia, te han pedido que utilices Docker para ir montando los diferentes servicios.

    Lo primero, decidir que podra y que no ver los ciudadanos y asi poder adoctirnar a lo mas jovenes e identificar a los mas adultos para someterlos a una dura vigilancia.

    Entregar el README con toda la documentación necesaria para su instalación en Raspberry y Ubuntu. Adjuntar comentarios, instrucciones de uso de las acciones mas comunes con el programa Hole y añadir biblioteca de direcciones. 

    1. Instalar Docker

    Actualiza el sistema y añade Docker:

    sudo apt update && sudo apt upgrade -y
    curl -sSL https://get.docker.com | sh
    sudo usermod -aG docker $USER

    Reinicia para aplicar permisos:

    sudo reboot

    Comprueba que funciona:

    docker run hello-world

    ⚙️ 2. Crear el volumen y red para Pi-hole

    Esto permite que los datos persistan aunque elimines el contenedor.

    docker volume create pihole_etc
    docker volume create pihole_dnsmasq

    🧩 3. Ejecutar Pi-hole con Docker (modo manual)

    Puedes hacerlo con un solo comando o con docker-compose.
    Empiezo por el comando directo (útil para enseñar):

    docker run -d \
        --name pihole \
        --restart=unless-stopped \
        -e TZ="Europe/Madrid" \
        -e WEBPASSWORD="tu_contraseña_segura" \
        -e DNSMASQ_LISTENING=all \
        -v pihole_etc:/etc/pihole \
        -v pihole_dnsmasq:/etc/dnsmasq.d \
        -p 53:53/tcp -p 53:53/udp \
        -p 80:80/tcp \
        --hostname pi-hole \
        --dns=127.0.0.1 --dns=1.1.1.1 \
        pihole/pihole:latest

    Después de unos segundos, abre en el navegador:

    http://<IP_de_tu_Raspberry>/admin

    🧭 4. Configurar IP estática

    Tu Raspberry necesita una IP fija, por ejemplo:

    sudo nano /etc/dhcpcd.conf

    Y añade:

    interface eth0 static ip_address=192.168.0.200/24 static routers=192.168.0.1 static domain_name_servers=1.1.1.1

    📦 5. (Opcional) Usar Docker Compose

    Es mucho más limpio para mantener el servicio.
    Crea un archivo docker-compose.yml en /home/pi/pihole:

    version: "3"
    services:
      pihole:
        container_name: pihole
        image: pihole/pihole:latest
        restart: unless-stopped
        network_mode: "host"
        environment:
          TZ: 'Europe/Madrid'
          WEBPASSWORD: 'tu_contraseña_segura'
        volumes:
          - ./etc-pihole:/etc/pihole
          - ./etc-dnsmasq.d:/etc/dnsmasq.d

    Y lánzalo:

    docker compose up -d

    Usar network_mode: host es muy recomendable en Raspberry, porque simplifica el uso de los puertos 53 y 80 (evitas conflictos con el firewall de Docker).


    🌐 6. Configurar el router

    Ahora tu Pi-hole está sirviendo DNS en la IP fija (ejemplo: 192.168.0.200).

    Entra en tu router y en Configuración WAN o DNS manual, pon:

    DNS primario: 192.168.0.200 (ojo las ips mostradas son las de este ejemplo)

    DNS secundario: 1.1.1.1

    7. Pruebas

    Desde cualquier dispositivo en la red:

    nslookup google.com

    Debería mostrar como servidor DNS tu Pi-hole.
    Y desde el panel web (http://192.168.0.200/admin) verás todas las peticiones y bloqueos.



    🧠 Preguntas de ejemplo para reflexionar (añadir al Readme.me)

    1. ¿Qué diferencia hay entre cambiar el DNS en un solo dispositivo y hacerlo en el router?
    2. ¿Por qué es importante que la Raspberry tenga una IP fija?
    3. ¿Qué ventajas de privacidad aporta Pi-hole frente a usar DNS públicos?
    4. ¿Qué limitaciones podría tener Pi-hole en una red grande?

    LISTAS DE SERVIDORES

    Estas se añaden desde la interfaz de Holi o Pi-hole en Group Management → Adlists.

    1. General (publicidad y rastreadores):

    https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts https://adaway.org/hosts.txt https://v.firebog.net/hosts/Easyprivacy.txt https://v.firebog.net/hosts/Easylist.txt https://v.firebog.net/hosts/AdguardDNS.txt https://v.firebog.net/hosts/Admiral.txt

    2. Malware y phishing:

    https://v.firebog.net/hosts/Prigent-Malware.txt https://v.firebog.net/hosts/Prigent-Phishing.txt https://mirror.cedia.org.ec/malwaredomains/justdomains https://malware-filter.gitlab.io/malware-filter/urlhaus-filter-hosts.txt

    3. SmartTV y telemetría:

    https://raw.githubusercontent.com/Perflyst/PiHoleBlocklist/master/SmartTV.txt https://raw.githubusercontent.com/Perflyst/PiHoleBlocklist/master/AmazonFireTV.txt

    4. Redes sociales (si quieres bloquearlas):

    https://v.firebog.net/hosts/Social.txt

    🧩 Listas de permiso (Allowlists)

    Estas son útiles para evitar falsos positivos.

    https://raw.githubusercontent.com/anudeepND/whitelist/master/domains/whitelist.txt https://raw.githubusercontent.com/StevenBlack/hosts/master/whitelist/whitelist.txt


    ⚡ Servidores DNS recomendados para Holi

    Estos son servidores DNS upstream (los que Holi consulta cuando no tiene la respuesta en caché):

    NombreDirección IPv4Privacidad / Seguridad
    Cloudflare1.1.1.1 y 1.0.0.1Muy rápido y privado
    Quad99.9.9.9Bloquea malware
    AdGuard DNS94.140.14.14 y 94.140.15.15Bloqueo de anuncios integrado
    OpenDNS208.67.222.222 y 208.67.220.220Filtro parental opcional
    Google DNS8.8.8.8 y 8.8.4.4Muy estable, menos privacidad
  • Actividad – Locos por los Retos de Docker

    Actividad – Locos por los Retos de Docker

    En esta nueva práctica vamos a explotar al máximo las capacidades de nuestros contenedores. Hasta crear un autentico LAB de pentesting

    RECUERDA:
    Crear y ejecutar contenedores
    docker run -it ubuntu
    docker run -it –name mi-ubuntu ubuntu
    docker run –name mi-ubuntu -it -v /datos-persistentes ubuntu
    docker run –name mi-ubuntu -it -v mi-volumen:/datos ubuntu
    docker run -it -v C:\ruta\local:/ruta/en/contenedor ubuntu

    Crear Volumenes
    docker volume create mi-volumen

    Consultar informacion
    docker ps
    docker ps -a
    docker images

    Imagen personalizadas
    docker commit mi-ubuntu mi-imagen-personalizadaOperaciones con contendores
    docker start mi-ubuntu
    docker exec -it mi-ubuntu bash
    docker start -ai mi-ubuntu
    docker rm mi-ubuntu
    docker container prune


    Paso 1

    EMPEZAREMOS TRABAJANDO EN NUESTRA MAQUINA VIRTUAL Kali (o Ubuntu)
    Primero vamos a Crear un entorno de red simple con servidores web para la busqueda de vulnerabilidades y monitorización.

    Crea un directorio para tu proyecto:

    Ejemplo mkdir red1 

    Dentro crea las carpetas httpd y firewall

    Dentro de la carpeta httpd crea un archivo Dockerfile-httpd

    y inserta el siguiente código:

    # Dockerfile para httpd
    FROM httpd:latest
    COPY ./public-html/ /usr/local/apache2/htdocs/
    NOTAS;

    La instrucción COPY ./public-html/ /usr/local/apache2/htdocs/ en el Dockerfile realiza lo siguiente:

    COPY: Es una instrucción de Dockerfile que copia archivos o directorios desde el sistema de archivos del host al sistema de archivos del contenedor.
    ./public-html/: Especifica el directorio en tu máquina local que contiene los archivos que deseas copiar. En este caso, se asume que tienes un directorio llamado public-html en el mismo nivel que tu Dockerfile.

    /usr/local/apache2/htdocs/: Especifica el destino dentro del contenedor donde se copiarán los archivos. Este es el directorio predeterminado de documentos de Apache (httpd), donde se almacenan los archivos que se servirán como contenido web.

    Crea otro  Dockerfile-firewall en la carpeta del firewall y pon:

    # Dockerfile para el firewall
    FROM ubuntu:latest
    RUN apt-get update && apt-get install -y iptables
    COPY ./firewall-rules.sh /usr/local/bin/firewall-rules.sh
    RUN chmod +x /usr/local/bin/firewall-rules.sh
    ENTRYPOINT ["/usr/local/bin/firewall-rules.sh"]
    NOTAS;
    RUN en un Dockerfile se utiliza para ejecutar comandos dentro de la imagen durante el proceso de construcción. Es una de las instrucciones más comunes y permite instalar paquetes, configurar el sistema, y realizar otras tareas necesarias para preparar la imagen.
    La carpeta public-html debes crearela en la de httpd


    Crea un archivo llamado firewall-rules.sh dentro del subdirectorio firewall:

    #!/bin/bash
    # Limpiar reglas existentes
    iptables -F
    
    # Permitir tráfico desde el host
    iptables -A INPUT -i eth0 -s 192.168.1.0/24 -j ACCEPT
    
    # Bloquear todo el tráfico restante
    iptables -A INPUT -j DROP


    Ejemplos y manual de iptables: https://binariocero.com/linux/guia-de-uso-de-iptables-opciones-y-ejemplos Links to an external site.
    OJO, ajusta las direcciones ip (la del host) a tu red actual

    Ahora vamos hacer el compose para el arranque de los contenedores.

    Crea un archivo llamado docker-compose.yml en el directorio principal del proyecto

    version: '3.8'
    
    services:
      web1:
        build:
          context: ./httpd
          dockerfile: Dockerfile-httpd
        networks:
          mynetwork:
            ipv4_address: 172.20.0.2
    
      web2:
        build:
          context: ./httpd
          dockerfile: Dockerfile-httpd
        networks:
          mynetwork:
            ipv4_address: 172.20.0.3
    
      firewall:
        build:
          context: ./firewall
          dockerfile: Dockerfile-firewall
        cap_add:
          - NET_ADMIN
        networks:
          mynetwork:
            ipv4_address: 172.20.0.4
    
    networks:
      mynetwork:
        driver: bridge
        ipam:
          config:
            - subnet: 172.20.0.0/16


    docker-compose up --build
    * Realiza pruebas de conexion entre el host y los contenedores.
    * En cada servidor web modifica el index.html para que ponga server1, server2 o lo que quieras.

    Posibles problemas
    Para ver las redes: sudo docker network ls
    Si necesitas borrar la red: sudo docker network  rm  nombreRed
    Si teneis problemas de permisos usar siempre sudo

    Puede ser que tengas que cambiar el archivo de info del repositorio de parrot
    /etc/containers/registries.conf
    [registries.search]registries = [‘docker.io’,’quay.io’]

    Paso 2

    Configurar un entorno de laboratorio con Parrot 

    Crea una nueva carpeta para parrot y crea el dockerfile

    Dockerfile para Parrot Security OS

    # Usar la imagen oficial de Parrot Security OS
    FROM parrotsec/security:latest
    
    # Actualizar y instalar herramientas
    RUN apt-get update && apt-get install -y \
        metasploit-framework \
        nmap \
        burpsuite \
        wireshark \
        john \
        hydra \
        git \
        vim \
        wget && 
       
     # Establecer el punto de entrada CMD ["/bin/bash"]

    Además de las herramientas mencionadas anteriormente, aquí tienes algunas adicionales que podrías considerar:

    1. Aircrack-ng: Suite de herramientas para evaluar la seguridad de redes Wi-Fi.
    2. SQLmap: Herramienta para detectar y explotar vulnerabilidades de inyección SQL.
    3. Nikto: Escáner de servidores web para detectar vulnerabilidades.
    4. Gobuster: Herramienta para la enumeración de directorios y archivos en servidores web.


    Ejecución del Contenedor

    Para construir y ejecutar el contenedor:

    # Construir la imagen
    docker build -t parrot-pentest .
    
    # Ejecutar el contenedor
    docker run -it parrot-pentest

    Paso 3


    En los pasos anteriores has creado un docker-composer para montar 3 contenedores (dos de web y el firewall). Luego has creado un contenedor parrot con herramientas, pero si te fijas, este esta en una red diferente.

    Ahora debes modificar el YML del paso 1 para que cree todo el proceso del paso 1 y 2. Es decir los dos de web, el firewall y el parrot con los dokerfiles ya creados.

    Ayuda
    Si necesitas borrar la red: sudo docker network  rm  nombreRed
    Para eliminar un contenedor sudo docker rm nombre o id del contenedor
    Para parar un contenderor: sudo docker stop nombre o id del contenedor

    Si quieres pararlos todos: sudo docker stop $(docker ps -q)
    Para borrar todos los de una red en concreto: sudo docker rm -f nombreDeLaRed

    Como vamos a usar parrot para administrar la red, debemos indicarle tanot que sea interactivo como que es una maquina administradora.

    Ejemplo:

    version: '3.8'
    
    services:
      # Servicio web1
      web1:
        build:
          context: ./httpd
          dockerfile: Dockerfile-httpd
        networks:
          mynetwork:
            ipv4_address: 172.20.0.2
    
      # Servicio web2
      web2:
        build:
          context: ./httpd
          dockerfile: Dockerfile-httpd
        networks:
          mynetwork:
            ipv4_address: 172.20.0.3
    
      # Servicio de firewall
      firewall:
        build:
          context: ./firewall
          dockerfile: Dockerfile-firewall
        cap_add:
          - NET_ADMIN  # Esto otorga privilegios para manipular la red
        networks:
          mynetwork:
            ipv4_address: 172.20.0.4
    
      # Nuevo contenedor Parrot Security OS
      parrot:
        build:
          context: ./parrotsec  # Ubicación del Dockerfile para Parrot Security OS
          dockerfile: Dockerfile-parrot  # Nombre del Dockerfile que contiene las instrucciones
        networks:
          mynetwork:
            ipv4_address: 172.20.0.5
        cap_add:
          - SYS_ADMIN  # Permite algunos privilegios elevados si es necesario para Parrot OS
        stdin_open: true  # Mantiene la terminal abierta para interacciones
        tty: true  # Habilita un terminal interactivo
    
    # Definición de la red "mynetwork"
    networks:
      mynetwork:
        driver: bridge
        ipam:
          config:
            - subnet: 172.20.0.0/16  # Subred definida para la red interna

    El dockerfile, tambien tenemos que prepararlo para el yml, cambiando o poniendo el nombre del archivo. Crea una carpeta llamada parrotsec en tu proyecto y dentro de ella coloca el Dockerfile-parrot

    
    # Usar la imagen oficial de Parrot Security OS
    FROM parrotsec/security:latest
    
    # Actualizar y instalar herramientas
    RUN apt-get update && apt-get install -y \
        metasploit-framework \
        nmap \
        burpsuite \
        wireshark \
        john \
        hydra \
        git \
        vim \
        wget \
        && apt-get clean
    
    # Establecer el directorio de trabajo
    WORKDIR /root
    
    # Ejecutar un comando para mantener el contenedor activo
    CMD [ "bash" ]

    docker-compose up en el directorio de tu proyecto. Docker Compose construirá y levantará todos los contenedores

    Dentro del conetenedor de parrot ejecuta un nmap para rastrear todas las ips de la red en la que se encuentra.

    nmap -sn direccionRed/mascara
    Ejemplo: nmap -sn 172.10.0.0/24

    Ayuda

    Si necesitas borrar la red: sudo docker network  rm  nombreRed
    Para eliminar un contenedor sudo docker rm nombre o id del contened

    
    
    
    

    Paso 4

    Ahora vamos a realizar  diferentes rastreos con nmap en la subred.
     

    1. Escaneo básico de una dirección IP en la red:

    Supongamos que quieres escanear la dirección IP 172.20.0.2 (que es la dirección IP de tu contenedor web1). Puedes ejecutar el siguiente comando en el contenedor de Parrot:

    nmap 172.20.0.2

    Este comando realiza un escaneo básico de los puertos más comunes del contenedor web1.

    2. Escaneo de todos los puertos:

    Si quieres hacer un escaneo de todos los puertos de una máquina en la red, puedes usar la opción -p- para escanear todos los puertos (del 1 al 65535):

    nmap -p- 172.20.0.2

    Este comando escaneará todos los puertos de la IP 172.20.0.2 (el contenedor web1) para verificar cuáles están abiertos.

    3. Escaneo detallado con información de servicios:

    Si quieres obtener más información acerca de los servicios que están corriendo en un contenedor (por ejemplo, versión del servicio), puedes usar la opción -sV que realiza un escaneo de versión de servicios:

    nmap -sV 172.20.0.2

    Esto no solo escaneará los puertos, sino que también intentará detectar la versión de los servicios que están corriendo en esos puertos.

    4. Escaneo con detección de sistema operativo:

    Puedes agregar la opción -O para intentar detectar el sistema operativo que está ejecutando el contenedor o la máquina objetivo:

    nmap -O 172.20.0.2

    Este comando intentará identificar el sistema operativo basado en el comportamiento de los puertos y las respuestas de red.

    5. Escaneo en una subred completa:

    Si deseas escanear toda la red para encontrar qué dispositivos están activos y qué puertos están abiertos, puedes especificar una subred completa. Por ejemplo, si quieres escanear la subred 172.20.0.0/24, puedes usar el siguiente comando:

    nmap 172.20.0.0/24

    Este comando escaneará todas las direcciones IP de 172.20.0.1 a 172.20.0.254 dentro de la subred 172.20.0.0/24 para ver qué máquinas están activas y qué puertos tienen abiertos.

    6. Escaneo de puertos específicos:

    Si solo te interesa escanear puertos específicos, puedes usar la opción -p para definir los puertos que quieres escanear. Por ejemplo, si solo te interesa saber si el puerto 80 (HTTP) y 443 (HTTPS) están abiertos en web1, puedes hacer lo siguiente:

    nmap -p 80,443 172.20.0.2

    Este comando solo escaneará los puertos 80 y 443 en la IP 172.20.0.2.

    7. Escaneo silencioso (sin descubrimiento de hosts):

    Si quieres escanear sin enviar demasiada información a la red (es decir, hacer un escaneo «silencioso»), puedes usar la opción -Pn que desactiva el descubrimiento de hosts (es decir, no verificará si la máquina está en línea antes de hacer el escaneo):

    nmap -Pn 172.20.0.2

    Esto puede ser útil si deseas realizar un escaneo sin alertar a sistemas de monitoreo de red, ya que nmap no enviará un paquete de «descubrimiento» al objetivo.

    8. Escaneo de una máquina con múltiples servicios (ejemplo de escaneo en Parrot):

    Si quisieras escanear tu red en busca de múltiples servicios o máquinas y visualizar la topología de red de manera más detallada, puedes usar el comando siguiente para hacer un escaneo más avanzado:

    nmap -sS -sV -O -T4 172.20.0.0/24

    Este comando hace lo siguiente:

    • -sS: Escaneo de tipo «SYN» (más sigiloso).
    • -sV: Detección de versiones de servicios.
    • -O: Detección del sistema operativo.
    • -T4: Ajusta la velocidad del escaneo para hacerlo más rápido.

    Escaneará toda la subred 172.20.0.0/24 buscando máquinas activas y proporcionando información detallada sobre los servicios y sistemas operativos detectados.

    9. Escaneo de vulnerabilidades con scripts Nmap (NSE):

    Nmap incluye una gran cantidad de scripts de detección de vulnerabilidades que puedes ejecutar con el parámetro --script. Por ejemplo, para detectar posibles vulnerabilidades relacionadas con SMB, puedes ejecutar el siguiente comando:

    nmap --script smb-vuln* 172.20.0.2

    Esto ejecutará todos los scripts de vulnerabilidades SMB que están disponibles en Nmap y tratará de detectar cualquier posible problema en el puerto SMB (445).

    Cómo ejecutar los comandos en tu contenedor Parrot:

    1. Accede al contenedor Parrot desde tu máquina host con el siguiente comando:docker exec -it <nombre_o_id_del_contenedor_parrot> bashEl nombre del contenedor lo puedes obtener con docker ps.
    2. Una vez dentro del contenedor, simplemente ejecuta los comandos de nmap como si estuvieras en cualquier otra máquina Linux.
    • Red interna de Docker: Todos estos escaneos solo serán visibles dentro de la red interna de Docker. Si estás ejecutando estos escaneos desde el contenedor Parrot, solo podrás escanear los contenedores que estén en la misma red (en este caso, mynetwork).

    Paso 5 de 80

    Vamos a ver ahora el trafico que se produce dentro de la red, para ello usremos wiresark desde la terminal del contenedor de parrot.

    Primero verifica las interfaces de red dentro del contenedor:

    ip a

    Normalmente, la interfaz  será eth0. Puedes verificar el tráfico de la subred capturando paquetes en esta interfaz.


    3️⃣ Capturar tráfico con Wireshark

    Dentro del contenedor Parrot, puedes iniciar Wireshark en modo terminal con tshark:

    tshark -i eth0

    4️⃣ Generar tráfico entre los contenedores

    Desde otro terminal, puedes generar tráfico entre los servicios. Por ejemplo, desde web1 puedes hacer peticiones a web2:

    docker exec -it web1 curl http://172.20.0.3

    O puedes hacer un ping desde Parrot a web2:

    ping -c 4 172.20.0.3

    Si quieres capturar únicamente tráfico HTTP (puerto 80), puedes ejecutar:

    tshark -i eth0 port 80

    Para tráfico ICMP (pings):

    tshark -i eth0 icmp

    5️⃣ Filtrar tráfico en Wireshark

    En la interfaz gráfica de Wireshark, puedes filtrar paquetes con:

    • ip.addr == 172.20.0.2 → Para ver solo tráfico de web1
    • ip.addr == 172.20.0.3 → Para ver tráfico de web2
    • http → Para capturar solo tráfico HTTP
    • icmp → Para capturar solo tráfico de ping

    Paso 6 de 80

    Ahora vamos a hacerlo, pero fuera de la subred

    Identificar la interfaz de Docker en el host

    Docker usa una interfaz virtual llamada bridge para manejar redes internas. Para encontrar la interfaz de la red mynetwork (172.20.0.0/16), ejecuta:

    ip a | grep docker

    Verás algo como esto:

    3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0

    • Si la red mynetwork no usa la interfaz docker0, identifica su nombre con:

    docker network inspect mynetwork | grep Gateway

    El resultado te dará el Gateway y te ayudará a identificar la interfaz.


    Capturar tráfico con Wireshark en el host

    Abre Wireshark en tu sistema Parrot y selecciona la interfaz de red de Docker, por ejemplo:

    • docker0
    • br-xxxxxxxxxxxx (si Docker creó una interfaz bridge específica)

    Puedes verificar qué interfaces están activas con:

    ip link show


    Filtrar tráfico de la subred Docker

    Usa estos filtros en Wireshark para ver solo el tráfico de la subred 172.20.0.0/16:

    • Capturar todo el tráfico de Docker:ip.addr == 172.20.0.0/16
    • Capturar tráfico HTTP entre los contenedores:tcp.port == 80
    • Capturar pings (ICMP) entre contenedores:icmp

    No olvides generar trafico entre los contenedores mientras haces el rastreo.

    Paso 7

    En el contenedor Web 1 vamos a instalar PHP para Apache, y vamos a poner una pagina que identifique la ubicación del usuario que hace la petición.

    Aquí tienes un ejemplo de como hacerlo.

    <?php
    function getUserLocation($ip) {
        $url = «http://ip-api.com/json/{$ip}?fields=status,country,regionName,city,query»;
        $response = file_get_contents($url);
        $data = json_decode($response, true);    if ($data[‘status’] == ‘success’) {
            return [
                ‘ip’ => $data[‘query’],
                ‘country’ => $data[‘country’],
                ‘region’ => $data[‘regionName’],
                ‘city’ => $data[‘city’]
            ];
        } else {
            return null;
        }
    }// Obtener la IP del usuario
    $ip = $_SERVER[‘REMOTE_ADDR’];
    $location = getUserLocation($ip);if ($location) {
        echo «IP: » . $location[‘ip’] . «<br>»;
        echo «País: » . $location[‘country’] . «<br>»;
        echo «Región: » . $location[‘region’] . «<br>»;
        echo «Ciudad: » . $location[‘city’] . «<br>»;
    } else {
        echo «No se pudo determinar la ubicación.»;
    }
    ?>

    Para acceder desde el navegador del host a la página PHP alojada en uno de tus contenedores web1 o web2, sigue estos pasos:

    Exponer el puerto del servidor web en Docker Compose

    Actualmente, en tu docker-compose.yml, los servicios web1 y web2 no tienen puertos expuestos al host. Para hacerlo, edita el archivo y agrega la sección ports:

    services:
      web1:
        build:
          context: ./httpd
          dockerfile: Dockerfile-httpd
        networks:
          mynetwork:
            ipv4_address: 172.20.0.2
        ports:
          – «8080:80»  # Expone el puerto 80 del contenedor como 8080 en el host  web2:
        build:
          context: ./httpd
          dockerfile: Dockerfile-httpd
        networks:
          mynetwork:
            ipv4_address: 172.20.0.3
        ports:
          – «8081:80»  # Expone el puerto 80 del contenedor como 8081 en el host

    Con esta configuración:

    • web1 será accesible desde el host en http://localhost:8080
    • web2 será accesible desde el host en http://localhost:8081

    Aplicar los cambios y reiniciar los contenedores

    Después de editar docker-compose.yml, aplica los cambios reiniciando los contenedores:

    docker-compose down

    docker-compose up -d

    Paso 8  

    Ahora vamos a subir un conjunto de contenedores a Docker Hub junto con su docker-compose.yml

    Si no tienes una cuenta en Docker Hub, regístrate en https://hub.docker.com/.

    Luego, inicia sesión en Docker desde la terminal: 

    docker login

    Docker Compose usa imágenes personalizadas (build), así que primero debes crear y etiquetar las imágenes correctamente con tu usuario de Docker Hub.

    Edita el docker-compose.yml para usar imágenes con nombres de Docker Hub:

    services:
      web1:
        build:
          context: ./httpd
          dockerfile: Dockerfile-httpd
        image: tu_usuario_docker/web1:latest  # Define la imagen con tu usuario
        networks:
          mynetwork:
            ipv4_address: 172.20.0.2
        ports:
          - "8080:80"
    
      web2:
        build:
          context: ./httpd
          dockerfile: Dockerfile-httpd
        image: tu_usuario_docker/web2:latest
        networks:
          mynetwork:
            ipv4_address: 172.20.0.3
        ports:
          - "8081:80"
    
      firewall:
        build:
          context: ./firewall
          dockerfile: Dockerfile-firewall
        image: tu_usuario_docker/firewall:latest
        cap_add:
          - NET_ADMIN
        networks:
          mynetwork:
            ipv4_address: 172.20.0.4
    
      parrot:
        build:
          context: ./parrotsec
          dockerfile: Dockerfile-parrot
        image: tu_usuario_docker/parrotsec:latest
        networks:
          mynetwork:
            ipv4_address: 172.20.0.5
        cap_add:
          - SYS_ADMIN
        stdin_open: true
        tty: true
    
    networks:
      mynetwork:
        driver: bridge
        ipam:
          config:
            - subnet: 172.20.0.0/16

    Con esta configuración, cada servicio tendrá una imagen específica en Docker Hub.

    Ejecuta los siguientes comandos para construir y etiquetar cada imagen:

    docker build -t tu_usuario_docker/web1:latest ./httpd -f Dockerfile-httpd
    docker build -t tu_usuario_docker/web2:latest ./httpd -f Dockerfile-httpd
    docker build -t tu_usuario_docker/firewall:latest ./firewall -f Dockerfile-firewall
    docker build -t tu_usuario_docker/parrotsec:latest ./parrotsec -f Dockerfile-parrot

    Una vez construidas las imágenes, súbelas a Docker Hub con:

    docker push tu_usuario_docker/web1:latest
    docker push tu_usuario_docker/web2:latest
    docker push tu_usuario_docker/firewall:latest
    docker push tu_usuario_docker/parrotsec:latest

    Subir el docker-compose.yml a un repositorio

    Docker Hub no almacena archivos de configuración, por lo que es recomendable subir el docker-compose.yml a GitHub

    Debes crear un repositorio Git o trasladar el archivo yml a un repositorio que tengas.

    Luego lo añades y haces el push como siempre

    Paso 9

     Pidele la url del repositorio donde tenga el compose a un compañero.

    Crea una nueva carpeta y ejecuta el compose

    git clone https://github.com/tu_usuario/docker-compose-repo.git
    cd docker-compose-repo
    docker-compose up -d

    Nota: como lo que estas descargando es el yml, puedes modificarlo a tu gusto antes de hacer el up.

    Ejemplo de solución

    Locos-por-los-Retos
  • [Reto] – Dockerizar app JEE (Tomcat 10 + MySQL)

    [Reto] – Dockerizar app JEE (Tomcat 10 + MySQL)

    Contexto: JEE sin frameworks, sin Maven, WAR exportado desde Eclipse (Dynamic Web Project).
    Front: HTML/JS con fetch consumiendo JSON.

    Requisitos

    • Docker instalado (Docker Desktop o Engine)
    • Tener el .war exportado desde Eclipse
    • Driver MySQL dentro del WAR en WEB-INF/lib (esto es clave sin Maven)

    Preparar el WAR desde Eclipse

    1. Click derecho al proyecto → Export…
    2. Web → WAR file
    3. Guarda TuApp.war (lo usaremos en ambos métodos)

    Checklist rápido:

    • Abre el WAR como zip → existe WEB-INF/lib/mysql-connector-*.jar

    PARTE 1 — Docker SIN Compose (a mano, entendiendo todo)

    1.1 Crear una red Docker (para que “se vean” por nombre)

    docker network create jee-net

    1.2 Crear un volumen para MySQL (persistencia real)

    docker volume create jee-mysql-data

    1.3 Levantar MySQL en contenedor

    docker run -d \
    --name jee-mysql \
    --network jee-net \
    -e MYSQL_ROOT_PASSWORD=root1234 \
    -e MYSQL_DATABASE=jee_app \
    -e MYSQL_USER=jee \
    -e MYSQL_PASSWORD=jee1234 \
    -v jee-mysql-data:/var/lib/mysql \
    -p 3306:3306 \
    mysql:8.0 \
    --default-authentication-plugin=mysql_native_password

    Verificar logs:

    docker logs -f jee-mysql

    (espera a que salga algo tipo “ready for connections”.)

    1.4 Crear base/tablas (opción guiada en vivo)

    Entrar a MySQL:

    docker exec -it jee-mysql mysql -u jee -pjee1234 jee_app

    Ejemplo de SQL (hazlo con tus tablas reales):

    CREATE TABLE IF NOT EXISTS alumnos (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nombre VARCHAR(100) NOT NULL
    );INSERT INTO alumnos(nombre) VALUES ('Ada'), ('Alan');
    SELECT * FROM alumnos;

    Salir:

    exit

    1.5 Preparar Tomcat 10 con tu WAR (sin construir imagen)

    Aquí hay dos formas. La más didáctica es montar el WAR como volumen.

    Crea carpeta local:

    mkdir -p app
    cp TuApp.war app/ROOT.war

    Levanta Tomcat 10 y monta el WAR:

    docker run -d \
    --name jee-tomcat \
    --network jee-net \
    -p 8080:8080 \
    -e DB_HOST=jee-mysql \
    -e DB_PORT=3306 \
    -e DB_NAME=jee_app \
    -e DB_USER=jee \
    -e DB_PASS=jee1234 \
    -v "$(pwd)/app/ROOT.war:/usr/local/tomcat/webapps/ROOT.war:ro" \
    tomcat:10.1-jdk17-temurin

    Logs:

    docker logs -f jee-tomcat

    1.6 Punto crucial: JDBC en Docker (host ≠ localhost)

    En tu código, la URL debe usar el nombre del contenedor:

    • localhost
    • jee-mysql (porque ese es el --name del contenedor en la misma red)

    1.7 Probar la API

    curl http://localhost:8080/tu-endpoint

    o en navegador.

    1.8 Parar y limpiar (para enseñar “ciclo de vida”)

    Parar:

    docker stop jee-tomcat jee-mysql

    Borrar contenedores:

    docker rm jee-tomcat jee-mysql

    Volumen (¡ojo, borra datos!):

    docker volume rm jee-mysql-data

    PARTE 2 — Docker CON Compose (modo “un comando y listo”)

    Aquí el objetivo es:
    ✅ 1 carpeta, ✅ 1 compose, ✅ build opcional, ✅ init automático con SQL.

    2.1 Estructura

    taller-compose/
    ├─ docker-compose.yml
    ├─ app/
    │ ├─ Dockerfile
    │ └─ ROOT.war
    └─ db/
    └─ init.sql

    Copia tu WAR:

    mkdir -p taller-compose/app taller-compose/db
    cp TuApp.war taller-compose/app/ROOT.war

    2.2 app/Dockerfile (Tomcat 10 + WAR)

    FROM tomcat:10.1-jdk17-temurin
    
    RUN rm -rf /usr/local/tomcat/webapps/*
    
    COPY ROOT.war /usr/local/tomcat/webapps/ROOT.war
    
    EXPOSE 8080

    2.3 db/init.sql (carga automática al primer arranque)

    CREATE TABLE IF NOT EXISTS alumnos (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nombre VARCHAR(100) NOT NULL
    );INSERT INTO alumnos(nombre) VALUES ('Ada'), ('Alan');

    2.4 docker-compose.yml (MySQL + Tomcat)

    services:
      db:
        image: mysql:8.0
        container_name: jee-mysql
    
        environment:
          MYSQL_ROOT_PASSWORD: root1234
          MYSQL_DATABASE: jee_app
          MYSQL_USER: jee
          MYSQL_PASSWORD: jee1234
    
        ports:
          - "3306:3306"
    
        volumes:
          - dbdata:/var/lib/mysql
          - ./db/init.sql:/docker-entrypoint-initdb.d/01_init.sql:ro
    
        command: --default-authentication-plugin=mysql_native_password
    
      app:
        build: ./app
        container_name: jee-tomcat
    
        depends_on:
          - db
    
        ports:
          - "8080:8080"
    
        environment:
          DB_HOST: db
          DB_PORT: 3306
          DB_NAME: jee_app
          DB_USER: jee
          DB_PASS: jee1234
    
    volumes:
      dbdata:

    Ojo al detalle nerd importante:
    En Compose, el hostname correcto es db (nombre del servicio), no el container_name.

    2.5 Arranque

    Dentro de taller-compose/:

    docker compose up -d --build
    docker compose ps

    Logs:

    docker compose logs -f db
    docker compose logs -f app

    2.6 Probar

    curl http://localhost:8080/tu-endpoint

    2.7 Parar

    docker compose down

    Parar y borrar volúmenes (reinicio total):

    docker compose down -v
  • 2.8 –  [Reto] Matrix: Huellas en el Código

    2.8 – [Reto] Matrix: Huellas en el Código

    La Resistencia ha detectado alteraciones en el sistema.

    Alguien ha entrado sin permiso. El sistema (Linux) registra todas las trazas, pero necesitan operadores capacitados para reconstruir lo ocurrido.

    El alumno se convierte en Analista de Zion, encargado de rastrear la actividad de los usuarios creados en el Reto 1: neo, trinity, apoc, switch, smith.

    El objetivo:

    Descubrir quién ha accedido, cuándo, desde dónde, qué ha tocado, y si ha conseguido privilegios dentro de Matrix.


    FASE 1 — La lluvia de código (logs en tiempo real)

    Orden del Oráculo: observar el flujo del sistema en directo.

    1. Ver los mensajes del sistema en tiempo real: sudo journalctl -f
    2. Cambiar entre usuarios mientras journalctl está abierto (por ejemplo, su - trinity, luego exit).
    3. Detectar en el log: • el evento de autenticación • si el login se ha permitido o ha fallado

    Resultado esperado: reconocer entradas como “session opened”, “session closed”, fallos PAM, etc.

    :

    Cada login es una “vibración en el código de Matrix”, y journalctl es la pantalla donde llueve el código verde.


    FASE 2 — El rastro de entrada y salida

    Aquí usamos last, who, w.

    1. ¿Quién está conectado ahora mismo?

    who
    w
    
    

    2. ¿Qué usuarios han entrado en el sistema en los últimos días?

    last
    
    

    3. ¿Se detectan accesos fallidos?

    (En Distros Debian/Ubuntu)

    sudo zgrep -i "failed" /var/log/auth.log*
    
    

    Preguntas tipo misión:

    • ¿Trinity accedió ayer?
    • ¿Apoc intentó entrar varias veces y falló?
    • ¿Neo ha usado sudo recientemente?
    • ¿Smith existe en los logs aunque no debería moverse por el sistema?

    FASE 3 — Sudo: quién ha manipulado Matrix

    sudo journalctl -u sudo
    
    

    o en Ubuntu también:

    sudo grep 'COMMAND=' /var/log/auth.log
    
    

    Descubrir si “Neo ha modificado normas de la simulación” o si “Smith ha intentado elevarse”.

    Tareas:

    1. Ver qué comandos se han ejecutado con sudo.
    2. Identificar el usuario que los ejecutó.
    3. Detectar intentos de sudo fallidos.

    Bonus para rizar el rizo:

    sudo journalctl | grep sudo
    
    

    FASE 4 — Huellas en el historial: El Código dejado atrás

    Revisar qué comandos ha ejecutado cada usuario.

    Para ello, entrar como cada uno:

    sudo su - trinity
    history
    
    

    o inspeccionar los archivos:

    • ~/.bash_history

    ~/.zsh_history (si procede)

    Preguntas narrativas:

    • ¿Quién creó un archivo dentro de /simulacion fuera de su hora de trabajo?
    • ¿Quién intentó entrar a /backdoor aunque no tenía permisos?
    • ¿Qué usuario ejecutó comandos sospechosos como sudo su?
    • ¿Acaso Smith intentó copiar algo desde mission-data?

    FASE 5 — Localizar la intrusión: reconstrucción forense

    “Durante la noche, uno de los usuarios ha intentado manipular el código de Matrix.

    El sistema registró 3 accesos fallidos, un uso indebido de sudo y una entrada en /simulacion fuera del horario.” (Realiza con un usuario las acciones para mantener la ficción)

    Tu misión es:

    1. Localizar esos eventos.
    2. Determinar qué usuario lo hizo.
    3. Extraer las líneas exactas de log donde ocurrió.
    4. Preparar un informe breve tipo forense: • usuario implicado • hora • evento • interpretación técnica

    Aquí se cruzan:

    • journalctl
    • auth.log
    • last
    • history
    • permisos
  • Pildora – Instalación de programa desde un repositorio.

    Pildora – Instalación de programa desde un repositorio.

    Los alumnos deben instalar y ejecutar FossFLOW en un servidor Ubuntu, probar sus funcionalidades básicas y generar un README.md propio documentando todo el proceso.

    Requisitos del sistema

    El servidor debe tener:

    • Ubuntu 20.04, 22.04 o superior
    • Acceso por terminal
    • Git
    • Node.js + npm
    • (Opcional) Docker + Docker Compose
    • Navegador local o túnel SSH para acceder al servicio web

    1. Actualizar el servidor

    sudo apt update && sudo apt upgrade -y


    2. Instalar Git

    sudo apt install git -y

    3. Instalar Node.js LTS y npm

    Recomendado usar NodeSource:

    curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - sudo apt install -y nodejs

    Verificar:

    node -v npm -v

    4. Clonar el repositorio FossFLOW

    git clone https://github.com/stan-smith/FossFLOW.git cd FossFLOW

    5. Instalar dependencias del proyecto

    npm install

    6. Construir el proyecto

    npm run build:lib

    7. Ejecutar la aplicación

    La versión de desarrollo suele ser:

    npm run dev

    El servidor quedará escuchando en:

    http://localhost:3000

    En su PC local: IN

    ssh -L 3000:localhost:3000 usuario@IP_DEL_SERVIDOR

    Luego abrir en su navegador local:

    http://localhost:3000

    8. Probar la aplicación

    Cada alumno debe:

    • Crear un diagrama isométrico.
    • Añadir varios elementos.
    • Guardar o exportar el proyecto.
    • Importarlo nuevamente para verificar funcionamiento.

    9. Crear un README.md propio

    README.md

    Debe contener:

    1. Descripción del proyecto
    2. Requisitos del servidor Ubuntu
    3. Instrucciones de instalación paso a paso
    4. Comandos utilizados
    5. Cómo se ejecuta (modo dev o Docker)
    6. Cómo acceder desde el navegador
    7. Problemas encontrados y soluciones
    8. Captura de la prueba realizada (o explicar cómo la realizó)
    9. Conclusiones finales