Categoría: Sistemas

  • 7. Funciones y Modularización del Código

    Los scripts que has hecho hasta ahora funcionan bien, pero tienen un problema: si el código crece, se convierte en algo difícil de mantener, leer y modificar. Las funciones solucionan esto al permitir reutilizar código y dividirlo en partes más pequeñas.

    Este módulo te enseñará a definir funciones, pasar argumentos, devolver valores y modularizar scripts más complejos.


    1. ¿Qué es una función en Bash?

    Una función es un bloque de código con nombre propio que puedes ejecutar cuando quieras, tantas veces como quieras.

    En pseudolenguaje:

    
    
    
    
    
    definir función → hacer algo
    llamar función → ejecuta ese algo
    

    2. Sintaxis para definir funciones

    Bash acepta dos sintaxis equivalentes:

    Forma 1:

    
    
    
    
    
    nombre_funcion() {
        comandos
    }
    

    Forma 2:

    
    
    
    
    
    function nombre_funcion {
        comandos
    }
    

    Ambas son válidas. Lo más usado es la primera por ser más limpia.


    3. Llamar a una función

    Una vez definida, basta con usar su nombre:

    
    
    
    
    
    mi_funcion
    

    Ejemplo:

    
    
    
    
    
    saludar() {
        echo "Hola desde la función"
    }
    
    saludar
    

    Salida:

    
    
    
    
    
    Hola desde la función
    

    4. Funciones con parámetros

    Las funciones pueden recibir argumentos igual que el script completo.

    Ejemplo:

    
    
    
    
    
    saludar() {
        echo "Hola $1"
    }
    
    saludar "Laura"
    

    Salida:

    
    
    
    
    
    Hola Laura
    

    Si deseas más parámetros:

    • $1 → primer argumento
    • $2 → segundo
    • $@ → todos

    5. Funciones que devuelven valores

    En Bash una función no “devuelve” valores como en otros lenguajes. Lo más común es:

    • Imprimir en pantalla
    • Guardar en variables
    • O usar return solo para códigos numéricos (0–255)

    5.1 Método estándar (captura por sustitución)

    
    
    
    
    
    sumar() {
        echo $(( $1 + $2 ))
    }
    
    resultado=$(sumar 3 4)
    echo "Resultado: $resultado"
    

    Salida:

    
    
    
    
    
    Resultado: 7
    

    5.2 return (solo numérico)

    
    
    
    
    
    comparar() {
        if [ $1 -gt $2 ]; then
            return 0
        else
            return 1
        fi
    }
    
    comparar 10 5
    
    if [ $? -eq 0 ]; then
        echo "El primero es mayor"
    fi
    

    6. Variables locales vs globales

    Por defecto, las variables en Bash son globales dentro del script.

    Para limitar su alcance dentro de la función, usa local:

    
    
    
    
    
    prueba() {
        local mensaje="Hola"
        echo "$mensaje"
    }
    
    prueba
    echo "$mensaje"  # Está vacía fuera de la función
    

    7. Organización modular del código

    A partir de ahora puedes:

    • Definir varias funciones en un mismo script
    • Usar funciones como “bloques” lógicos
    • Separar responsabilidades

    Ejemplo de script modular:

    
    
    
    
    
    mostrar_menu() {
        echo "1) Fecha"
        echo "2) Usuario"
        echo "3) Salir"
    }
    
    procesar_opcion() {
        case $1 in
            1) date ;;
            2) echo $USER ;;
            3) exit ;;
            *) echo "Opción inválida" ;;
        esac
    }
    
    mostrar_menu
    read -p "Opción: " op
    procesar_opcion $op
    

    8. Incluir funciones desde otros archivos (source)

    Esto permite crear “librerías” de funciones.

    Por ejemplo, en utils.sh:

    
    
    
    
    
    saludar() {
        echo "Hola $1"
    }
    

    En otro script:

    
    
    
    
    
    source utils.sh
    saludar "Carlos"
    

    Esto se usa para:

    • reutilizar código
    • crear módulos de funciones
    • evitar duplicar scripts

    9. Ejemplos

    Ejemplo 1: Función suma

    
    
    
    
    
    sumar() {
        echo $(( $1 + $2 ))
    }
    
    resultado=$(sumar 5 3)
    echo "Resultado: $resultado"
    

    Ejemplo 2: Librería simple

    log.sh:

    
    
    
    
    
    log() {
        echo "[LOG] $1"
    }
    

    test.sh:

    
    
    
    
    
    source log.sh
    log "Esto es una prueba"
    

    Ejemplo 3: Comprobador de archivos

    
    
    
    
    
    existe() {
        if [ -f "$1" ]; then
            echo "El archivo existe"
        else
            echo "No existe"
        fi
    }
    
    existe "/etc/passwd"
    

    Ejercicios propuestos

    Ejercicio 1:
    Crear un script matematicas.sh con funciones:

    • sumar
    • restar

    Cada función recibe 2 números y muestra el resultado.

    Ejercicio 2:
    Crear un script saludos.sh con una función saludar que reciba un nombre y muestre:

    
    
    
    
    
    Hola, <nombre>
    

    Ejercicio 3:
    Crear un script menu.sh con una función menu que muestre:

    1. Mostrar fecha
    2. Mostrar usuario
    3. Salir

    Y llame a otras funciones según la opción.

    Ejercicio 4:
    Crear un archivo utilidades.sh con una función log que agregue un mensaje a un archivo registro.txt.
    Luego crear un script test.sh que llame a log usando source.

    Soluciones

    ✅ Ejercicio 1 — matematicas.sh

    Enunciado:
    Crear un script matematicas.sh con funciones:

    • sumar
    • restar

    Cada función recibe 2 números y muestra el resultado.

    💡 Solución:

    
    
    
    
    
    #!/bin/bash
    # Script: matematicas.sh
    # Funciones para sumar y restar dos números
    
    sumar() {
        # $1 y $2 son los parámetros de la función
        resultado=$(( $1 + $2 ))
        echo "La suma de $1 + $2 es $resultado"
    }
    
    restar() {
        resultado=$(( $1 - $2 ))
        echo "La resta de $1 - $2 es $resultado"
    }
    
    # Ejemplos de uso (se pueden sustituir por lectura de parámetros)
    sumar 10 5
    restar 10 5
    

    Si quieres que usen parámetros del script en lugar de valores fijos:

    
    
    
    
    
    #!/bin/bash
    
    sumar() {
        echo "La suma de $1 + $2 es $(( $1 + $2 ))"
    }
    
    restar() {
        echo "La resta de $1 - $2 es $(( $1 - $2 ))"
    }
    
    sumar "$1" "$2"
    restar "$1" "$2"
    

    ✅ Ejercicio 2 — saludos.sh

    Enunciado:
    Crear un script saludos.sh con una función saludar que reciba un nombre y muestre:

    Hola, <nombre>

    💡 Solución:

    
    
    
    
    
    #!/bin/bash
    # Script: saludos.sh
    # Función saludar que recibe un nombre
    
    saludar() {
        nombre="$1"
        echo "Hola, $nombre"
    }
    
    # Ejemplo 1: pasar el nombre como parámetro al script
    # saludar "$1"
    
    # Ejemplo 2: pedirlo por teclado
    read -p "Introduce tu nombre: " nom
    saludar "$nom"
    

    ✅ Ejercicio 3 — menu.sh

    Enunciado:
    Crear un script menu.sh con una función menu que muestre:

    1. Mostrar fecha
    2. Mostrar usuario
    3. Salir

    Y llame a otras funciones según la opción.

    💡 Solución:

    
    
    
    
    
    #!/bin/bash
    # Script: menu.sh
    # Menú con funciones para organizar el código
    
    mostrar_fecha() {
        echo "Fecha actual: $(date +"%Y-%m-%d %H:%M:%S")"
    }
    
    mostrar_usuario() {
        echo "Usuario actual: $USER"
    }
    
    menu() {
        echo "==== MENÚ ===="
        echo "1) Mostrar fecha"
        echo "2) Mostrar usuario"
        echo "3) Salir"
    }
    
    # Bucle para que el menú se repita hasta salir
    while true; do
        menu
        read -p "Elige una opción: " opcion
    
        case "$opcion" in
            1) mostrar_fecha ;;
            2) mostrar_usuario ;;
            3) echo "Saliendo..."; exit 0 ;;
            *) echo "Opción no válida" ;;
        esac
    
        echo # línea en blanco para separar
    done
    

    ✅ Ejercicio 4 — utilidades.sh + test.sh

    Enunciado:

    1. Crear un archivo utilidades.sh con una función log que agregue un mensaje a un archivo registro.txt.
    2. Crear un script test.sh que llame a log usando source.

    💡 utilidades.sh

    
    
    
    
    
    #!/bin/bash
    # Archivo: utilidades.sh
    # Contiene funciones reutilizables
    
    log() {
        mensaje="$1"
        fecha=$(date +"%Y-%m-%d %H:%M:%S")
        echo "[$fecha] $mensaje" >> registro.txt
    }
    

    Importante: este archivo no se ejecuta solo, se “incluye” desde otros scripts.


    💡 test.sh

    
    
    
    
    
    #!/bin/bash
    # Script: test.sh
    # Usa la función log de utilidades.sh
    
    # Cargar funciones desde utilidades.sh
    source ./utilidades.sh
    
    log "Inicio de la ejecución de test.sh"
    echo "He escrito una línea en registro.txt"
    
    # Puedes añadir más registros
    log "Otra acción importante realizada"
    

    Al ejecutar:

    
    
    
    
    
    chmod +x test.sh
    ./test.sh
    

    Contenido de registro.txt (ejemplo):

    
    
    
    
    
    [2026-01-11 19:30:01] Inicio de la ejecución de test.sh
    [2026-01-11 19:30:01] Otra acción importante realizada
    

  • 8. Entrada, Salida y Redirecciones

    En Bash, la forma en la que controlamos la entrada (lo que llega al programa) y la salida (lo que produce el programa) es crucial para automatizar tareas, guardar resultados, procesar archivos y comunicarnos entre procesos.

    Este módulo te enseña a usar redirecciones, pipes, flujos estándar y here documents, herramientas que convierten comandos simples en utilidades potentes.


    1. Los tres flujos estándar

    Todo comando tiene tres “canales”:

    FlujoNombreDescriptorSignificado
    stdinentrada estándar0Lo que el programa lee
    stdoutsalida estándar1Salida normal del programa
    stderrsalida de errores2Mensajes de error

    Ejemplo mental:

    • stdin: lo que escribes con el teclado
    • stdout: lo que ves normalmente en pantalla
    • stderr: errores que también aparecen en pantalla, pero son distintos

    2. Redirección de Salida (> y >>)

    Permite enviar la salida a un archivo en lugar de la pantalla.

    2.1 Sobrescribir (>)

    
    
    
    
    
    ls > archivos.txt
    

    Crea archivos.txt con la salida de ls.

    Si ya existía, lo sobrescribe.


    2.2 Añadir (>>)

    
    
    
    
    
    date >> registros.txt
    

    Añade la fecha al final sin borrar lo anterior.


    3. Redirección de Errores (2>)

    Para redirigir errores (stderr):

    
    
    
    
    
    comando 2> errores.log
    

    Ejemplo típico:

    
    
    
    
    
    ls /no/existe 2> errores.log
    

    errores.log contendrá:

    
    
    
    
    
    ls: no se puede acceder a '/no/existe': No existe el archivo o el directorio
    

    4. Redirección combinada (&>, 2>&1)

    A veces queremos juntar stdout + stderr.

    Hay dos métodos:

    4.1 Enviar ambos a un archivo

    
    
    
    
    
    comando &> salida.log
    

    4.2 Enviar stderr → stdout

    
    
    
    
    
    comando > salida.log 2>&1
    

    Eso significa:

    • > salida.log → stdout va a salida.log
    • 2>&1 → stderr va al mismo sitio que stdout

    5. Redirección de entrada (<)

    Permite que un comando lea datos desde un archivo.

    Ejemplo:

    
    
    
    
    
    sort < notas.txt
    

    Esto ordena las líneas de notas.txt y las muestra por pantalla.


    6. Pipes (|)

    Los pipes conectan programas entre sí: la salida de uno es la entrada del siguiente.

    Formato:

    
    
    
    
    
    comando1 | comando2
    

    Ejemplo clásico:

    
    
    
    
    
    ls /etc | grep ssh
    

    Interpretación:

    1. ls /etc lista todo
    2. grep ssh se queda con lo que contenga “ssh”

    Más ejemplos útiles:

    • Ver procesos y filtrar:
    
    
    
    
    
    ps aux | grep firefox
    
    • Contar líneas de un archivo:
    
    
    
    
    
    cat archivo.txt | wc -l
    
    • Buscar puertos en uso:
    
    
    
    
    
    netstat -tuln | grep ":80"
    

    7. Registro en archivos (logs)

    Para guardar salidas a un log sin perder errores:

    
    
    
    
    
    comando >> log.txt 2>&1
    

    Este patrón se usa muchísimo en servidores.


    8. Here Documents (<<)

    Permiten “pasar un texto” como entrada a un comando o script.

    Ejemplo:

    
    
    
    
    
    cat << EOF
    Hola mundo
    Esto es un here document
    EOF
    

    Salida:

    
    
    
    
    
    Hola mundo
    Esto es un here document
    

    Usos típicos: scripts SQL, correos, configuraciones, etc.

    Ejemplo con mysql:

    
    
    
    
    
    mysql -u root -p << EOF
    SHOW DATABASES;
    EOF
    

    9. Here Strings (<<<)

    Son como here documents pero para una sola cadena.

    Ejemplo:

    
    
    
    
    
    grep texto <<< "hola texto adiós"
    

    Resultado:

    
    
    
    
    
    hola texto adiós
    

    10. Ejemplos

    Ejemplo 1: Guardar un listado

    
    
    
    
    
    ls -l > listado.txt
    

    Ejemplo 2: Capturar errores

    
    
    
    
    
    find / -name "*.conf" 2> errores.txt
    

    Ejemplo 3: Recuento de procesos

    
    
    
    
    
    ps aux | wc -l
    

    Ejemplo 4: Ordenar archivo y guardar

    
    
    
    
    
    sort < nombres.txt > nombres_ordenados.txt
    

    Ejemplo 5: Script que registra salida y errores

    
    
    
    
    
    ./backup.sh >> backup.log 2>&1
    

    Ejercicios Propuestos

    Ejercicio 1:
    Crear un script lista.sh que liste /etc y guarde la salida en etc.txt.

    Ejercicio 2:
    Crear un script errores.sh que haga ls a un directorio que no existe y guarde el error en errores.log.

    Ejercicio 3:
    Crear un script red.sh que use un pipe para mostrar solo las líneas de ifconfig que contengan inet.

    Ejercicio 4:
    Crear un script ordenar.sh que ordene las líneas de ciudades.txt y las guarde en ordenadas.txt.

    Soluciones

    ✅ Ejercicio 1 — lista.sh

    Enunciado:
    Crear un script lista.sh que liste /etc y guarde la salida en etc.txt.

    💡 Solución:

    
    
    
    
    
    #!/bin/bash
    # Script: lista.sh
    # Lista el contenido de /etc y lo guarda en etc.txt
    
    ls /etc > etc.txt
    echo "Listado guardado en etc.txt"
    

    Tras ejecutarlo:

    
    
    
    
    
    ./lista.sh
    

    etc.txt contendrá el listado del directorio /etc.


    ✅ Ejercicio 2 — errores.sh

    Enunciado:
    Crear un script errores.sh que haga ls a un directorio que no existe y guarde el error en errores.log.

    💡 Solución:

    
    
    
    
    
    #!/bin/bash
    # Script: errores.sh
    # Genera un error de ls y lo guarda en errores.log
    
    ls /ruta/que/no/existe 2> errores.log
    echo "Error guardado en errores.log"
    

    Después de ejecutarlo:

    
    
    
    
    
    cat errores.log
    

    Salida esperada (puede variar según el idioma del sistema):

    
    
    
    
    
    ls: no se puede acceder a '/ruta/que/no/existe': No existe el archivo o el directorio
    

    ✅ Ejercicio 3 — red.sh

    Enunciado:
    Crear un script red.sh que use un pipe para mostrar solo las líneas de ifconfig que contengan inet.

    💡 Solución:

    
    
    
    
    
    #!/bin/bash
    # Script: red.sh
    # Muestra solo las líneas con inet usando pipes
    
    ifconfig | grep inet
    

    Si usas ip a (más moderno que ifconfig), sería:

    
    
    
    
    
    #!/bin/bash
    ip a | grep inet
    

    Salida típica:

    
    
    
    
    
    inet 192.168.1.100/24 brd 192.168.1.255 scope global wlan0
    inet6 fe80::abcd:1234:5678:9101/64 scope link
    

    ✅ Ejercicio 4 — ordenar.sh

    Enunciado:
    Crear un script ordenar.sh que ordene las líneas de ciudades.txt y las guarde en ordenadas.txt.

    💡 Solución:

    
    
    
    
    
    #!/bin/bash
    # Script: ordenar.sh
    # Ordena el archivo ciudades.txt y guarda el resultado
    
    sort < ciudades.txt > ordenadas.txt
    echo "Archivo ordenado guardado en ordenadas.txt"
    

    Si ciudades.txt contiene:

    
    
    
    
    
    Madrid
    Sevilla
    Barcelona
    Valencia
    

    El resultado en ordenadas.txt será:

    
    
    
    
    
    Barcelona
    Madrid
    Sevilla
    Valencia
    

    Otra opción

    Si quieres que los alumnos vean prácticas reales:

    Guardar logs sin machacar:

    
    
    
    
    
    ls /etc >> etc.log 2>&1
    

    Redirigir stdout + stderr a la vez:

    
    
    
    
    
    comando >> salida.log 2>&1
    

    Ejemplo realista: backup con logging:

    
    
    
    
    
    ./backup.sh >> backup.log 2>&1
    

    Esto se usa en cronjobs y servicios systemd.


    Resumen de herramientas usadas en los ejercicios

    HerramientaUso
    >redirigir salida, sobrescribe
    >>redirigir salida, añade
    2>redirigir errores
    ``
    <redirigir entrada desde archivo
    sortordenar líneas
    grepfiltrar texto

  • 9. Gestión de Archivos y Automatización del Sistema

    La automatización en Bash suele implicar mover, copiar, buscar, procesar y vigilar archivos, además de ejecutar tareas periódicas. En este módulo aprenderás a manipular archivos desde scripts y a automatizar acciones sobre el sistema, entrando ya en terreno de administrador serio.


    1. Comandos esenciales para gestionar archivos

    Bash no inventa nada aquí: usa comandos del sistema. Estos son tus martillos y destornilladores:

    ComandoUso
    cpCopiar archivos o directorios
    mvMover o renombrar
    rmBorrar archivos
    mkdirCrear directorios
    rmdirBorrar directorios vacíos
    touchCrear archivos vacíos o actualizar fecha
    chmodCambiar permisos
    chownCambiar propietario
    findBuscar archivos
    fileDetectar tipo de archivo

    Ejemplos rápidos:

    
    
    
    
    
    cp origen.txt destino.txt
    mv archivo.txt /tmp/
    rm viejo.txt
    mkdir respaldos
    touch notas.log
    

    2. Copias de seguridad (Backups) simples

    Un backup básico es copiar archivos o carpetas a otro lugar. Ejemplo:

    
    
    
    
    
    #!/bin/bash
    cp -r /home/usuario/documentos /home/usuario/respaldo/
    

    Añadir fecha para evitar sobreescritura:

    
    
    
    
    
    fecha=$(date +%Y-%m-%d)
    cp -r /home/usuario/documentos "/home/usuario/respaldo/doc_$fecha"
    

    Así tendrás:

    
    
    
    
    
    doc_2026-01-12/
    doc_2026-01-13/
    doc_2026-01-14/
    ...
    

    Automatización empieza aquí.


    3. Comprimir y descomprimir desde scripts

    Común en backups, logs y despliegue de software.

    HerramientaUso
    tarEmpaquetar/comprimir
    gzCompresión gzip
    zip/unzipCompresión zip

    Ejemplo:

    
    
    
    
    
    tar -czf respaldo.tar.gz /etc
    

    Explicación:

    • c → crear
    • z → comprimir con gzip
    • f → indicar nombre del archivo

    Descomprimir:

    
    
    
    
    
    tar -xzf respaldo.tar.gz
    

    4. Buscar archivos con find

    find es un radar. Busca por nombre, tamaño, fecha, permisos…

    Ejemplos útiles:

    Encontrar archivos por nombre:

    
    
    
    
    
    find /var/log -name "*.log"
    

    Por tamaño:

    
    
    
    
    
    find / -size +100M
    

    Por fecha (modificados hace menos de 1 día):

    
    
    
    
    
    find /tmp -mtime -1
    

    Por permisos inseguros:

    
    
    
    
    
    find /home -perm 777
    

    Puedes además ejecutar acciones:

    
    
    
    
    
    find /var/log -name "*.log" -exec gzip {} \;
    

    Esto comprime todos los .log.


    5. Analizar y procesar logs

    Los logs cuentan la historia del sistema. Para analizarlos usamos:

    • grep (buscar patrones)
    • cut (extraer columnas)
    • awk (procesar datos)
    • sed (modificar texto)

    Ejemplos básicos:

    Buscar errores:

    
    
    
    
    
    grep -i "error" /var/log/syslog
    

    Buscar IPs:

    
    
    
    
    
    grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" acceso.log
    

    Contar líneas:

    
    
    
    
    
    wc -l /var/log/auth.log
    

    6. Automatización con cron

    cron ejecuta tareas programadas automáticamente.

    Editar tareas del usuario:

    
    
    
    
    
    crontab -e
    

    Formato:

    
    
    
    
    
    MIN HORA DIA MES DIASEM EJECUTABLE
    

    Ejemplos:

    Ejecutar un script cada día a las 23:00:

    
    
    
    
    
    0 23 * * * /home/user/scripts/backup.sh
    

    Cada 5 minutos:

    
    
    
    
    
    */5 * * * * /home/user/scripts/monitor.sh
    

    Ver tareas activas:

    
    
    
    
    
    crontab -l
    

    7. Automatización con systemd (modo pro)

    systemd permite ejecutar servicios y temporizadores.

    Estructura:

    • .service → define una acción
    • .timer → define cuándo se ejecuta

    Ejemplo de servicio:

    /etc/systemd/system/backup.service

    
    
    
    
    
    [Unit]
    Description=Backup Diario
    
    [Service]
    ExecStart=/usr/local/bin/backup.sh
    

    Ejemplo de timer:

    /etc/systemd/system/backup.timer

    
    
    
    
    
    [Unit]
    Description=Programa el backup diario
    
    [Timer]
    OnCalendar=daily
    
    [Install]
    WantedBy=timers.target
    

    Activar timer:

    
    
    
    
    
    systemctl enable --now backup.timer
    

    Ver logs:

    
    
    
    
    
    journalctl -u backup.service
    

    Los alumnos pueden ver cómo se automatiza un servidor real.


    8. Ejemplos

    Ejemplo 1: Backup con timestamp

    
    
    
    
    
    #!/bin/bash
    fecha=$(date +%Y-%m-%d_%H-%M)
    tar -czf backup_$fecha.tar.gz /home/alumno
    

    Ejemplo 2: Buscar archivos grandes

    
    
    
    
    
    #!/bin/bash
    find / -size +500M > grandes.txt
    

    Ejemplo 3: Comprimir logs viejos

    
    
    
    
    
    #!/bin/bash
    find /var/log -name "*.log" -mtime +7 -exec gzip {} \;
    

    Ejemplo 4: Filtrar errores de syslog

    
    
    
    
    
    #!/bin/bash
    grep -i "error" /var/log/syslog > errores.log
    

    Ejercicios Propuestos

    Ejercicio 1:
    Crear un script backup.sh que comprima /etc en un archivo etc.tar.gz.

    Ejercicio 2:
    Crear un script buscar.sh que busque archivos .conf en /etc y guarde la lista en conf.txt.

    Ejercicio 3:
    Crear un script errores.sh que filtre la palabra “error” del archivo /var/log/syslog y lo guarde en errores.log.

    Ejercicio 4:
    Crear una entrada cron que ejecute backup.sh todos los días a las 23:00.

    Ejercicio 5 (opcional pro):
    Crear un .service + .timer para ejecutar buscar.sh cada hora.


    Soluciones

    ✅ Ejercicio 1 — backup.sh

    Enunciado:
    Crear un script backup.sh que comprima /etc en un archivo etc.tar.gz.

    💡 Solución básica:

    
    
    
    
    
    #!/bin/bash
    # Script: backup.sh
    # Crea un backup comprimido del directorio /etc
    
    tar -czf etc.tar.gz /etc
    echo "Backup creado: etc.tar.gz"
    

    💡 Solución un poco mejor (con fecha):

    
    
    
    
    
    #!/bin/bash
    # Script: backup.sh
    # Crea un backup comprimido del directorio /etc con fecha
    
    fecha=$(date +%Y-%m-%d_%H-%M)
    archivo="etc_$fecha.tar.gz"
    
    tar -czf "$archivo" /etc
    echo "Backup creado: $archivo"
    

    ✅ Ejercicio 2 — buscar.sh

    Enunciado:
    Crear un script buscar.sh que busque archivos .conf en /etc y guarde la lista en conf.txt.

    💡 Solución:

    
    
    
    
    
    #!/bin/bash
    # Script: buscar.sh
    # Busca archivos .conf en /etc y los guarda en conf.txt
    
    find /etc -type f -name "*.conf" > conf.txt
    echo "Listado de archivos .conf guardado en conf.txt"
    

    Si quieres que añada en lugar de sobrescribir:

    
    
    
    
    
    find /etc -type f -name "*.conf" >> conf.txt
    

    ✅ Ejercicio 3 — errores.sh

    Enunciado:
    Crear un script errores.sh que filtre la palabra “error” del archivo /var/log/syslog y lo guarde en errores.log.

    💡 Solución:

    
    
    
    
    
    #!/bin/bash
    # Script: errores.sh
    # Filtra líneas con 'error' en /var/log/syslog y las guarda en errores.log
    
    grep -i "error" /var/log/syslog > errores.log
    echo "Líneas con 'error' guardadas en errores.log"
    
    • -i → ignora mayúsculas/minúsculas (ERROR, Error, error…).

    ✅ Ejercicio 4 — Entrada de cron

    Enunciado:
    Crear una entrada cron que ejecute backup.sh todos los días a las 23:00.

    💡 Suposiciones:

    • El script está en: /home/usuario/scripts/backup.sh
    • Tiene permisos de ejecución: chmod +x backup.sh

    💡 Línea de crontab:

    Se edita con:

    
    
    
    
    
    crontab -e
    

    Y se añade:

    
    
    
    
    
    0 23 * * * /home/usuario/scripts/backup.sh >> /home/usuario/scripts/backup.log 2>&1
    

    Explicación rápida:

    • 0 23 * * * → a las 23:00 todos los días
    • >> backup.log 2>&1 → guarda salida y errores en un log (estilo “vida real”)

    ✅ Ejercicio 5 (opcional) — systemd service + timer

    Enunciado:
    Crear un .service + .timer para ejecutar buscar.sh cada hora.

    1️⃣ Script buscar.sh (por si acaso):

    
    
    
    
    
    #!/bin/bash
    # /usr/local/bin/buscar.sh
    
    find /etc -type f -name "*.conf" > /var/log/conf.txt
    

    Dar permisos:

    
    
    
    
    
    sudo chmod +x /usr/local/bin/buscar.sh
    

    2️⃣ Unidad de servicio: /etc/systemd/system/buscar.service

    
    
    
    
    
    [Unit]
    Description=Buscar archivos .conf en /etc
    
    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/buscar.sh
    

    3️⃣ Unidad de temporizador: /etc/systemd/system/buscar.timer

    
    
    
    
    
    [Unit]
    Description=Ejecutar buscar.sh cada hora
    
    [Timer]
    OnCalendar=hourly
    Persistent=true
    
    [Install]
    WantedBy=timers.target
    

    4️⃣ Activar y comprobar

    Recargar unidades:

    
    
    
    
    
    sudo systemctl daemon-reload
    

    Activar y arrancar el timer:

    
    
    
    
    
    sudo systemctl enable --now buscar.timer
    

    Ver estado:

    
    
    
    
    
    systemctl status buscar.timer
    

    Ver ejecuciones del servicio:

    
    
    
    
    
    journalctl -u buscar.service
    

  • 10. ¿QUÉ ES EL PATH?

    PATH es una variable de entorno que contiene una lista de directorios separados por dos puntos. Cuando escribes un comando como ls, el shell recorre esos directorios en orden buscando un ejecutable llamado “ls”. Si lo encuentra, lo ejecuta. Si no lo encuentra, error.

    Puedes verlo así:

    echo "$PATH"
    

    Ejemplo típico de salida:

    /usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/alumno/.local/bin

    El orden importa: el shell mira primero el primer directorio, luego el siguiente, y así.

    CREAR UN SCRIPT

    #!/bin/bash
    echo "Hola desde el sistema, $(whoami)!"
    

    Guardar como saludo.sh.

    –––––––

    ELEGIR DÓNDE VIVIRÁ
    Aquí hay dos caminos:

    A — Sólo para el usuario
    Usar ~/.local/bin (en muchas distros modernas este ya está en PATH).

    Si no existe:

    mkdir -p ~/.local/bin
    

    Luego mover el script ahí:

    mv saludo.sh ~/.local/bin/
    

    B — Para todo el sistema (requiere sudo)
    Usar /usr/local/bin:

    sudo mv saludo.sh /usr/local/bin/
    

    Esto hace que el script esté disponible para todos los usuarios

    –––––––

    PERMISOS
    El script debe tener el bit de ejecución activo. Si no:

    chmod +x ~/.local/bin/saludo.sh
    

    o si está en /usr/local/bin:

    sudo chmod +x /usr/local/bin/saludo.sh
    

    –––––––

    VERIFICAR SI EL DIRECTORIO YA ESTÁ EN EL PATH
    Para el caso ~/.local/bin, muchas distros lo incluyen. Comprobar con:

    echo "$PATH" | tr ':' '\n'
    

    Si se ve ~/.local/bin, listo.

    Si NO está, hay que añadirlo en ~/.bashrc o ~/.profile:

    echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
    source ~/.bashrc
    

    Aquí puedes introducir la distinción entre bashrc, profile y shells interactivos / no interactivos, pero sin entrar en guerra santa. A nivel pedagógico basta con que entiendan que esa línea hace persistente la ruta.

    –––––––

    EJECUTAR DESDE CUALQUIER PARTE
    Ve a cualquier carpeta:

    cd /tmp
    saludo.sh
    

    El script debería ejecutarse como cualquier comando del sistema. Si alguien intenta poner ./saludo.sh, puedes remarcar que ahora no hace falta, porque no necesita ruta explícita.

    –––––––

    OPCIONAL — QUITAR LA EXTENSIÓN
    Para que se sienta más “comando real”, renombrarlo:

    mv ~/.local/bin/saludo.sh ~/.local/bin/saludo
    

    Y ejecutarlo simplemente como:

    saludo
    

    La extensión .sh es cultural, no obligatoria, y que comandos del sistema no suelen llevar extensión.

  • 11. [Reto] Bash Incremental: Aprender Shell a Golpes de Ejemplos

    11. [Reto] Bash Incremental: Aprender Shell a Golpes de Ejemplos

    En esta práctica trabajarás con una colección de scripts en Bash orientados a tareas básicas de automatización y administración en Linux. El objetivo es que ejecutes y analices cada uno de los scripts en tu terminal para comprender su funcionamiento y el efecto que producen.

    Tareas a realizar

    1. Copia todos los scripts proporcionados en tu máquina Linux (física o virtual).
    2. Asegúrate de que cada script tenga permisos de ejecución usando: chmod +x nombre_script.sh
    3. Ejecuta cada script desde la terminal y observa el resultado.
    4. Modifica al menos 3 scripts para adaptarlos a una variante que tenga sentido. Por ejemplo:
      • Cambiar rutas
      • Cambiar comandos
      • Añadir opciones
      • Añadir colores o logs

    La línea del “shebang” (#!)

    #!/bin/bash
    #!/usr/bin/env bash

    La diferencia tiene que ver con flexibilidad vs. certeza.

    Cuando pones #!/bin/bash estás diciendo “usa Bash que está en /bin/bash”.
    Eso asume que la ruta es exactamente esa. En muchas distros Linux es verdad, en macOS a veces también, pero en otras no. Por ejemplo, en sistemas BSD, en instalaciones personalizadas, o si manejas múltiples versiones de Bash instaladas desde brew, nix, etc., /bin/bash puede no existir o no ser el Bash que quieres.

    La alternativa #!/usr/bin/env bash juega una carta distinta:
    env busca ejecutables en el PATH del usuario, encuentra dónde está bash y lo lanza.
    Es como decir: “búscame un Bash válido en la ruta del sistema y úsalo”.
    Eso lo vuelve más portátil y adaptable, sobre todo en entornos raros, macOS moderno, contenedores, virtual environments y setups educativos donde Bash no está donde uno espera.

    El resumen práctico:

    — #!/bin/bash = certero pero rígido. Si no existe esa ruta, falla.
    — #!/usr/bin/env bash = más portable y respetuoso del PATH, útil cuando no conoces el entorno.

    Ejemplo 1: “Hola, soy un script”
    Propósito: variables y echo.

    #!/usr/bin/env bash
    
    nombre="Antonio"
    echo "Hola, $nombre"
    echo "Estoy en el directorio: $(pwd)"
    

    Concepto nuevo: variables y comandos incrustados $(...).


    Ejemplo 2: “Si me pasas un nombre, lo uso”
    Propósito: argumentos $1.

    #!/usr/bin/env bash
    
    if [ -z "$1" ]; then
      echo "Uso: $0 <nombre>"
      exit 1
    fi
    
    echo "Hola, $1"
    

    Concepto nuevo: if mínimo, chequeo de argumentos y exit.


    Ejemplo 3: “Saludo a varios”
    Propósito: recorrer argumentos (for).

    #!/usr/bin/env bash
    
    if [ "$#" -eq 0 ]; then
      echo "Uso: $0 nombre1 nombre2 ..."
      exit 1
    fi
    
    for persona in "$@"; do
      echo "Hola, $persona"
    done
    

    Concepto nuevo: for y "$@" (todos los argumentos).


    Ejemplo 4: “Saludo según hora”
    Propósito: condicionales compuestos.

    #!/usr/bin/env bash
    
    hora=$(date +%H)
    
    if [ "$hora" -lt 12 ]; then
      saludo="Buenos días"
    elif [ "$hora" -lt 20 ]; then
      saludo="Buenas tardes"
    else
      saludo="Buenas noches"
    fi
    
    echo "$saludo, $(whoami)"
    

    Concepto nuevo: elif, comparaciones numéricas y uso de comandos para info del sistema.


    Pequeño ejemplo 5: “Función que loguea cosas”
    Propósito: funciones y reutilización.

    #!/usr/bin/env bash
    
    log(){
      echo "[$(date +%H:%M:%S)] $1"
    }
    
    log "Iniciando proceso"
    sleep 1
    log "Proceso terminado"
    

    Concepto nuevo: funciones y timestamps.


    Pequeño ejemplo 6: “Descargo URLs de una lista”
    Propósito: arrays, loops y llamar programas externos.

    Archivo urls.txt de ejemplo:

    https://example.org
    https://wikipedia.org
    

    Script:

    #!/usr/bin/env bash
    
    while read -r url; do
      [ -z "$url" ] && continue
      echo "Descargando $url"
      curl -s -O "$url"
    done < urls.txt
    

    Concepto nuevo: while read, redirección y pequeñas automatizaciones.


    Ejemplo 7: “Contador de líneas de código por extensión”
    Propósito: bucles, condicionales, comandos, pipes.

    #!/usr/bin/env bash
    
    if [ -z "$1" ]; then
      echo "Uso: $0 <directorio>"
      exit 1
    fi
    
    dir="$1"
    for ext in sh py js php; do
      total=$(find "$dir" -type f -name "*.$ext" -print0 | xargs -0 cat 2>/dev/null | wc -l)
      echo "$ext: $total líneas"
    done
    

    Concepto nuevo: usar herramientas externas y procesar resultados.


    Ejemplo 8: “Menú interactivo mínimo”
    Propósito: select y control básico de flujo.

    #!/usr/bin/env bash
    
    select opcion in Fecha Usuario Salir; do
      case "$opcion" in
        Fecha) date ;;
        Usuario) whoami ;;
        Salir) echo "Adiós"; break ;;
        *) echo "Opción no válida" ;;
      esac
    done
    

    Concepto nuevo: select + case.


    Pequeño ejemplo 9: “Backup comprimido con timestamp”
    Propósito: combinación de todo para algo útil.

    #!/usr/bin/env bash
    
    origen="$1"
    destino="$2"
    
    if [ -z "$origen" ] || [ -z "$destino" ]; then
      echo "Uso: $0 <directorio_origen> <directorio_destino>"
      exit 1
    fi
    
    fecha=$(date +%Y%m%d_%H%M%S)
    archivo="$destino/backup_$fecha.tar.gz"
    
    echo "Creando backup de $origen en $archivo..."
    tar -czf "$archivo" "$origen"
    echo "Backup creado."

    Ejemplo 10: Crear estructura de carpetas de proyecto

    Idea: Montar la estructura típica de un proyecto sin ir haciendo mkdir a mano.

    #!/usr/bin/env bash
    
    if [ -z "$1" ]; then
      echo "Uso: $0 <nombre_proyecto>"
      exit 1
    fi
    
    PROYECTO="$1"
    
    mkdir -p "$PROYECTO"/{src,bin,logs,tmp,docs}
    
    echo "Proyecto creado en: $PROYECTO"
    ls -R "$PROYECTO"
    

    Ejemplo 11: Buscar una palabra en todos los .log de un directorio

    Idea: Mini-grep para revisar logs del sistema o de una app.

    #!/usr/bin/env bash
    
    DIR="${1:-/var/log}"
    CADENA="$2"
    
    if [ -z "$CADENA" ]; then
      echo "Uso: $0 <directorio_logs> <cadena_a_buscar>"
      echo "Ejemplo: $0 /var/log error"
      exit 1
    fi
    
    echo "Buscando '$CADENA' en *.log de $DIR..."
    grep -Rni --include="*.log" "$CADENA" "$DIR"
    

    Ejemplo 12: Top 5 archivos más grandes de un directorio

    Idea: Visualizar qué archivos se están comiendo el disco.

    #!/usr/bin/env bash
    
    DIR="${1:-.}"
    
    echo "Top 5 archivos más grandes en: $DIR"
    du -ah "$DIR" 2>/dev/null | sort -h | tail -n 5
    

    Ejemplo 13: Aviso sencillo de uso de disco

    Idea: Script que comprueba / y avisa si pasa de cierto porcentaje.

    #!/usr/bin/env bash
    
    LIMITE=80  # porcentaje
    
    uso=$(df -h / | awk 'NR==2 {gsub("%","",$5); print $5}')
    
    echo "Uso actual de / : $uso%"
    
    if [ "$uso" -gt "$LIMITE" ]; then
      echo "⚠ Atención: uso de disco por encima de ${LIMITE}%"
    else
      echo "Todo OK, por debajo de ${LIMITE}%"
    fi
    

    Ejemplo 14: Copia rápida de syslog con timestamp

    Idea: Guardar copia de seguridad de un log del sistema en el HOME del usuario.

    #!/usr/bin/env bash
    
    ORIGEN="/var/log/syslog"
    DEST="$HOME"
    
    if [ ! -f "$ORIGEN" ]; then
      echo "No existe $ORIGEN (en algunas distros es /var/log/messages)"
      exit 1
    fi
    
    FECHA=$(date +%Y%m%d_%H%M%S)
    COPIA="$DEST/syslog_$FECHA.log"
    
    cp "$ORIGEN" "$COPIA"
    
    echo "Copia creada en: $COPIA"
    

    Ejemplo 15: Ping-monitor cutre pero efectivo

    Idea: Comprobar conectividad a un host cada pocos segundos.

    #!/usr/bin/env bash
    
    HOST="${1:-8.8.8.8}"
    
    echo "Monitoreando ping a $HOST (Ctrl+C para salir)"
    
    while true; do
      if ping -c 1 -W 1 "$HOST" >/dev/null 2>&1; then
        echo "[$(date +%H:%M:%S)] $HOST está accesible"
      else
        echo "[$(date +%H:%M:%S)] ⚠ $HOST NO responde"
      fi
      sleep 3
    done
    

    Ejemplo 16: Listar usuarios del sistema con su shell

    Idea: Leer /etc/passwd y mostrar usuario + shell. Tocado sistema pero muy didáctico.

    #!/usr/bin/env bash
    
    echo "Usuarios del sistema y su shell:"
    echo "--------------------------------"
    
    while IFS=: read -r user _ _ _ _ _ shell; do
      echo "$user -> $shell"
    done < /etc/passwd
    

    Ejemplo 17: Comprobar si un servicio está activo (systemd)

    Idea: Ver el estado de un servicio con systemctl.

    #!/usr/bin/env bash
    
    if [ -z "$1" ]; then
      echo "Uso: $0 <nombre_servicio>"
      echo "Ejemplo: $0 apache2"
      exit 1
    fi
    
    SERV="$1"
    
    estado=$(systemctl is-active "$SERV" 2>/dev/null)
    
    if [ "$estado" = "active" ]; then
      echo "✅ El servicio $SERV está ACTIVO"
    elif [ "$estado" = "inactive" ]; then
      echo "⏸ El servicio $SERV está INACTIVO"
    else
      echo "❓ El servicio $SERV no existe o no usa systemd (estado: $estado)"
    fi
    

    Ejemplo 18: Renombrar archivos añadiendo un prefijo

    Idea: Jugar con nombres de archivos y bucles. Muy útil para fotos, prácticas, etc.

    #!/usr/bin/env bash
    
    if [ "$#" -lt 2 ]; then
      echo "Uso: $0 <prefijo> <archivos...>"
      echo "Ejemplo: $0 practica1 *.txt"
      exit 1
    fi
    
    PREFIJO="$1"
    shift
    
    for fichero in "$@"; do
      if [ -f "$fichero" ]; then
        nuevo="${PREFIJO}_$fichero"
        mv "$fichero" "$nuevo"
        echo "$fichero -> $nuevo"
      else
        echo "Saltando $fichero (no es un archivo)"
      fi
    done
    

    Ejemplo 19: Menú para ver info básica del sistema

    Idea: Un menú simple que llame a varios comandos de sistema.

    #!/usr/bin/env bash
    
    mostrar_sistema() {
      echo "Sistema:"
      uname -a
    }
    
    mostrar_cpu() {
      echo "CPU:"
      lscpu | head -n 10
    }
    
    mostrar_mem() {
      echo "Memoria:"
      free -h
    }
    
    mostrar_disks() {
      echo "Discos:"
      df -h
    }
    
    PS3="Elige una opción (1-5): "
    
    select opcion in "Info sistema" "CPU" "Memoria" "Discos" "Salir"; do
      case "$REPLY" in
        1) mostrar_sistema ;;
        2) mostrar_cpu ;;
        3) mostrar_mem ;;
        4) mostrar_disks ;;
        5) echo "Adiós"; break ;;
        *) echo "Opción no válida" ;;
      esac
    done
    

  • Actividad – Completa Script de NMAP

    Actividad – Completa Script de NMAP

    Hacer un script de Bash que reúna los comandos y opciones más útiles de nmap, organizado en funciones y con un menú para que practiquen if/else, funciones, lectura de parámetros y buenas prácticas.y

    Completa el script, para ello se te propociona el menú y el conjunto de funciones utilizadas. Debes completarlo para que tenga un funcionamiento correcto

    # Menú principal
    main_menu() {
    
      while true; do
        clear
        echo "========================================"
        echo "       NMAP HELPER - MENÚ EDUCATIVO     "
        echo "========================================"
        echo "1) Ping scan (descubrir hosts vivos)"
        echo "2) TCP SYN top 100 (--top-ports 100 -sS)"
        echo "3) TCP connect scan y puertos personalizados (-sT -p)"
        echo "4) Detección de servicios y versiones (-sV -sC)"
        echo "5) Detección de SO (-O)"
        echo "6) Escaneo UDP (-sU)"
        echo "7) Escaneo agresivo (-A)"
        echo "8) NSE scripts (--script)"
        echo "9) Salida en formatos (-oN, -oX, -oG)"
        echo "10) Escaneo sin ping (-Pn)"
        echo "11) Crea tu propia opción para namp"
        echo "12) Salir"
        echo "========================================"
        read -p "Elige opción [1-12]: " opt

    En todas las opciones al final debe dar el mensaje de legalidad de uso.

    usage_note() {
      cat <<EOF
    
    IMPORTANTE (ÉTICA Y LEGAL):
    - Solo escanea equipos y redes que sean de tu propiedad o para los que tengas permiso explícito.
    - El escaneo puede ser detectado por IDS/IPS y puede tener consecuencias en redes de producción.
    - No uses estos comandos en redes públicas sin autorización.
    
    EOF
    }

  • Actividad – Script interactivo para gestión de red con Netplan

    Actividad – Script interactivo para gestión de red con Netplan


    En entornos Linux de servidor, la configuración de red es un elemento crítico. Un error puede dejar el sistema incomunicado, inaccesible por SSH o fuera de la red. En Ubuntu Server moderno, la gestión de red se realiza mediante Netplan, que utiliza archivos YAML para definir cómo se configuran las interfaces.

    En administraciones reales, cambiar entre IP dinámica (DHCP) y IP estática es una tarea habitual:

    • Laboratorios → DHCP automático
    • Servidores → IP fija y controlada
    • Máquinas virtuales → cambios frecuentes
    • Entornos de pruebas → configuraciones rápidas

    Automatizar esta tarea reduce errores humanos y permite aplicar buenas prácticas de administración.


    Se te pide desarrollar un script en Bash interactivo que permita:

    • Cambiar una interfaz de red entre DHCP y IP estática
    • Solicitar datos al usuario
    • Validar entradas básicas
    • Generar automáticamente el archivo de configuración Netplan
    • Aplicar los cambios con netplan apply
    • Crear copias de seguridad antes de modificar la configuración
    • Ofrecer un menú interactivo

    Requisitos técnicos

    El script debe:

    1. Ejecutarse únicamente como root
    2. Verificar que existe el archivo de Netplan
    3. Permitir elegir entre:
      • Configuración DHCP
      • Configuración IP estática
      • Salir
    4. En modo IP estática debe solicitar:
      • Dirección IP
      • Máscara en formato CIDR
      • Gateway
      • DNS
    5. Confirmar datos antes de aplicar cambios
    6. Crear copia de seguridad automática del archivo original
    7. Mostrar el archivo generado antes de aplicar
    8. Aplicar configuración con netplan apply
    9. Gestionar errores básicos

    Restricciones

    • El script debe estar escrito íntegramente en Bash
    • No se permite editar Netplan manualmente fuera del script
    • No se permite copiar directamente soluciones externas
    • Debe funcionar en Ubuntu Server con Netplan

    Análisis de solución

    Una vez terminado tu script puedes comparalo con el ejemplo de solución.

    Deberás:

    • Comparar tu solución con la propuesta
    • Detectar mejoras posibles
    • Identificar:
      • Validaciones adicionales
      • Buenas prácticas usadas
      • Manejo de errores
      • Estructura del código
      • Modularización en funciones

    El objetivo no es solo que funcione… sino entender cómo se escribe un script robusto de administración real.


    Ejemplo de solucion

    1. Idea general del script

    El script en Bash hará:

    1. Detectar qué archivo de Netplan estoy usando (normalmente algo como /etc/netplan/00-installer-config.yaml).
    2. Mostrar un menú en consola:
        1. Configurar IP estática
        1. Configurar IP dinámica (DHCP)
        1. Salir
    3. Según la opción:
      • Pedirá los datos necesarios (IP, máscara, gateway, DNS) si es estática.
      • Generará un archivo YAML de Netplan con esa configuración.
      • Ejecutará netplan apply para aplicar los cambios.

    IMPORTANTE:

    • Necesitaré ejecutarlo como root (sudo ./script.sh), porque va a escribir en /etc/netplan/.
    • Debo saber el nombre de la interfaz (por ejemplo enp0s3 o ens33). Lo puedo consultar mediante ip a o ifconfig

    2. Ejemplo de archivo Netplan (referencia rápida)

    Consulto mi archivo actual de Netplan mediante ls /etc/netplan primero y sudo cat /etc/netplan/50-cloud-init.yaml obteniendo las siguientes:

    DHCP (IP dinámica)

    network:
      version: 2
      ethernets:
        enp0s3:
          dhcp4: true

    «

    IP estática

    network:
      version: 2
      renderer: networkd
      ethernets:
        enp0s3:
          dhcp4: false
          addresses:
            - 192.168.1.50/24
          gateway4: 192.168.1.1
          nameservers:
            addresses:
              - 8.8.8.8
              - 1.1.1.1
    

    Nuestro script generará algo parecido según la opción que elijas.


    3. Script completo en Bash

    Mediante sudo nano script_cambiar_ip_netplan.sh,creo el script dentro de mi carpeta de scripts con ruta /home/mario/scripts. En su interior introduzco los siguientes parámetros de configuración:

    #!/usr/bin/env bash
    
    # ==========================================================
    # Script para cambiar entre IP estática y dinámica (DHCP)
    # en Ubuntu Server usando Netplan.
    #
    # Úsalo con:
    #   sudo ./cambiar_ip_netplan.sh
    # ==========================================================
    
    # ---------- CONFIGURACIÓN BÁSICA A EDITAR ----------
    # Nombre de la interfaz de red (ajústalo a tu caso: enp0s3, ens33, etc.)
    INTERFACE="enp0s3"
    
    # Archivo de Netplan a usar
    NETPLAN_FILE="/etc/netplan/50-cloud-init.yaml"
    # Si tu sistema usa otro, cámbialo aquí, por ejemplo:
    # NETPLAN_FILE="/etc/netplan/50-cloud-init.yaml"
    # ---------------------------------------------------
    
    # Comprueba que se ejecuta como root
    if [[ "$EUID" -ne 0 ]]; then
      echo "Este script debe ejecutarse como root. Usa: sudo $0"
      exit 1
    fi
    
    # Comprueba que existe el archivo de Netplan
    if [[ ! -f "$NETPLAN_FILE" ]]; then
      echo "ERROR: No se encuentra el archivo de Netplan: $NETPLAN_FILE"
      echo "Revísalo y edita el script para apuntar al archivo correcto."
      exit 1
    fi
    
    # Función para pausar
    pausa() {
      echo
      read -rp "Pulsa Enter para continuar..." _;
    }
    
    # Función para configurar DHCP
    configurar_dhcp() {
      echo "Configurando interfaz $INTERFACE con IP dinámica (DHCP)..."
    
      # Hacemos copia de seguridad
      cp "$NETPLAN_FILE" "${NETPLAN_FILE}.backup_$(date +%Y%m%d_%H%M%S)"
    
      cat > "$NETPLAN_FILE" <<EOF
    network:
      version: 2
      renderer: networkd
      ethernets:
        $INTERFACE:
          dhcp4: true
    EOF
    
      echo "Archivo Netplan generado:"
      echo "----------------------------------------"
      cat "$NETPLAN_FILE"
      echo "----------------------------------------"
    
      echo "Aplicando cambios con netplan apply..."
      netplan apply
    
      if [[ $? -eq 0 ]]; then
        echo "Configuración DHCP aplicada correctamente."
      else
        echo "Hubo un error al aplicar la configuración. Revisa el archivo YAML."
      fi
    
      pausa
    }
    
    # Función para configurar IP estática
    configurar_estatica() {
      echo "Configuración de IP estática para la interfaz: $INTERFACE"
      echo
    
      read -rp "Introduce la IP (ej: 192.168.1.50): " IP
      read -rp "Introduce la máscara en CIDR (ej: 24 para 255.255.255.0): " CIDR
      read -rp "Introduce la puerta de enlace (gateway) (ej: 192.168.1.1): " GATEWAY
      read -rp "Introduce DNS (separados por espacio, ej: 8.8.8.8 1.1.1.1): " DNS_ENTRIES
    
      # Validaciones básicas (muy simples)
      if [[ -z "$IP" || -z "$CIDR" || -z "$GATEWAY" || -z "$DNS_ENTRIES" ]]; then
        echo "Algún campo está vacío. Cancelando configuración."
        pausa
        return
      fi
    
      echo
      echo "Resumen de la configuración estática:"
      echo "  IP:           $IP/$CIDR"
      echo "  Gateway:      $GATEWAY"
      echo "  DNS:          $DNS_ENTRIES"
      echo
    
      read -rp "¿Es correcto? (s/n): " CONFIRM
      if [[ "$CONFIRM" != "s" && "$CONFIRM" != "S" ]]; then
        echo "Configuración cancelada."
        pausa
        return
      fi
    
      # Creamos una copia de seguridad del archivo actual
      cp "$NETPLAN_FILE" "${NETPLAN_FILE}.backup_$(date +%Y%m%d_%H%M%S)"
    
      # Generamos lista YAML de DNS
      DNS_YAML=""
      for dns in $DNS_ENTRIES; do
        DNS_YAML+="          - $dns"$'\n'
      done
    
      # Escribimos nueva configuración en el archivo Netplan
      cat > "$NETPLAN_FILE" <<EOF
    network:
      version: 2
      renderer: networkd
      ethernets:
        $INTERFACE:
          dhcp4: false
          addresses:
            - $IP/$CIDR
          gateway4: $GATEWAY
          nameservers:
            addresses:
    $(echo -n "$DNS_YAML")
    EOF
    
      echo "Archivo Netplan generado:"
      echo "----------------------------------------"
      cat "$NETPLAN_FILE"
      echo "----------------------------------------"
    
      echo "Aplicando cambios con netplan apply..."
      netplan apply
    
      if [[ $? -eq 0 ]]; then
        echo "Configuración estática aplicada correctamente."
      else
        echo "Hubo un error al aplicar la configuración. Revisa el archivo YAML."
      fi
    
      pausa
    }
    
    # Menú principal
    while true; do
      clear
      echo "=============================================="
      echo "   Cambiar configuración de red (Netplan)"
      echo "   Interfaz actual: $INTERFACE"
      echo "   Archivo Netplan: $NETPLAN_FILE"
      echo "=============================================="
      echo "1) Usar IP dinámica (DHCP)"
      echo "2) Usar IP estática"
      echo "3) Salir"
      echo "----------------------------------------------"
      read -rp "Elige una opción [1-3]: " OPCION
    
      case "$OPCION" in
        1)
          configurar_dhcp
          ;;
        2)
          configurar_estatica
          ;;
        3)
          echo "Saliendo..."
          exit 0
          ;;
        *)
          echo "Opción no válida."
          pausa
          ;;
      esac
    done
    

    4. Cómo usarlo paso a paso

    1. Crear el archivo del script: sudo nano script_cambiar_ip_netplan.sh Pega el contenido anterior, guarda y cierra (Ctrl+O, Enter, Ctrl+X).
    2. Dar permisos de ejecución: sudo chmod +x script_cambiar_ip_netplan.sh
    3. Editar variables según tu caso:
      • Abre el script y cambia: INTERFACE="enp0s3" NETPLAN_FILE="/etc/netplan/50-cloud-init.yaml" Pon el nombre de la interfaz que tengas y el archivo real de Netplan.
    4. Ejecutar el script como root: sudo ./script_cambiar_ip_netplan.sh
    5. Elegir opción del menú:
      • Si eliges estática, introduce:
        • IP (ej. 192.168.0.50)
        • CIDR (ej. 24)
        • Gateway (ej. 192.168.0.1)
        • DNS (ej. 8.8.8.8 1.1.1.1)

    5. Recomendaciones para no quedarte “sin red”

    • Haz pruebas estando en consola local (no por SSH), para que si te quedas sin red aún tengas acceso.
    • El script crea copias de seguridad del YAML original con nombre tipo:
      • /etc/netplan/00-installer-config.yaml.backup_20251206_153055
    • Si algo sale mal, puedes restaurar: sudo cp /etc/netplan/00-installer-config.yaml.backup_YYYYMMDD_HHMMSS /etc/netplan/00-installer-config.yaml sudo netplan applyM

    6. Evidencias de funcionamiento del Script en mi UbuntuServer.

    • A continuación adjunto distintas capturas de pantallas de mi UbuntuServer en las que puedo seleccionar las distintas opciones (yo no asignaré IP fija en este momento, ya que quiero seguir trabajando con mi server mediante DHCP)

    Arrancamos el script seleccionado la config por DHCP:

    Aquí vemos las opciones que nos ofrece, sin seleccionar ninguna:

    En esta simulamos introducir los parámetros para configurar IP estática:

    Y en esta última seleccionamos la opción de salir, y hacemos un ip a donde evidencia la asignación de IP por DHCP:

  • [Reto] – Aletheia un Sistema de Auditoría y Análisis Forense Automatizado

    [Reto] – Aletheia un Sistema de Auditoría y Análisis Forense Automatizado

    El término aletheia proviene del griego antiguo αλήθεια y significa «verdad», pero con un matiz profundo que va más allá de una simple correspondencia con la realidad; se refiere al «desocultamiento del ser» o al proceso de hacer evidente lo que estaba oculto.

    En entornos profesionales de administración de sistemas, auditoría y ciberseguridad, el análisis de evidencias no se realiza en el equipo personal del analista.
    Los datos —logs, resultados de auditoría, informes técnicos o documentación sensible— se envían a servidores dedicados, diseñados para procesar información de forma controlada, trazable y reproducible.

    El proyecto Aletheia plantea la construcción de uno de estos servidores.

    Aletheia es una máquina independiente dentro de la red cuya función no es almacenar información ni ofrecer servicios al usuario final, sino transformar evidencias técnicas en conocimiento estructurado.
    Para ello, integra un motor de inteligencia artificial local, accesible únicamente desde el propio servidor, que actúa como sistema de análisis y apoyo a la toma de decisiones.

    A diferencia de soluciones basadas en la nube, este servidor:

    • no envía información a terceros,
    • no depende de conectividad externa,
    • y permite mantener control total sobre los datos analizados.

    Durante el desarrollo del proyecto, el alumnado diseñará y desplegará un servicio capaz de:

    • recibir archivos y evidencias técnicas,
    • procesarlos de forma segura y estática,
    • analizarlos desde una perspectiva de auditoría o forense,
    • y generar informes claros, coherentes y reutilizables.

    El objetivo no es “usar IA”, sino integrarla como parte de una arquitectura real de sistemas, entendiendo su papel como herramienta de análisis, no como sustituto del criterio técnico.

    Este proyecto reproduce un escenario habitual en organizaciones reales, donde la inteligencia no reside en el usuario final, sino en la infraestructura que da soporte al análisis.

    Fase 1 — Puesta a punto del servidor

    Requisitos mínimos de la VM

    1. Crea una VM en VirtualBox:
      • Ubuntu Server 22.04/24.04 (64-bit)
      • 4 vCPU
      • 8 GB RAM
      • 40 GB disco
      • Red: Adaptador puente

    Instala Ubuntu Server y crea un usuario (no root), por ejemplo: alumno.


    1) Actualiza el sistema

    sudo apt update && sudo apt -y upgrade
    sudo reboot
    

    2) Instala herramientas base

    Instalar utilidades básicas:

    • curl
    • unzip
    • jq
    • python3
    sudo apt -y install curl unzip jq ca-certificates gnupg python3 python3-venv python3-pip
    

    3) Configura hostname (opcional pero recomendado)

    sudo hostnamectl set-hostname forense-ai
    

    Comprueba:

    hostnamectl
    

    4) Comprueba IP del servidor

    ip a
    

    Fase 2 — Instalar y probar Ollama

    5) Instala Ollama

    curl -fsSL https://ollama.com/install.sh | sh
    

    6) Comprueba que el servicio está activo

    sudo systemctl status ollama --no-pager
    

    7) Descarga un modelo ligero (recomendado para VM)

    ollama pull phi3
    

    8) Prueba que responde

    ollama run phi3 "Resume en 5 líneas qué es una auditoría de sistemas."
    

    Si esto funciona, ya tienes “motor IA” listo.

    Fase 3 — Instalar Apache + PHP (interfaz web)

    9) Instala Apache y PHP

    sudo apt -y install apache2 php libapache2-mod-php
    

    10) Habilita y arranca Apache

    sudo systemctl enable --now apache2
    

    11) Abre el firewall (solo si lo estás usando)

    Si tienes UFW activo:

    sudo ufw allow 'Apache'
    sudo ufw status
    

    12) Comprueba acceso web

    Desde tu PC (host), abre:

    • http://IP_DEL_SERVIDOR/

    Debes ver la página por defecto de Apache.


    Fase 4 — Crear la estructura del servicio “Forense-AI”

    13) Crea carpetas del proyecto

    sudo mkdir -p /var/www/forense-ai/{uploads,results,scripts,logs}
    sudo chown -R www-data:www-data /var/www/forense-ai
    sudo chmod -R 750 /var/www/forense-ai
    

    14) Crea un VirtualHost

    sudo nano /etc/apache2/sites-available/forense-ai.conf
    

    Pega esto:

    <VirtualHost *:80>
        ServerName forense-ai.local
        DocumentRoot /var/www/forense-ai
    
        <Directory /var/www/forense-ai>
            Options -Indexes
            AllowOverride All
            Require all granted
        </Directory>
    
        ErrorLog ${APACHE_LOG_DIR}/forense-ai_error.log
        CustomLog ${APACHE_LOG_DIR}/forense-ai_access.log combined
    </VirtualHost>
    

    Activa el sitio:

    sudo a2ensite forense-ai
    sudo a2dissite 000-default
    sudo systemctl reload apache2
    

    Fase 5 — Servicio web: formulario de subida + análisis

    15) Instala herramientas para extraer texto de PDF

    sudo apt -y install poppler-utils
    

    (trae pdftotext)

    16) Crea el formulario web index.php

    sudo nano /var/www/forense-ai/index.php
    

    Contenido:

    <?php
    $maxSize = 8 * 1024 * 1024; // 8 MB
    $allowed = ['txt','log','pdf'];
    
    function safe_name($name) {
      $name = preg_replace('/[^a-zA-Z0-9._-]/', '_', $name);
      return $name;
    }
    
    ?>
    <!doctype html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Forense-AI</title>
      <style>
        body { font-family: Arial, sans-serif; margin: 40px; max-width: 900px; }
        .box { padding: 16px; border: 1px solid #ccc; border-radius: 8px; }
        input, textarea, select { width: 100%; padding: 8px; margin-top: 8px; }
        button { padding: 10px 14px; margin-top: 12px; }
        .small { color: #555; font-size: 0.9em; }
      </style>
    </head>
    <body>
      <h1>Forense-AI — Analizador de evidencias</h1>
      <div class="box">
        <form action="process.php" method="post" enctype="multipart/form-data">
          <label>Evidencia (TXT/LOG/PDF, máx 8 MB)</label>
          <input type="file" name="evidence" required>
    
          <label>Tipo de análisis</label>
          <select name="mode">
            <option value="audit">Auditoría (hallazgos y riesgos)</option>
            <option value="forensic">Forense (línea temporal y eventos)</option>
            <option value="summary">Resumen ejecutivo</option>
          </select>
    
          <label>Contexto (opcional)</label>
          <textarea name="context" rows="4" placeholder="Ej: Esto es un auth.log de un servidor SSH expuesto a Internet..."></textarea>
    
          <button type="submit">Subir y analizar</button>
          <p class="small">El análisis se realiza localmente en el servidor (Ollama). No se envía nada a Internet.</p>
        </form>
      </div>
    </body>
    </html>
    

    17) Crea el script de procesamiento process.php

    sudo nano /var/www/forense-ai/process.php
    

    Contenido:

    <?php
    $uploadDir = __DIR__ . "/uploads/";
    $resultDir = __DIR__ . "/results/";
    $logDir    = __DIR__ . "/logs/";
    
    $maxSize = 8 * 1024 * 1024;
    $allowed = ['txt','log','pdf'];
    
    function safe_name($name) {
      return preg_replace('/[^a-zA-Z0-9._-]/', '_', $name);
    }
    
    function ext($name) {
      $p = pathinfo($name);
      return strtolower($p['extension'] ?? '');
    }
    
    function run_cmd($cmd) {
      $output = [];
      $ret = 0;
      exec($cmd . " 2>&1", $output, $ret);
      return [$ret, implode("\n", $output)];
    }
    
    if (!isset($_FILES['evidence'])) {
      http_response_code(400);
      exit("No file uploaded");
    }
    
    $f = $_FILES['evidence'];
    if ($f['error'] !== UPLOAD_ERR_OK) {
      http_response_code(400);
      exit("Upload error");
    }
    
    if ($f['size'] > $maxSize) {
      http_response_code(400);
      exit("File too large");
    }
    
    $original = $f['name'];
    $extension = ext($original);
    
    if (!in_array($extension, $allowed, true)) {
      http_response_code(400);
      exit("Invalid extension");
    }
    
    $mode = $_POST['mode'] ?? 'audit';
    $context = trim($_POST['context'] ?? '');
    
    $base = date("Ymd_His") . "_" . safe_name($original);
    $dest = $uploadDir . $base;
    
    if (!move_uploaded_file($f['tmp_name'], $dest)) {
      http_response_code(500);
      exit("Failed to save upload");
    }
    
    // Extraer texto
    $textFile = $dest . ".txt";
    if ($extension === 'pdf') {
      // pdftotext
      [$ret, $out] = run_cmd("pdftotext " . escapeshellarg($dest) . " " . escapeshellarg($textFile));
      if ($ret !== 0) {
        http_response_code(500);
        exit("pdftotext failed:\n" . htmlspecialchars($out));
      }
    } else {
      // Copiar tal cual
      copy($dest, $textFile);
    }
    
    // Leer texto (limitamos por tamaño para no petar memoria)
    $raw = file_get_contents($textFile);
    if ($raw === false) {
      http_response_code(500);
      exit("Cannot read extracted text");
    }
    $raw = substr($raw, 0, 50000); // 50k chars (suficiente para práctica)
    
    $promptBase = "Eres un analista de ciberseguridad. Responde en español con formato claro.\n";
    if ($mode === 'audit') {
      $task = "Analiza la evidencia como auditoría. Devuelve: 1) Resumen, 2) Hallazgos (con evidencias), 3) Riesgos, 4) Recomendaciones priorizadas.";
    } elseif ($mode === 'forensic') {
      $task = "Analiza la evidencia con enfoque forense. Devuelve: 1) Resumen, 2) Línea temporal aproximada, 3) Eventos relevantes, 4) Hipótesis, 5) Próximos pasos.";
    } else {
      $task = "Resume la evidencia para un responsable no técnico. Devuelve un resumen ejecutivo y 5 puntos clave.";
    }
    
    $contextPart = $context ? "\nContexto aportado por el usuario:\n" . $context . "\n" : "";
    
    $prompt = $promptBase . $task . $contextPart . "\nEVIDENCIA (texto):\n" . $raw . "\n";
    
    // Llamar a Ollama
    $model = "phi3";
    $cmd = "ollama run " . escapeshellarg($model) . " " . escapeshellarg($prompt);
    
    [$ret, $analysis] = run_cmd($cmd);
    if ($ret !== 0) {
      http_response_code(500);
      exit("Ollama failed:\n" . htmlspecialchars($analysis));
    }
    
    $reportName = basename($dest) . "_informe.md";
    $reportPath = $resultDir . $reportName;
    
    $report = "# Informe Forense-AI\n\n"
            . "- Archivo: **" . htmlspecialchars($original) . "**\n"
            . "- Fecha: **" . date("Y-m-d H:i:s") . "**\n"
            . "- Modo: **" . htmlspecialchars($mode) . "**\n\n"
            . "---\n\n"
            . $analysis . "\n";
    
    file_put_contents($reportPath, $report);
    
    // Log básico
    file_put_contents($logDir . "activity.log",
      date("c") . " file=" . $base . " mode=" . $mode . " ip=" . ($_SERVER['REMOTE_ADDR'] ?? 'unknown') . "\n",
      FILE_APPEND
    );
    
    header("Location: result.php?f=" . urlencode($reportName));
    

    18) Crea la página de resultados result.php

    sudo nano /var/www/forense-ai/result.php
    

    Contenido:

    <?php
    $resultDir = __DIR__ . "/results/";
    $f = $_GET['f'] ?? '';
    $f = basename($f); // evita traversal
    $path = $resultDir . $f;
    
    if (!$f || !file_exists($path)) {
      http_response_code(404);
      exit("Report not found");
    }
    
    $txt = file_get_contents($path);
    ?>
    <!doctype html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Resultado — Forense-AI</title>
      <style>
        body { font-family: Arial, sans-serif; margin: 40px; max-width: 900px; }
        pre { white-space: pre-wrap; border: 1px solid #ccc; padding: 16px; border-radius: 8px; }
        a { display:inline-block; margin-top: 12px; }
      </style>
    </head>
    <body>
      <h1>Informe generado</h1>
      <a href="download.php?f=<?php echo urlencode($f); ?>">Descargar informe</a>
      <pre><?php echo htmlspecialchars($txt); ?></pre>
      <a href="index.php">⬅ Volver</a>
    </body>
    </html>
    

    19) Crea el descargador download.php

    sudo nano /var/www/forense-ai/download.php
    

    Contenido:

    <?php
    $resultDir = __DIR__ . "/results/";
    $f = $_GET['f'] ?? '';
    $f = basename($f);
    $path = $resultDir . $f;
    
    if (!$f || !file_exists($path)) {
      http_response_code(404);
      exit("Not found");
    }
    
    header('Content-Type: text/markdown; charset=utf-8');
    header('Content-Disposition: attachment; filename="' . $f . '"');
    readfile($path);
    

    Fase 6 — Permisos y seguridad mínima del servicio

    20) Permisos finales (muy importante)

    sudo chown -R www-data:www-data /var/www/forense-ai
    sudo find /var/www/forense-ai -type d -exec chmod 750 {} \;
    sudo find /var/www/forense-ai -type f -exec chmod 640 {} \;
    sudo systemctl reload apache2
    

    21) Importante: Ollama solo local

    Comprueba que Ollama no está expuesto:

    • El servicio web llama a ollama run localmente.
    • No hace falta abrir puertos de Ollama.

    Fase 7 — Pruebas obligatorias (para entregar)

    22) Caso de prueba A (Auditoría)

    1. Sube un auth.log (o un ejemplo creado por vosotros)
    2. Modo: Auditoría
    3. Debe devolver hallazgos y recomendaciones

    23) Caso de prueba B (Forense)

    1. Sube una salida de nmap guardada como TXT
    2. Modo: Forense
    3. Debe generar hipótesis y próximos pasos

    24) Caso de prueba C (PDF)

    1. Sube un PDF técnico (manual, informe)
    2. Modo: Resumen ejecutivo
    3. Debe resumir y extraer puntos clave
  • 1 – KALI LINUX – HERRAMIENTAS Y METODOLOGÍA DE SEGURIDAD OFENSIVA

    1 – KALI LINUX – HERRAMIENTAS Y METODOLOGÍA DE SEGURIDAD OFENSIVA

    Qué sí es Kali Linux

    Kali Linux es una distribución GNU/Linux especializada en seguridad informática. Está diseñada para auditoría, pentesting, análisis forense y formación en ciberseguridad. Y aquí viene lo importante: es tan potente como malentendida.


    Kali es un laboratorio portátil. Un entorno pensado para aprender, probar y verificar la seguridad de sistemas, redes y aplicaciones.

    • Un sistema basado en Debian, estable y bien documentado.
    • Un conjunto curado de herramientas profesionales: escaneo, explotación, análisis de tráfico, ingeniería inversa, OSINT, forense, wireless…
    • Un estándar educativo y profesional en ciberseguridad (universidades, certificaciones, laboratorios, CTFs).
    • Una plataforma para pensar como atacante, con permiso y con método, para poder defender mejor.

    Kali no “hace magia”. Cada herramienta exige entender redes, sistemas, protocolos y lógica. Si no sabes qué es TCP, Kali no te lo va a enseñar a golpes de teclado.


    Qué no es Kali Linux

    Kali no es:

    • ❌ Un sistema para usar como Linux de diario (navegar, ofimática, jugar).
    • ❌ Un botón rojo para “hackear WiFi en 3 minutos”.
    • ❌ Una forma de saltarte la ley sin consecuencias.
    • ❌ Un atajo para no aprender fundamentos.
    • ❌ Un sistema “más potente” que Ubuntu para tareas normales.

    Si alguien instala Kali sin saber Linux, redes o seguridad… lo más probable es que solo consiga romper cosas propias y frustrarse.

    Kali Linux no te convierte en hacker.
    Kali Linux amplifica lo que ya sabes.

    Un experto con Ubuntu es peligroso (en el buen sentido).
    Un novato con Kali solo tiene un martillo enorme… y dedos cerca.


    Nunca es “primer Linux”. Siempre como herramienta especializada

    La historia BackTrack → Kali Linux es, en el fondo, la historia de cómo el “hacking artesanal” se convirtió en disciplina profesional. Vamos por partes, con contexto y sin mitología barata.


    BackTrack: el origen (2006–2013)

    BackTrack nació cuando la seguridad informática todavía tenía aroma a underground técnico.

    No era una distro “bonita”. Era un arsenal.

    BackTrack surge de la fusión de varios proyectos previos (WHAX, Auditor, etc.) y se construye sobre una idea clara:
    tener todas las herramientas de pentesting listas para usar, en un sistema arrancable.

    Características clave de BackTrack:

    • Basado primero en Slackware, luego en Ubuntu
    • Uso intensivo en Live CD / Live USB
    • Pensado para pentesters, investigadores y formadores
    • Muy popular en:
      • Auditorías
      • CTFs
      • Formación autodidacta
      • Escenarios “de campo”

    Pero BackTrack tenía problemas estructurales:

    • Mantenimiento complejo
    • Sistema poco homogéneo
    • Instalaciones frágiles
    • Difícil de escalar a entornos profesionales
    • Enfoque más “herramientas juntas” que “sistema bien diseñado”

    Era brillante… pero caótico.


    El punto de inflexión: profesionalización

    A medida que la ciberseguridad entra en:

    • empresas
    • universidades
    • certificaciones
    • auditorías reguladas

    BackTrack empieza a quedarse corto.

    No por las herramientas, sino por el modelo.

    Offensive Security (la empresa detrás del proyecto) se hace una pregunta clave:

    ¿Y si esto no fuera solo una distro con herramientas, sino una plataforma profesional mantenible?

    La respuesta fue romper con el pasado.


    Kali Linux: el renacimiento

    En 2013 BackTrack se retira oficialmente y nace Kali Linux.

    No es una versión nueva.
    Es un rediseño completo desde cero.

    Cambios fundamentales:

    • Base Debian pura (estabilidad, repositorios, mantenimiento)
    • Sistema modular y coherente
    • Instalación real en disco (no solo live)
    • Metodología clara: cada herramienta tiene un propósito
    • Integración con certificaciones como OSCP
    • Pensado para:
      • VMs
      • Cloud
      • ARM (Raspberry Pi)
      • Contenedores
      • Laboratorios educativos

    Kali ya no es “un CD lleno de cosas”.
    Es un sistema operativo de trabajo.


    Cambio de filosofía

    BackTrack decía:

    “Aquí tienes herramientas. Averigua tú el resto.”

    Kali dice:

    “Aquí tienes herramientas clasificadas, documentadas y mantenidas, ahora aprende el método.”

    Por eso Kali:

    • Clasifica herramientas por fases del ataque
    • Elimina herramientas obsoletas sin piedad
    • Prioriza reproducibilidad y legalidad
    • Se alinea con estándares profesionales

    Por qué BackTrack murió (y debía morir)

    BackTrack no fracasó.
    Cumplió su misión.

    Fue el puente entre:

    • el hacker autodidacta
    • y el profesional de seguridad

    Kali es lo que viene después:

    • más serio
    • más estable
    • más ético
    • más usable en docencia

    Hoy, enseñar BackTrack tendría el mismo sentido que enseñar MS-DOS para administrar servidores modernos: interesante como historia, inútil como práctica real.


    Resumen mental rápido

    BackTrack fue:

    • rebelde
    • potente
    • desordenado
    • fundacional

    Kali es:

    • profesional
    • mantenido
    • estructurado
    • educativo

    Uno abrió la puerta.
    El otro construyó la casa.

    Y esa evolución explica muy bien cómo maduró toda la ciberseguridad como disciplina.

    Filosofía de Offensive Security

    La filosofía de Offensive Security no va de “atacar por atacar”. Va de una idea incómoda, pero profundamente honesta:

    Si algo puede romperse, alguien lo romperá. Mejor que seas tú, con permiso y con método.

    Eso es offensive security. No una actitud gamberra, sino una postura intelectual frente a la seguridad.


    Pensar como atacante para defender de verdad

    La seguridad defensiva clásica tiende a decir:
    “he configurado esto bien, debería ser seguro”.

    La seguridad ofensiva responde:
    “debería no es una garantía”.

    Offensive Security parte de una premisa brutalmente simple:
    la única forma fiable de comprobar la seguridad de un sistema es intentar comprometerlo.


    El enemigo no es el hacker, es la ilusión de seguridad

    En esta filosofía, el problema no son los atacantes.
    El problema es el autoengaño técnico:

    • “Esto no lo va a atacar nadie”
    • “Nadie sabrá que está aquí”
    • “Es solo una app pequeña”
    • “Tenemos firewall, estamos cubiertos”

    Offensive security desmonta esas frases con hechos, no con opiniones.


    Herramientas ≠ filosofía

    Un matiz clave que muchos no pillan:

    • Usar Metasploit no te hace offensive security.
    • Usar Kali no te hace offensive security.
    • Saber exploits no te hace offensive security.

    La filosofía está en el proceso mental:

    1. Enumerar sin asumir nada
    2. Buscar superficies de ataque reales
    3. Encadenar fallos pequeños
    4. Pensar en impacto, no solo en “entré”
    5. Documentar cómo y por qué ocurrió

    El ataque es el medio.
    El objetivo es el conocimiento verificable.


    Metodología antes que ego

    Offensive Security es, paradójicamente, anti-ego.

    No va de:

    • “mira lo listo que soy”
    • “he entrado en X”
    • “tengo 0days”

    Va de:

    • ¿qué falló exactamente?
    • ¿cómo se reproduce?
    • ¿cómo se mitiga?
    • ¿qué aprendemos de esto?

    Por eso OffSec insiste tanto en:

    • laboratorios
    • informes
    • reproducibilidad
    • entender lo que haces, no copiar comandos

    La filosofía offensive no glorifica el delito.
    Lo separa claramente.

    Hay una línea muy clara:

    • con permiso → auditoría
    • sin permiso → delito

    La diferencia no está en la técnica. Está en el contexto y la intención.



    En el fondo, es una postura filosófica

    Offensive Security dice algo muy humano:

    La confianza ciega es peligrosa.
    El escepticismo informado es saludable.

    No destruye sistemas por placer. Los desmonta para entenderlos.

    La línea roja: el permiso

    Todo se decide con una sola pregunta:

    ¿Tienes autorización explícita para hacer lo que estás haciendo?

    • Sí → auditoría, práctica, formación.
    • No → acceso ilícito, daños informáticos, responsabilidades penales.

    No importa:

    • que el sistema sea vulnerable
    • que “solo estuvieras mirando”
    • que no hayas borrado nada
    • que fuera “por aprender”

    La intención técnica no te protege legalmente.


    En España —y de forma muy similar en la UE— entran en juego leyes como:

    • acceso no autorizado a sistemas
    • interceptación de comunicaciones
    • alteración o daño de datos
    • uso indebido de credenciales
    • suplantación

    Muchas acciones típicas de laboratorio (escaneos, fuerza bruta, sniffing) son ilegales fuera de un entorno autorizado, aunque no “rompas” nada.

    El argumento “no causé daño” no suele salvarte. El acceso ya es el daño.


    Ética profesional ≠ “todo lo que la ley permita”

    La ética va un paso más allá de la ley.

    Hay cosas que pueden ser legales… y aun así poco éticas.

    Ejemplos clásicos:

    • escanear infraestructuras sin avisar “a ver qué sale”
    • probar exploits en sistemas de terceros aunque “solo sea lectura”
    • usar datos reales en informes educativos sin anonimizar
    • humillar a un cliente demostrando fallos sin contexto

    La ética profesional exige:

    • mínimo impacto
    • necesidad justificada
    • proporcionalidad
    • responsabilidad sobre los datos

    No todo lo técnicamente posible es profesionalmente aceptable.


    El principio del entorno controlado

    Por eso en formación se insiste tanto en:

    • máquinas virtuales
    • laboratorios aislados
    • plataformas vulnerables a propósito
    • redes sin salida a Internet
    • contratos y documentos de autorización

    No es paranoia.
    Es protección legal y pedagógica.

    Un buen profesional nunca “practica” en producción ajena.


    Documentar también es una obligación ética

    Offensive security no termina cuando entras.

    Termina cuando:

    • explicas qué hiciste
    • explicas por qué fue posible
    • explicas cómo corregirlo
    • evalúas impacto real
    • propones medidas de mitigación

    Callarte un fallo crítico para “parecer más hacker” es una falta ética.
    Exagerarlo para impresionar también.


    El error más común

    Creer que:

    • la herramienta es ilegal
    • o que usarla “en local” siempre es seguro

    La realidad:

    • las herramientas no son ilegales
    • el uso sí puede serlo

    Nmap, Wireshark, Metasploit o Burp son herramientas legítimas.
    Usarlas fuera de contexto es lo que crea problemas.


    La regla de oro

    Antes de ejecutar un comando ofensivo, un profesional se pregunta:

    1. ¿Tengo permiso escrito?
    2. ¿Es el entorno adecuado?
    3. ¿Es necesario hacerlo?
    4. ¿Puedo justificarlo en un informe?
    5. ¿Estoy preparado para asumir consecuencias si algo falla?

    Si alguna respuesta incomoda… se para.

    La ciberseguridad ofensiva no va de cruzar límites,
    va de entenderlos y respetarlos.

    El conocimiento da poder.
    La ética decide si ese poder construye o destruye

    Diferencias: Kali vs Parrot vs BlackArch vs Ubuntu “hardened”

    No son rivales directos. Son respuestas distintas al mismo problema.

    Kali Linux

    Kali es ofensiva pura y explícita.
    Está pensada para atacar con método, no para convivir.

    • Enfoque: pentesting, auditoría, formación
    • Filosofía: offensive security
    • Herramientas: muchas, seleccionadas, clasificadas por fase
    • Público: estudiantes, pentesters, auditores
    • Uso típico: laboratorio, VM, live, cloud

    Kali no intenta ser discreta. Es un maletín abierto lleno de ganzúas… con permiso.


    Parrot Security OS

    Parrot es más híbrida y más política en el buen sentido.

    • Enfoque: seguridad + privacidad + desarrollo
    • Filosofía: anonimato, hardening, uso diario posible
    • Herramientas: menos que Kali, pero bien integradas
    • Público: seguridad, pero también usuarios avanzados
    • Uso típico: sistema principal o VM

    Parrot intenta convivir con el día a día. Kali no.


    BlackArch

    BlackArch es radical.

    • Enfoque: ofensivo extremo
    • Filosofía: “si existe una herramienta, la incluimos”
    • Herramientas: miles
    • Público: usuarios muy avanzados
    • Uso típico: entornos muy específicos

    BlackArch no te enseña. Te exige saber.
    Es potencia sin pedagogía.


    Ubuntu hardened

    Aquí cambia completamente el eje.

    • Enfoque: defensa
    • Filosofía: reducir superficie de ataque
    • Herramientas ofensivas: ninguna por defecto
    • Público: administradores, producción
    • Uso típico: servidores, entornos reales

    No sirve para atacar. Sirve para no ser atacado.


    Cada uno juega a otra cosa, aunque compartan campo.


    Modos de uso de Kali Linux

    Aquí está la parte crítica para docencia y práctica profesional.


    1. Máquina virtual (VM)

    Este es el modo rey en formación.

    Qué es:

    • Kali ejecutándose dentro de VirtualBox, VMware, Proxmox, etc.

    Ventajas:

    • Aislamiento total
    • Fácil de romper y rehacer
    • Snapshots
    • Ideal para laboratorios

    Inconvenientes:

    • Rendimiento
    • Algunas limitaciones hardware (WiFi, GPU)

    Uso típico:

    • clases
    • prácticas
    • CTFs
    • pruebas controladas

    Si alguien empieza con Kali, esto es lo correcto.


    2. Live USB

    Kali “arranca y desaparece”.

    Qué es:

    • Kali ejecutándose desde USB sin tocar el disco

    Ventajas:

    • No deja rastro (en modo live)
    • Ideal para auditorías puntuales
    • Muy portable

    Inconvenientes:

    • Cambios no persistentes (salvo configuración especial)
    • Más lento
    • No pensado para trabajar a largo plazo

    Uso típico:

    • auditorías de campo
    • demostraciones
    • emergencias

    Este modo es heredero directo del espíritu BackTrack.


    3. Instalación bare metal

    Aquí ya hablamos de uso serio y consciente.

    Qué es:

    • Kali instalado como sistema principal en el equipo

    Ventajas:

    • Rendimiento completo
    • Acceso total al hardware
    • Entorno de trabajo permanente

    Inconvenientes:

    • No es cómodo para uso diario
    • Riesgo si no sabes lo que haces
    • No tiene sentido para la mayoría

    Uso típico:

    • profesionales dedicados
    • equipos exclusivos de auditoría

    Instalar Kali como “mi Linux normal” suele ser una mala decisión… hasta que deja de serlo por razones muy concretas.


    4. Kali en la nube / contenedor (conceptual)

    Aquí entramos en la Kali moderna.

    Kali en la nube

    • Kali desplegado en VPS, cloud o laboratorio remoto
    • Ideal para OSINT, análisis, escaneos desde IP externa
    • Muy usado en auditorías reales

    No dependes de tu portátil.
    Dependes de infraestructura reproducible.

    Kali en contenedores

    • Herramientas concretas en Docker
    • No todo el sistema, solo lo necesario
    • Automatización, CI/CD, pruebas repetibles

    Esto refleja una idea clave:

    Kali ya no es solo un sistema, es un ecosistema de herramientas.


  • 2 – KALI LINUX: Metodología de un ataque

    2 – KALI LINUX: Metodología de un ataque

    Ciclo clásico de un test de penetración

    Este ciclo no es una receta mágica ni siempre lineal. Es un modelo mental de trabajo. En la práctica se avanza, se retrocede y se repite. Pensar que es lineal es el primer error del principiante.


    1. Reconocimiento

    Aquí no se ataca. Aquí se observa.

    El objetivo es responder a una pregunta básica pero poderosa:

    ¿Qué existe ahí fuera que pueda ser relevante?

    Se recopila información del objetivo sin interactuar directamente o con la mínima huella posible.

    Incluye:

    • Dominios, subdominios, IPs
    • Rangos de red
    • Tecnologías usadas
    • Información pública de la organización
    • Usuarios, correos, patrones

    Es como mirar un edificio desde la calle: cuántas puertas tiene, cuántas ventanas, si hay cámaras, si alguien entra y sale.

    Error típico del alumno: querer usar exploits aquí.
    Lección clave: sin información, cualquier ataque es ruido.


    2. Enumeración

    Ahora sí se empieza a tocar el sistema… con cuidado.

    La enumeración responde a otra pregunta crítica:

    ¿Qué servicios concretos están activos y cómo se comportan?

    Aquí se baja al detalle:

    • Puertos abiertos
    • Servicios y versiones
    • Rutas web
    • Usuarios válidos
    • Recursos compartidos
    • Respuestas del sistema

    La diferencia con el reconocimiento es la profundidad.
    Si el reconocimiento es el mapa, la enumeración es poner nombres a las calles.

    Error típico: escanear sin entender los resultados.
    Lección clave: un puerto abierto no es una vulnerabilidad; es una pista.


    3. Explotación

    Aquí ocurre lo que todos esperan… pero solo debería llegar cuando hay base suficiente.

    La pregunta ahora es directa:

    ¿Puedo aprovechar esto para obtener acceso?

    Explotar no significa “romperlo todo”, significa:

    • Ejecutar código
    • Saltarse autenticaciones
    • Obtener una shell
    • Acceder a información sensible

    Puede ser:

    • Automático (frameworks)
    • Manual (mucho más interesante didácticamente)

    Error típico: lanzar exploits al azar.
    Lección clave: explotar es confirmar una hipótesis, no probar suerte.


    4. Post-explotación

    Este es el bloque que diferencia a un curioso de un profesional.

    Una vez dentro, la pregunta cambia:

    ¿Hasta dónde puedo llegar y qué impacto real tiene esto?

    Aquí se evalúa:

    • Qué permisos se tienen
    • Si se puede escalar privilegios
    • Qué otros sistemas son accesibles
    • Qué datos pueden extraerse
    • Qué persistencia sería posible

    No se trata de “hacer daño”, sino de medir consecuencias.

    Error típico: quedarse satisfecho con “ya entré”.
    Lección clave: una intrusión sin impacto medido no sirve para nada.


    5. Reporte

    El paso más infravalorado… y el más importante.

    El objetivo no es impresionar, es comunicar.

    Un buen reporte responde a:

    • Qué se hizo
    • Cómo se hizo
    • Qué se consiguió
    • Qué riesgo real existe
    • Cómo se puede mitigar

    Aquí el lenguaje cambia:

    • Técnico para técnicos
    • Claro y ejecutivo para responsables

    Error típico: pensar que esto es “relleno”.
    Lección clave: si no se puede explicar, no existe.


    ¿Qué es MITRE ATT&CK?

    La caja MITRE ATT&CK es, básicamente, el mapa oficial del “cómo” atacan los adversarios. No es una herramienta, no es un exploit, y no sirve para “hackear” directamente. Sirve para pensar con rigor.

    Si el ciclo clásico te dice en qué fase estás, MITRE ATT&CK te dice qué tácticas y técnicas existen en cada fase. Ciencia del mal comportamiento, documentada con obsesión académica.


    MITRE ATT&CK (Adversarial Tactics, Techniques and Common Knowledge) es una base de conocimiento que recoge:

    • Técnicas reales usadas por atacantes
    • Observadas en incidentes reales
    • Clasificadas y normalizadas
    • Mantenida por MITRE (organización sin ánimo de lucro)

    No habla de herramientas concretas. Habla de comportamientos.


    La “caja” ATT&CK

    Se suele representar como una matriz (una caja grande):

    • Columnas → Tácticas (el por qué)
    • Filas → Técnicas (el cómo)

    Cada celda responde a:

    Para conseguir este objetivo, ¿qué formas conocidas existen?


    Tácticas principales (Enterprise)

    Las tácticas son intenciones del atacante. No son pasos estrictos, pero sí un flujo lógico.

    • Reconnaissance – Recopilar información
    • Resource Development – Preparar infraestructura
    • Initial Access – Primer acceso al sistema
    • Execution – Ejecutar código
    • Persistence – Mantener acceso
    • Privilege Escalation – Subir permisos
    • Defense Evasion – Evitar detección
    • Credential Access – Obtener credenciales
    • Discovery – Conocer el entorno interno
    • Lateral Movement – Moverse por la red
    • Collection – Recopilar datos
    • Command and Control – Comunicación con el atacante
    • Exfiltration – Sacar información
    • Impact – Daño o efecto final

    Observa algo interesante: no es lineal. Es un grafo mental.


    Técnicas y sub-técnicas

    Cada táctica contiene técnicas numeradas (por ejemplo T1059).

    Ejemplo:

    • Táctica: Execution
    • Técnica: Command and Scripting Interpreter
    • Sub-técnica: PowerShell, Bash, Python

    Esto permite:

    • Hablar con precisión
    • Comparar ataques distintos
    • Decir “qué pasó” sin folklore

    Relación con el ciclo clásico

    Aquí ocurre la magia didáctica.

    Ciclo clásicoMITRE ATT&CK
    ReconocimientoReconnaissance
    EnumeraciónDiscovery
    ExplotaciónInitial Access + Execution
    Post-explotaciónPersistence, Privilege Escalation, Lateral Movement, Collection
    ReporteDocumentar técnicas ATT&CK

    El ciclo clásico es pedagógico.
    MITRE ATT&CK es analítico y profesional.


    Evita frases como:

    • “Me hackearon con un virus”
    • “Usaron Metasploit”
    • “Fue un ataque raro”

    Y las sustituye por:

    • “T1059 – ejecución mediante intérprete de comandos”
    • “T1003 – dumping de credenciales”
    • “T1021 – movimiento lateral vía SMB”

    Eso es lenguaje común entre Red Team, Blue Team y SOC.


    Red Team vs Blue Team

    MITRE ATT&CK es el campo de batalla compartido:

    • Red Team: qué técnicas usar
    • Blue Team: qué técnicas detectar
    • Purple Team: alinear ambos mundos

    Kali vive cómodo en el Red Team, pero ATT&CK es neutral.

    KALI LINUX: CLASIFICACIÓN DE HERRAMIENTAS

    A partir de aquí, Kali se entiende por categorías funcionales, no por listas caóticas.


    Reconocimiento pasivo (OSINT)

    Sin tocar el objetivo directamente.

    Herramientas clave:

    • whois
    • theHarvester
    • Maltego
    • Amass (modo pasivo)
    • dnsenum
    • subfinder
    • Google dorks (conceptual)

    Objetivo: aprender a sacar información sin levantar sospechas.


    Reconocimiento activo y escaneo

    Aquí ya “tocamos” el sistema.

    Herramientas clave:

    • nmap (bloque enorme, merece varias clases)
      • Descubrimiento
      • Puertos
      • Servicios
      • Scripts NSE
    • masscan
    • netdiscover
    • arp-scan

    Objetivo: mapear superficie de ataque.


    Enumeración de servicios

    Saber qué versión, qué fallo y qué puerta está abierta.

    Por servicios:

    • HTTP/HTTPS:
      • whatweb
      • nikto
      • dirb, dirbuster, gobuster
    • SMB:
      • enum4linux
      • smbclient
    • FTP:
      • ftp, nmap ftp-*
    • DNS:
      • dig
      • dnsrecon

    Objetivo: transformar “puertos abiertos” en vulnerabilidades reales.


    Análisis de vulnerabilidades

    Antes de explotar, se evalúa.

    Herramientas:

    • nikto (web)
    • searchsploit
    • Introducción a CVE, CVSS
    • Relación versión → exploit

    Objetivo: no disparar a ciegas.


    Explotación

    Aquí empieza lo serio

    Herramientas:

    • Metasploit Framework
      • exploits
      • payloads
      • sesiones
    • Explotación manual (conceptual)
    • Uso responsable y controlado

    Objetivo: entender cómo se compromete un sistema, no solo ejecutar exploits.


    Post-explotación

    Una vez dentro… ¿ahora qué?

    • Enumeración interna
    • Escalada de privilegios
    • Persistencia (conceptual)
    • Exfiltración (conceptual)
    • Limpieza de rastros (ética y teoría)

    Herramientas:

    • Módulos de Metasploit
    • Scripts básicos

    Objetivo: comprender el impacto real de una intrusión.


    Ataques a credenciales

    Uno de los bloques favoritos de los alumnos.

    Herramientas:

    • hydra
    • john
    • hashcat
    • Diccionarios
    • Tipos de hash

    Objetivo: demostrar por qué las contraseñas débiles son el eslabón roto.


    Redes inalámbricas

    Siempre motiva mucho.

    Herramientas:

    • aircrack-ng
    • airodump-ng
    • aireplay-ng
    • Conceptos:
      • WPA/WPA2/WPA3
      • Handshake
      • Diccionarios

    Objetivo: entender por qué el WiFi mal configurado es un desastre.


    Sniffing y análisis de tráfico

    Ver lo invisible.

    Herramientas:

    • tcpdump
    • wireshark
    • Filtros básicos
    • Captura de credenciales en claro

    Objetivo: aprender a leer la red como si fuera texto.


    13. Ingeniería social (teórica)

    Con cuidado y ética.

    • Conceptos
    • Casos reales
    • Phishing (solo teórico o laboratorio controlado)

    Objetivo: entender que el humano es el vector más vulnerable.


    Automatización y scripting en Kali

    Pensar como profesional.

    • Bash básico para pentesting
    • Python para automatizar tareas
    • Uso de herramientas encadenadas

    Objetivo: dejar de ser “usuario de herramientas” y pasar a operador.


    Documentación y reporting

    El ataque no vale nada sin informe.

    • Evidencias
    • Capturas
    • Explicación técnica
    • Recomendaciones de mitigación
    • Informe ejecutivo vs técnico

    Objetivo: cerrar el ciclo profesional.