Categoría: Servicios y servidores

  • Proyecto Loot Figures — Parte 1: implantación en XAMPP y Ubuntu Server

    Proyecto Loot Figures — Parte 1: implantación en XAMPP y Ubuntu Server

    1. Presentación del proyecto

    En esta actividad vamos a implantar Loot Figures, una tienda web de figuras de plástico inspiradas en personajes de videojuegos.

    La aplicación ya está desarrollada. Nuestro trabajo consistirá en examinar sus archivos, preparar los entornos necesarios, configurar la base de datos y conseguir que funcione en dos instalaciones diferentes:

    1. En nuestro ordenador, utilizando XAMPP.
    2. En la máquina virtual Ubuntu Server que hemos preparado en clase.

    Además de conseguir que la tienda se abra en el navegador, tendremos que comprobar sus funciones y documentar el procedimiento.

    Implantar una aplicación no consiste únicamente en copiar archivos. También debemos identificar sus requisitos, configurar los servicios, preparar la base de datos, ajustar permisos y comprobar que todo funciona correctamente.


    2. Objetivos de aprendizaje

    Al terminar esta primera parte, deberás ser capaz de:

    • Identificar los archivos y las carpetas de una aplicación PHP.
    • Abrir un proyecto completo en VS Code o PhpStorm.
    • Reconocer la función de los modelos, los DAO y los archivos que reciben datos.
    • Diferenciar el código PHP del código que ejecuta el navegador.
    • Preparar un entorno con Apache, PHP y MySQL o MariaDB.
    • Crear una base de datos e importar su estructura.
    • Configurar la conexión entre PHP y la base de datos.
    • Ejecutar un script de carga de datos.
    • Configurar Apache para servir la carpeta pública del proyecto.
    • Implantar la misma aplicación en Windows y Ubuntu Server.
    • Comprobar su funcionamiento y resolver incidencias.
    • Elaborar documentación técnica que permita repetir la instalación.

    3. Material necesario

    Para realizar la actividad necesitarás:

    • El archivo del proyecto: loot-figures-php-clase.zip.
    • Un ordenador con XAMPP.
    • VS Code o PhpStorm.
    • Un navegador web.
    • La máquina virtual Ubuntu Server utilizada en clase.
    • Un usuario de Ubuntu con permisos para ejecutar sudo.
    • Conexión entre tu ordenador y la máquina virtual.

    La aplicación utiliza PHP 8.x, una base de datos MySQL o MariaDB y las extensiones PHP necesarias para trabajar con mysqli, sesiones y archivos.

    En esta primera parte no utilizaremos Docker. Vamos a preparar los servicios directamente para comprender qué necesita la aplicación.

    4. Resultado que debes conseguir

    Al finalizar, tendrás dos instalaciones independientes:

    EntornoAplicaciónBase de datosAcceso
    Ordenador con XAMPPCopia local del proyectoBase de datos de XAMPPhttp://localhost:8080
    Máquina virtual Ubuntu ServerCopia del proyecto en el servidorBase de datos de Ubuntuhttp://IP_DEL_SERVIDOR:8080

    Cada instalación tendrá su propia base de datos.

    Los cambios realizados en una instalación no aparecerán automáticamente en la otra.

    Utilizaremos el puerto 8080 para la tienda. De esta forma, podemos conservar las páginas o servicios que ya estén utilizando el puerto 80.


    Bloque A. Examinar el proyecto antes de instalarlo

    5. Descargar y descomprimir los archivos

    Descarga el ZIP proporcionado por el profesor y descomprímelo.

    La carpeta principal del proyecto se llama:

    loot-figures-clase

    Comprueba que dentro aparecen, entre otras, estas carpetas:

    app
    config
    database
    docs
    public
    scripts

    No comiences modificando archivos. Primero vamos a identificar qué contiene el proyecto.

    6. Abrir el proyecto en VS Code o PhpStorm

    Opción A: VS Code

    1. Abre VS Code.
    2. Selecciona Archivo → Abrir carpeta.
    3. Elige la carpeta principal loot-figures-clase.
    4. Comprueba que aparecen todas las carpetas del proyecto en el explorador lateral.
    5. Abre el archivo README.md.

    Opción B: PhpStorm

    1. Abre PhpStorm.
    2. Selecciona Open / Abrir.
    3. Elige la carpeta principal loot-figures-clase.
    4. Espera a que termine de analizar el proyecto.
    5. Abre el archivo README.md.

    Debes abrir la carpeta completa, no únicamente un archivo PHP ni solo la carpeta public.

    El editor nos permite consultar y modificar el código. Para ejecutar la aplicación necesitaremos un servidor PHP.

    7. Reconocer las carpetas del proyecto

    Examina la estructura y completa una tabla como esta en tu documentación:

    Carpeta o archivo¿Para qué sirve?
    app/modelosClases que representan clientes, productos, pedidos y mensajes
    app/daoClases que realizan las consultas a la base de datos
    app/Conexion.phpCódigo que abre la conexión con MySQL mediante mysqli
    configConfiguración de la aplicación
    database/schema.sqlInstrucciones SQL para crear las tablas
    publicArchivos que debe servir Apache al navegador
    public/apiArchivos PHP que reciben peticiones y devuelven datos
    public/partialsPartes comunes: cabecera, navegación y pie
    public/assetsJavaScript, CSS, logo e imágenes
    public/uploadsImágenes subidas desde la administración
    scripts/seed.phpScript que introduce los datos de ejemplo
    docsDocumentación del proyecto

    Preguntas que debes responder

    1. ¿Qué diferencia hay entre app/modelos y app/dao?
    2. ¿Qué archivo contiene la configuración de la base de datos?
    3. ¿Qué carpeta debe publicar Apache?
    4. ¿Por qué la configuración y los scripts de instalación no deben quedar dentro del directorio público?
    5. ¿Qué diferencia hay entre un archivo PHP y un archivo JavaScript?
    6. ¿Qué función tienen header.php, nav.php y footer.php?

    8. Seguir una operación sencilla

    Abre estos archivos:

    public/api/contacto.php
    app/modelos/Mensaje.php
    app/dao/MensajeDAO.php

    Localiza el recorrido de los datos:

    1. Se reciben los datos del formulario.
    2. Se validan.
    3. Se crea un objeto Mensaje.
    4. Se crea el DAO.
    5. El DAO inserta el mensaje en la base de datos.
    6. PHP devuelve una respuesta JSON.

    Identifica estas instrucciones:

    $mensaje = new Mensaje(0, $nombre, $email, $texto);
    
    $dao = new MensajeDAO($conexion);
    
    $dao->insertar($mensaje);

    No es necesario comprender todavía todo el proyecto. En esta fase debes poder explicar qué responsabilidad tiene cada archivo.

    Evidencia: incluye una captura del proyecto abierto en el editor y una explicación breve de este recorrido.


    Bloque B. Implantación local con XAMPP

    9. Preparar XAMPP

    Si todavía no tienes XAMPP, descárgalo desde su web oficial:

    Descargar XAMPP

    Las instrucciones siguientes utilizan una instalación de Windows situada en:

    C:\xampp

    Si tu instalación está en otra ubicación, adapta las rutas.

    Abre el panel de control de XAMPP e inicia:

    • Apache.
    • MySQL.

    Aunque el panel muestre el nombre MySQL, XAMPP puede incluir MariaDB como motor de base de datos.

    Comprueba estas direcciones:

    http://localhost
    http://localhost/phpmyadmin

    phpMyAdmin nos permitirá gestionar la base de datos de esta instalación. En la configuración básica de XAMPP se accede a él desde el propio equipo. apachefriends.org

    Evidencia: captura del panel con Apache y MySQL iniciados.

    10. Colocar el proyecto

    Crea esta carpeta:

    C:\proyectos

    Coloca dentro el proyecto descomprimido:

    C:\proyectos\loot-figures-clase

    Comprueba que existe:

    C:\proyectos\loot-figures-clase\public\index.php

    La carpeta del proyecto estará fuera de htdocs. Configuraremos Apache para que publique únicamente su carpeta public.

    Después, abre esta ubicación definitiva en VS Code o PhpStorm.

    11. Configurar Apache para la tienda

    11.1. Revisar la carga de VirtualHosts

    Abre este archivo:

    C:\xampp\apache\conf\httpd.conf

    Busca la línea:

    Include conf/extra/httpd-vhosts.conf

    Si aparece comentada con #, elimina ese carácter.

    Guarda el archivo.

    11.2. Añadir la configuración

    Abre:

    C:\xampp\apache\conf\extra\httpd-vhosts.conf

    Añade al final:

    Listen 8080
    
    <VirtualHost *:8080>
        ServerName localhost
    
        DocumentRoot "C:/proyectos/loot-figures-clase/public"
    
        <Directory "C:/proyectos/loot-figures-clase/public">
            Options -Indexes
            AllowOverride All
            Require local
        </Directory>
    </VirtualHost>

    Importante: si ya existe una instrucción Listen 8080 en la configuración de Apache, no la añadas otra vez.

    En la configuración de Apache hemos escrito las rutas con /.

    ¿Qué significa esta configuración?

    InstrucciónFunción
    Listen 8080Apache escucha también en el puerto 8080
    VirtualHost *:8080Define el sitio que responderá en ese puerto
    DocumentRootIndica la carpeta pública de la aplicación
    AllowOverride AllPermite aplicar las instrucciones de .htaccess
    Require localPermite el acceso desde el propio ordenador

    Detén y vuelve a iniciar Apache desde XAMPP.

    Si no arranca, revisa los mensajes y registros del servicio antes de continuar.

    12. Crear la base de datos

    Abre:

    http://localhost/phpmyadmin

    Selecciona la pestaña SQL y ejecuta:

    CREATE DATABASE loot_figures
    CHARACTER SET utf8mb4
    COLLATE utf8mb4_unicode_ci;
    
    CREATE USER 'loot_app'@'localhost'
    IDENTIFIED BY 'CambiaEstaClaveBD!';
    
    GRANT SELECT, INSERT, UPDATE, DELETE
    ON loot_figures.*
    TO 'loot_app'@'localhost';

    Hemos creado:

    • La base de datos loot_figures.
    • El usuario loot_app.
    • Los permisos necesarios para las operaciones de la tienda.

    La aplicación utilizará este usuario, no la cuenta root.

    Si la base o el usuario ya existen por un intento anterior, revisa lo que has creado antes de repetir las instrucciones. No elimines bases de datos para resolver un error sin comprobar su contenido.

    13. Importar las tablas

    En phpMyAdmin:

    1. Selecciona la base de datos loot_figures.
    2. Abre la pestaña Importar.
    3. Selecciona el archivo:
    C:\proyectos\loot-figures-clase\database\schema.sql
    1. Ejecuta la importación.
    2. Comprueba que aparecen estas tablas:
    users
    products
    orders
    order_items
    messages
    login_attempts

    La importación debe realizarse con la cuenta de administración de la base de datos, porque crea las tablas.

    No vuelvas a importar el esquema sobre una instalación que ya tiene sus tablas.

    Evidencia: captura de la base de datos con las tablas creadas.

    14. Crear el archivo de configuración

    Dentro de config, copia:

    config.example.php

    y llama a la copia:

    config.php

    Puedes hacerlo desde el editor o el explorador de archivos.

    Edita config.php y utiliza estos valores:

    <?php
    
    return [
        'db' => [
            'host' => 'localhost',
            'port' => 3306,
            'name' => 'loot_figures',
            'user' => 'loot_app',
            'password' => 'CambiaEstaClaveBD!'
        ],
    
        'secure_cookie' => false,
        'debug' => false
    ];

    Si tu servicio de base de datos utiliza otro puerto, debes cambiar el valor port.

    En esta práctica trabajamos con HTTP local, por eso secure_cookie permanece en false.

    No copies config.docker.php: esa configuración corresponde a otro entorno.

    15. Comprobar PHP y cargar los datos de ejemplo

    Abre una terminal de PowerShell.

    Comprueba el PHP de XAMPP:

    & "C:\xampp\php\php.exe" -v

    Después, sitúate en el proyecto:

    Set-Location "C:\proyectos\loot-figures-clase"

    Ejecuta:

    & "C:\xampp\php\php.exe" scripts/seed.php

    El script creará los usuarios y productos de demostración.

    Si aparece un error, comprueba:

    • Que MySQL está iniciado.
    • Que existe config/config.php.
    • Que la contraseña y el puerto son correctos.
    • Que has importado las tablas.

    El archivo seed.php se ejecuta desde la terminal. No tienes que abrirlo mediante una URL.

    16. Abrir la tienda en localhost

    Abre:

    http://localhost:8080

    La tienda debería mostrar la home, el logo, las imágenes y los productos.

    No abras index.php haciendo doble clic. Tampoco utilices Live Server para ejecutar esta aplicación PHP. Debes acceder mediante Apache.

    Cuentas de demostración

    RolCorreoContraseña
    Administradoradmin@loot.localAdminDemo!2026
    Clientecliente@loot.localClienteDemo!2026

    Estas cuentas utilizan direcciones ficticias. No necesitas disponer de esos correos.

    17. Comprobar el funcionamiento local

    Realiza estas pruebas:

    Zona pública

    1. Abre la home.
    2. Accede al catálogo.
    3. Busca una figura.
    4. Filtra por rareza.
    5. Cambia el orden de los productos.
    6. Abre el detalle de una figura.

    Registro y cuenta

    1. Crea una cuenta con datos ficticios.
    2. Cierra sesión.
    3. Vuelve a entrar.
    4. Accede a tu perfil.
    5. Cambia el teléfono y comprueba que se guarda.

    Carrito y compra

    1. Entra como cliente.
    2. Añade una figura al carrito.
    3. Cambia la cantidad.
    4. Añade otra figura.
    5. Elimina una línea.
    6. Introduce una dirección ficticia.
    7. Confirma el pedido.
    8. Comprueba que aparece en el historial.

    La compra es una simulación y no realiza ningún cobro.

    Administración

    1. Entra como administrador.
    2. Accede al listado de productos.
    3. Modifica el nombre, precio o stock de una figura.
    4. Comprueba el resultado en el catálogo.
    5. Crea un usuario de prueba.
    6. Modifica sus datos.
    7. Cambia su contraseña.
    8. Comprueba que puede iniciar sesión con la nueva contraseña.
    9. Sube una fotografía a un producto.

    Contacto

    1. Envía un mensaje desde la página de contacto.
    2. Entra como administrador.
    3. Comprueba que el mensaje aparece en el panel.

    El mensaje se guarda en la base de datos. No se envía un correo electrónico.

    18. Observar una petición JSON

    Abre las herramientas de desarrollo del navegador y selecciona la pestaña Red / Network.

    Recarga el catálogo y localiza la petición a:

    api/listar_productos.php

    Examina su respuesta.

    Responde:

    1. ¿Qué información contiene el JSON?
    2. ¿Qué campos identifican el nombre y el precio del producto?
    3. ¿El navegador recibe el código fuente PHP?
    4. ¿Qué archivo JavaScript utiliza esos datos para construir las tarjetas?

    Después, visita:

    http://localhost:8080/ejemplo_clase.php

    Este formulario permite observar un envío clásico por POST.

    Utiliza otra cuenta ficticia para probarlo. Después del envío verás la respuesta JSON directamente en el navegador.

    Explica la diferencia entre este formulario y el registro habitual de la tienda.


    Bloque C. Implantación en Ubuntu Server

    19. Preparar la máquina virtual

    Utiliza la máquina virtual creada en clase.

    Antes de comenzar:

    1. Comprueba que puedes iniciar sesión.
    2. Identifica tu usuario.
    3. Comprueba que puedes ejecutar sudo.
    4. Anota la versión de Ubuntu.
    5. Comprueba la dirección IP.
    6. Realiza una instantánea si el programa de virtualización lo permite.

    Ejecuta:

    whoami
    cat /etc/os-release
    ip -br a

    También puedes consultar:

    hostname -I

    En los siguientes ejemplos utilizaremos:

    192.168.1.50

    Es una IP de ejemplo. Debes sustituirla por la dirección real de tu servidor.

    20. Comprobar la comunicación con la máquina virtual

    Desde tu ordenador, intenta acceder por SSH si ya lo configuraste en clase:

    ssh alumno@192.168.1.50

    Sustituye alumno por tu usuario real.

    Si la máquina utiliza NAT

    Puede ser necesario configurar una redirección de puertos en el programa de virtualización.

    Por ejemplo:

    Puerto del ordenadorPuerto de UbuntuUso
    222222SSH
    80818080Tienda

    Con esa configuración, SSH se utilizaría así:

    ssh -p 2222 alumno@127.0.0.1

    Y la tienda de Ubuntu se abriría desde el ordenador mediante:

    http://localhost:8081

    Si utilizas una red en la que el ordenador puede acceder directamente a la IP de Ubuntu, no necesitas esas redirecciones.

    Documenta el modo de red que estás utilizando.

    21. Instalar los servicios necesarios

    En Ubuntu Server ejecuta:

    sudo apt update

    Después:

    sudo apt install apache2 mysql-server php libapache2-mod-php php-mysql php-cli unzip

    Apache atenderá las peticiones web; PHP ejecutará el código del servidor; MySQL almacenará los datos. La documentación de Ubuntu recoge la instalación de Apache y de PHP con su módulo para Apache. Ubuntu Server documentation

    Si algunos paquetes ya estaban instalados, revisa el resultado del comando: no es necesario reinstalarlos manualmente.

    Activa los servicios:

    sudo systemctl enable --now apache2
    sudo systemctl enable --now mysql

    Comprueba su estado:

    systemctl status apache2 --no-pager
    systemctl status mysql --no-pager

    Ambos deben aparecer activos.

    Evidencia: captura de los servicios funcionando.

    22. Comprobar la versión y las extensiones de PHP

    Ejecuta:

    php -v

    Después:

    php -m

    Comprueba que aparecen:

    mysqli
    mysqlnd
    fileinfo
    session

    Anota la versión de PHP de Ubuntu y compárala con la de XAMPP.

    23. Transferir el proyecto al servidor

    Para esta instalación, utiliza el ZIP original entregado por el profesor. Crearemos una base de datos nueva en Ubuntu.

    Puedes transferir el archivo mediante SFTP o con scp.

    Ejemplo, ejecutado desde tu ordenador y desde la carpeta donde está el ZIP:

    scp loot-figures-php-clase.zip alumno@192.168.1.50:~/

    Si utilizas la redirección SSH del ejemplo anterior:

    scp -P 2222 loot-figures-php-clase.zip alumno@127.0.0.1:~/

    Observa que scp utiliza -P mayúscula para indicar el puerto.

    En Ubuntu comprueba que ha llegado:

    ls -lh ~/loot-figures-php-clase.zip

    Descomprime:

    cd ~
    unzip loot-figures-php-clase.zip

    Comprueba:

    ls ~/loot-figures-clase

    Mueve el proyecto:

    sudo mv ~/loot-figures-clase /var/www/

    La ubicación final será:

    /var/www/loot-figures-clase

    Si ya existe una carpeta con ese nombre por un intento anterior, revisa su contenido antes de repetir el movimiento.

    24. Configurar Apache en Ubuntu

    24.1. Añadir el puerto

    Abre:

    sudo nano /etc/apache2/ports.conf

    Añade:

    Listen 8080

    Conserva las instrucciones existentes y no dupliques Listen 8080 si ya aparece.

    24.2. Crear el sitio

    Ejecuta:

    sudo nano /etc/apache2/sites-available/loot-figures.conf

    Introduce:

    <VirtualHost *:8080>
        DocumentRoot /var/www/loot-figures-clase/public
    
        <Directory /var/www/loot-figures-clase/public>
            Options -Indexes
            AllowOverride All
            Require all granted
        </Directory>
    
        ErrorLog ${APACHE_LOG_DIR}/loot-figures-error.log
        CustomLog ${APACHE_LOG_DIR}/loot-figures-access.log combined
    </VirtualHost>

    Guarda el archivo.

    Activa el sitio:

    sudo a2ensite loot-figures.conf

    Comprueba la sintaxis:

    sudo apache2ctl configtest

    Si aparece:

    Syntax OK

    reinicia Apache:

    sudo systemctl restart apache2

    No desactives los sitios anteriores de clase: esta tienda utiliza otro puerto.

    25. Crear la base de datos en Ubuntu

    Accede a MySQL:

    sudo mysql

    La instalación de MySQL mediante los paquetes de Ubuntu permite administrar el servicio y crear cuentas para las aplicaciones. Ubuntu Server documentation

    Ejecuta:

    CREATE DATABASE loot_figures
    CHARACTER SET utf8mb4
    COLLATE utf8mb4_unicode_ci;
    
    CREATE USER 'loot_app'@'localhost'
    IDENTIFIED BY 'CambiaEstaClaveBD!';
    
    GRANT SELECT, INSERT, UPDATE, DELETE
    ON loot_figures.*
    TO 'loot_app'@'localhost';

    Sal:

    EXIT;

    Importa las tablas:

    sudo mysql loot_figures < /var/www/loot-figures-clase/database/schema.sql

    Comprueba el resultado:

    sudo mysql -e "SHOW TABLES FROM loot_figures;"

    Debes encontrar las mismas tablas que en XAMPP.

    26. Configurar la conexión de la aplicación

    Copia la plantilla:

    sudo cp /var/www/loot-figures-clase/config/config.example.php /var/www/loot-figures-clase/config/config.php

    Edita:

    sudo nano /var/www/loot-figures-clase/config/config.php

    Utiliza:

    <?php
    
    return [
        'db' => [
            'host' => 'localhost',
            'port' => 3306,
            'name' => 'loot_figures',
            'user' => 'loot_app',
            'password' => 'CambiaEstaClaveBD!'
        ],
    
        'secure_cookie' => false,
        'debug' => false
    ];

    La base de datos está dentro de la propia máquina Ubuntu, por eso la aplicación utiliza localhost como servidor de base de datos.

    No debes poner la IP del ordenador Windows en esta configuración.

    27. Preparar propietarios y permisos

    Apache necesita leer los archivos del proyecto. Además, debe poder escribir en la carpeta donde se guardan las imágenes subidas.

    Configura el propietario y el grupo:

    sudo chown -R root:www-data /var/www/loot-figures-clase

    Configura los directorios:

    sudo find /var/www/loot-figures-clase -type d -exec chmod 750 {} \;

    Configura los archivos:

    sudo find /var/www/loot-figures-clase -type f -exec chmod 640 {} \;

    Permite que Apache gestione las imágenes subidas:

    sudo chown -R www-data:www-data /var/www/loot-figures-clase/public/uploads

    Comprueba:

    ls -ld /var/www/loot-figures-clase/public/uploads
    ls -l /var/www/loot-figures-clase/config/config.php

    Preguntas

    1. ¿Qué representa el usuario www-data?
    2. ¿Por qué Apache necesita permiso de escritura en uploads?
    3. ¿Por qué no necesita escribir en todos los archivos PHP?
    4. ¿Qué diferencia hay entre los permisos de un archivo y los de un directorio?

    No utilices chmod 777 para resolver problemas de permisos. Debes identificar qué usuario necesita acceso y qué operación debe realizar.

    28. Cargar los datos de ejemplo

    Ejecuta el script utilizando el usuario que puede leer los archivos del proyecto:

    sudo -u www-data php /var/www/loot-figures-clase/scripts/seed.php

    Comprueba los productos:

    sudo mysql -e "SELECT id, name, stock FROM loot_figures.products;"

    Comprueba los usuarios sin mostrar los hashes de contraseña:

    sudo mysql -e "SELECT id, name, email, role FROM loot_figures.users;"

    Evidencia: captura de los datos creados.

    29. Comprobar el acceso web

    Desde tu ordenador abre:

    http://192.168.1.50:8080

    Sustituye la IP por la del servidor.

    Si utilizas la redirección NAT propuesta, abre:

    http://localhost:8081

    Si no puedes acceder

    Comprueba el estado de Apache:

    systemctl status apache2 --no-pager

    Comprueba los puertos:

    sudo ss -lntp

    Revisa el cortafuegos:

    sudo ufw status

    Si UFW está activo, permite el puerto de la tienda:

    sudo ufw allow 8080/tcp

    No es necesario activar ni desactivar el cortafuegos para realizar esta comprobación.

    Consulta el registro de errores del sitio:

    sudo tail -n 50 /var/log/apache2/loot-figures-error.log

    Importante: escribir localhost en el navegador de tu ordenador apunta a tu ordenador. No apunta a Ubuntu, salvo que hayas configurado una redirección de puertos.

    30. Repetir las pruebas funcionales

    Realiza en Ubuntu las mismas pruebas que hiciste en XAMPP:

    • Navegación pública.
    • Catálogo y filtros.
    • Registro.
    • Login y cierre de sesión.
    • Edición del perfil.
    • Carrito y pedido.
    • Historial.
    • Administración de productos.
    • Administración de clientes.
    • Cambio de contraseña.
    • Subida de una imagen.
    • Envío y consulta de un mensaje.

    Comprueba especialmente la subida de imágenes: permite verificar que los permisos de uploads están preparados correctamente.

    31. Comprobar qué está publicando Apache

    Intenta abrir:

    http://IP_DEL_SERVIDOR:8080/config/config.php
    http://IP_DEL_SERVIDOR:8080/database/schema.sql
    http://IP_DEL_SERVIDOR:8080/scripts/seed.php

    Estas direcciones no deben permitir acceder a esos archivos, porque están fuera de la carpeta pública.

    En cambio, debe funcionar:

    http://IP_DEL_SERVIDOR:8080/api/listar_productos.php

    Esta dirección devolverá los productos en JSON.

    Explica por qué unas rutas son accesibles y otras no.


    Bloque D. Comparación, documentación y entrega

    32. Comparar las dos instalaciones

    Completa esta tabla con los datos reales de tu trabajo:

    AspectoXAMPPUbuntu Server
    Sistema operativo
    Versión de PHP
    Motor y versión de base de datos
    Ubicación del proyecto
    Carpeta pública
    Archivo de configuración del sitio Apache
    Dirección de acceso
    Puerto web
    Usuario de la base de datos
    Gestión de permisos de uploads
    Ubicación de los registros de errores

    Responde también:

    1. ¿Qué pasos son iguales en los dos entornos?
    2. ¿Qué pasos cambian?
    3. ¿Qué tareas facilita XAMPP?
    4. ¿Qué servicios has tenido que preparar en Ubuntu?
    5. ¿Por qué el editor no sustituye al servidor web?
    6. ¿Dónde se ejecuta PHP?
    7. ¿Dónde se ejecuta JavaScript?
    8. ¿Por qué necesitas copiar archivos y preparar también la base de datos?

    33. Registrar las pruebas

    Incluye una tabla de comprobación para cada instalación:

    PruebaResultado esperadoResultado obtenidoEvidencia
    Abrir la homeSe muestran diseño e imágenes
    Consultar catálogoSe muestran los productos
    Registrar clienteSe crea la cuenta
    Iniciar sesiónSe accede a la cuenta
    Crear pedidoSe guarda y aparece en el historial
    Editar productoEl cambio aparece en el catálogo
    Cambiar contraseñaFunciona la nueva contraseña
    Subir imagenSe guarda y se muestra
    Enviar contactoEl administrador puede leerlo

    No marques una prueba como correcta sin realizarla.

    34. Documentar incidencias

    Si encuentras un problema, registra:

    • Qué estabas intentando hacer.
    • El mensaje de error.
    • Qué comprobaste.
    • La causa que identificaste.
    • La solución aplicada.
    • Cómo verificaste que funcionaba.

    Si no encuentras incidencias, indica las comprobaciones preventivas que has realizado: configuración, servicios, puertos, permisos y conexión a la base de datos.

    35. Documentación que debes entregar

    Prepara un README.md con estas secciones:

    1. Título, autor y objetivo.
    2. Descripción de la aplicación.
    3. Requisitos.
    4. Estructura del proyecto.
    5. Instalación en XAMPP.
    6. Instalación en Ubuntu Server.
    7. Configuración de Apache y base de datos.
    8. Pruebas funcionales.
    9. Incidencias y soluciones.
    10. Comparación de los entornos.
    11. Conclusiones personales.

    Guarda las capturas en una carpeta:

    capturas

    Puedes insertarlas así:

    ![Panel de XAMPP con los servicios iniciados](capturas/xampp-servicios.png)

    Los comandos deben aparecer en bloques de código:

    ```bash
    sudo systemctl status apache2 --no-pager
    ```

    La documentación debe explicar tu instalación real, con tus rutas, tu IP, tus versiones y tus resultados.

    No entregues únicamente una copia de este enunciado.

    36. Entrega final

    Entrega un ZIP con:

    • README.md.
    • La carpeta capturas.
    • Los fragmentos de configuración necesarios para comprender tu instalación, con las contraseñas sustituidas por un marcador.

    Por ejemplo:

    'password' => 'CONTRASEÑA_OCULTA'

    No es necesario incluir los discos de la máquina virtual ni una copia completa de XAMPP.

    Conserva las dos instalaciones funcionando para poder demostrarlas en clase.

    37. Comprobación final antes de entregar

    • La aplicación funciona en XAMPP.
    • La aplicación funciona en Ubuntu Server.
    • Has comprobado las funciones de cliente y administrador.
    • La subida de imágenes funciona en ambos entornos.
    • Apache sirve únicamente la carpeta public.
    • Has identificado los modelos, DAO y archivos de operaciones.
    • Has observado una respuesta JSON.
    • La documentación contiene pasos, comandos y evidencias.
    • Las capturas se visualizan correctamente en el README.
    • Puedes explicar qué has configurado y por qué.

    La actividad se considerará completada cuando puedas mostrar las dos instalaciones y explicar el recorrido de una petición desde el navegador hasta la base de datos.

  • Proyecto: Operación HAWKINS

    Proyecto: Operación HAWKINS

    Diseño de una infraestructura empresarial con VLSM y servicios de red

    1. Introducción

    Audio presentación

    El Centro de Investigación Avanzada de Hawkins es una organización ficticia inspirada en la serie Stranger Things. Tras varios incidentes en sus instalaciones, la dirección ha decidido sustituir su red improvisada por una infraestructura profesional, segmentada, documentada y preparada para crecer.

    El centro está formado por tres ubicaciones:

    • Sede Central de Hawkins: oficinas, laboratorios, seguridad, servidores y zona de visitantes.
    • Estación de Campo Starcourt: pequeño centro remoto de observación y comunicaciones.
    • Búnker NINA: instalación aislada en la que se realizan pruebas especialmente sensibles.

    Vuestro equipo ha sido contratado como consultora de sistemas y redes. Tendréis que analizar las necesidades de la organización, diseñar el direccionamiento mediante VLSM, construir una maqueta funcional y desplegar varios servicios de red.

    No se valorará únicamente que los equipos puedan comunicarse. La empresa exige una solución lógica, segura, ampliable, comprobada y correctamente documentada.


    2. Modalidad de trabajo

    • Trabajo individual o en parejas, según indique el profesor.
    • Herramienta principal recomendada: Cisco Packet Tracer.
    • Red IPv4 asignada a todo el proyecto: 172.20.0.0/16.
    • Todos los cálculos de subnetting deberán realizarse manualmente y explicarse además de mostrar las tablas completas.
    • En Packet Tracer no es necesario colocar físicamente todos los dispositivos indicados. Se representará cada red con un número reducido de equipos, pero el direccionamiento deberá admitir la cantidad real solicitada.
    • No es necesario realizar la configuración en los routers y switch, aunque si debe estar bien explicado en la documentación.

    3. Objetivos de aprendizaje

    Al terminar el proyecto, el alumnado deberá ser capaz de:

    1. Analizar las necesidades de una infraestructura con varias sedes.
    2. Crear subredes de distinto tamaño mediante VLSM.
    3. Calcular direcciones de red, broadcast, rangos utilizables y máscaras.
    4. Organizar departamentos mediante redes o VLAN independientes.
    5. Configurar direccionamiento estático y dinámico.
    6. Permitir la comunicación entre redes mediante routing.
    7. Aplicar reglas básicas de segmentación y control de acceso.
    8. Verificar el funcionamiento mediante pruebas reproducibles.
    9. Elaborar documentación técnica en Markdown.

    4. Historia del proyecto

    La infraestructura antigua utilizaba una única red para empleados, cámaras, servidores y visitantes. Esto ha provocado direcciones duplicadas, dificultad para localizar averías y acceso de usuarios no autorizados a recursos internos.

    La nueva red recibirá el nombre HAWKNET. Cada departamento deberá disponer de su propia subred. Las tres sedes estarán conectadas mediante enlaces WAN y compartirán determinados servicios alojados en la sede central.

    La dirección establece cuatro prioridades:

    • separar el tráfico de los departamentos;
    • garantizar que los nombres internos se resuelvan mediante DNS;
    • proporcionar configuración automática a los puestos de usuario;
    • proteger los laboratorios y la red de gestión frente a visitantes y dispositivos IoT.

    5. Topología general requerida

    La maqueta deberá contener, como mínimo:

    • un router o dispositivo de capa 3 en cada sede;
    • switches suficientes para representar la segmentación solicitada;
    • un switch principal en la sede central;
    • enlaces troncales cuando se utilicen VLAN;
    • un enlace entre la sede central y Starcourt;
    • un enlace entre la sede central y el búnker NINA;
    • servidores centralizados en Hawkins;
    • al menos un equipo cliente representativo en cada subred;
    • una nube o router ISP que represente Internet;
    • puntos de acceso inalámbricos para empleados y visitantes.

    El diseño exacto queda a criterio del equipo, pero todas las decisiones deberán justificarse.


    6. Necesidades de direccionamiento

    Se utilizará la red 172.20.0.0/16. A partir de ella debéis crear todas las subredes necesarias mediante VLSM.

    Las cantidades representan la capacidad que debe soportar cada red, no el número de dispositivos que hay que insertar en Packet Tracer.

    6.1. Sede Central de Hawkins

    Red o departamentoDispositivos actualesCrecimiento mínimo previsto
    Sensores, puertas y dispositivos IoT85020 %
    Wi-Fi de visitantes42020 %
    Personal administrativo19020 %
    Laboratorio de Energía11020 %
    Videovigilancia y seguridad física7520 %
    Investigadores6020 %
    Centro de Operaciones4220 %
    Servidores internos2620 %
    Telefonía IP2420 %
    Administración de red1220 %

    6.2. Estación de Campo Starcourt

    Red o departamentoDispositivos actualesCrecimiento mínimo previsto
    Personal de operaciones4820 %
    Sensores y cámaras3020 %
    Invitados1820 %
    Administración de red620 %

    6.3. Búnker NINA

    Red o departamentoDispositivos actualesCrecimiento mínimo previsto
    Laboratorio restringido2820 %
    Seguridad1420 %
    Servidores locales620 %
    Administración de red520 %

    6.4. Enlaces entre routers

    Debéis reservar una subred independiente para cada uno de estos enlaces:

    • Hawkins ↔ Starcourt.
    • Hawkins ↔ NINA.
    • Hawkins ↔ ISP.

    Cada enlace solo necesita las direcciones imprescindibles para sus dos extremos. Deberéis decidir si usar /30 o /31 y comprobar si la opción elegida es compatible con el simulador y los dispositivos utilizados.


    7. Normas para realizar el VLSM

    1. Calculad la capacidad necesaria sumando el crecimiento del 20 % y redondeando siempre hacia arriba.
    2. Recordad incluir las direcciones que vayan a consumir puertas de enlace, servidores u otros dispositivos de infraestructura.
    3. Ordenad las redes desde la que necesita más direcciones hasta la que necesita menos.
    4. Asignad a cada red el bloque más pequeño que cubra su necesidad.
    5. No pueden existir subredes solapadas.
    6. No debe desperdiciarse un bloque excesivamente grande sin una justificación técnica.
    7. La primera dirección utilizable de cada LAN se asignará, salvo justificación, a su puerta de enlace.
    8. Los servidores, routers, switches gestionables e impresoras usarán direcciones estáticas.
    9. Los clientes de usuario recibirán su configuración mediante DHCP.

    Para cada subred debéis mostrar el razonamiento utilizado. No será suficiente entregar una tabla generada automáticamente.


    8. Tabla obligatoria de direccionamiento

    La documentación incluirá una tabla como la siguiente, completada para todas las redes:

    SedeRed/VLANNecesidad con crecimientoPrefijoMáscara decimalDirección de redPrimer hostÚltimo hostBroadcastGateway
    HawkinsIoT

    También se añadirá una segunda tabla para los dispositivos configurados:

    DispositivoInterfazDirección IPMáscara/prefijoGatewayDNSAsignación
    SRV-DNS-01Fa0Estática

    9. VLAN y segmentación

    En la sede central cada departamento deberá estar separado mediante una VLAN o interfaz física diferente. Si se utilizan VLAN, debéis:

    • asignar un identificador y un nombre descriptivo a cada VLAN;
    • configurar los puertos de acceso;
    • utilizar una VLAN de gestión distinta de la VLAN nativa;
    • documentar qué puertos pertenecen a cada VLAN.

    Los identificadores de VLAN son libres, pero deben seguir un criterio coherente. Por ejemplo, se pueden agrupar por sede o por tipo de servicio.


    10. Routing entre sedes

    Todos los routers deberán conocer las redes remotas. El equipo elegirá una de estas opciones:

    El fallo de una ruta no podrá ocultarse añadiendo rutas innecesarias o utilizando una única red sin segmentación.


    11. Servicios obligatorios

    La red de servidores y las redes de administración no utilizarán DHCP para sus dispositivos principales.

    11.2. DNS

    El dominio interno será:

    hawkins.lab

    El DNS deberá contener, al menos, estos registros:

    11.3. Servidor web e intranet

    El servidor web mostrará una página sencilla con:

    • nombre y logotipo ficticio de la organización;
    • estado de las tres sedes;
    • mensaje de bienvenida;
    • nombre de los integrantes del equipo;
    • fecha de la última comprobación.

    La web pública de pruebas podrá ser accesible desde todas las redes. La intranet solo deberá ser accesible desde redes internas autorizadas.


    12. Requisitos básicos de seguridad

    La segmentación debe traducirse en reglas de acceso. Se configurarán ACL u otro mecanismo equivalente para cumplir, como mínimo, estas políticas:

    1. La red de visitantes solo puede acceder al DNS necesario, al portal web y a Internet.
    2. Los visitantes no pueden iniciar conexiones hacia las redes internas.
    3. La red IoT no puede acceder a Administración de red ni a los equipos de investigadores.
    4. Solo Administración de red puede gestionar routers y switches mediante SSH.
    5. Telnet deberá permanecer deshabilitado.
    6. El laboratorio NINA no será accesible desde redes de invitados.
    7. Seguridad podrá consultar las cámaras y sensores de las tres sedes.
    8. Los servidores DNS, DHCP y correo deberán ser accesibles únicamente desde las redes que necesiten cada servicio.

    Las reglas se colocarán lo más cerca posible del origen o destino y se documentará el motivo de cada una.


    13. Acceso a Internet y NAT

    La sede central se conectará a un router ISP. Debéis configurar:

    • una ruta por defecto hacia el ISP;
    • NAT/PAT para que las redes privadas autorizadas puedan salir a Internet;
    • un servidor externo de prueba, por ejemplo www.vecna-news.net, situado en una red que no pertenezca a 172.20.0.0/16;
    • bloqueo de salida para las redes que, según vuestra política, no deban acceder a Internet.

    No es necesario publicar servidores internos mediante NAT estático, aunque puede realizarse como ampliación.


    14. Nombres y configuración de dispositivos

    Los nombres deberán permitir identificar su ubicación y función. Ejemplos:

    RTR-HAW-01
    RTR-STAR-01
    RTR-NINA-01
    SW-HAW-CORE-01
    SW-HAW-LAB-01
    SRV-HAW-DNS-01
    PC-STAR-OPS-01

    15. Fases de realización

    Fase 1. Análisis

    1. Leed el caso completo.
    2. Identificad las sedes, departamentos, servidores y enlaces.
    3. Dibujad un primer esquema lógico.
    4. Decidid qué servicios serán centrales y cuáles serán locales.
    5. Anotad las restricciones de seguridad.

    Fase 2. Cálculo VLSM

    1. Calculad el número de hosts con crecimiento.
    2. Ordenad las redes de mayor a menor.
    3. Determinad el prefijo mínimo de cada una.
    4. Asignad los bloques dentro de 172.20.0.0/16.
    5. Calculad red, primer host, último host y broadcast.
    6. Comprobad que no existen solapamientos.
    7. Reservad espacio para futuras ampliaciones.

    Fase 3. Construcción de la topología

    1. Colocad routers, switches, servidores y clientes.
    2. Cablead correctamente los dispositivos.
    3. Asignad nombres a todos los equipos.
    4. Cread VLAN y configurad puertos.
    5. Configurad puertas de enlace.

    Fase 4. Direccionamiento y routing

    1. Configurad interfaces y subinterfaces.
    2. Asignad direcciones estáticas a infraestructura.
    3. Configurad rutas estáticas u OSPF.

    Fase 5. Pruebas y documentación

    1. Ejecutad el plan de pruebas.
    2. Corregid los fallos encontrados.
    3. Capturad evidencias relevantes.
    4. Completad el README.md.
    5. Revisad que otra persona pueda comprender y reproducir el proyecto.

    No se considerará demostrada una política si únicamente se prueba el caso permitido. Cuando corresponda, deberán probarse tanto el acceso correcto como su bloqueo.


    17. Entregables

    La entrega contendrá una carpeta comprimida con esta estructura orientativa:

    operacion-hawkins/
    ├── README.md
    ├── packet-tracer/
    │   └── hawknet.pkt
    ├── configuraciones/
    │   ├── RTR-HAW-01.txt
    │   ├── RTR-STAR-01.txt
    │   └── RTR-NINA-01.txt
    ├── diagramas/
    │   ├── topologia-logica.png
    │   └── topologia-fisica.png
    

    El archivo principal se llamará exactamente README.md y utilizará Markdown. Más adelante, cuando se haya trabajado Git, el mismo proyecto deberá poder incorporarse a un repositorio sin reorganizar toda la documentación.


    18. Contenido obligatorio del README.md

    1. Portada: título, integrantes, curso y fecha.
    2. Resumen ejecutivo del proyecto.
    3. Descripción de las tres sedes.
    4. Requisitos detectados.
    5. Diagrama lógico de red.
    6. Explicación paso a paso del cálculo VLSM.
    7. Tabla completa de direccionamiento.
    8. Tabla de VLAN.
    9. Inventario y función de los dispositivos.
    10. Explicación del routing seleccionado.
    11. Reglas de seguridad y ACL aplicadas.
    12. Configuración de NAT/PAT.
    13. Plan de pruebas y resultados.
    14. Problemas encontrados y soluciones.
    15. Conclusiones y posibles mejoras.
    16. Fuentes consultadas.

    Las capturas deben estar recortadas, ser legibles y llevar un pequeño texto explicativo. No se admitirán decenas de capturas sin contexto ni configuraciones pegadas sin explicación.


    19. Condiciones de aceptación

    El proyecto se considerará funcional cuando:

    • todas las subredes estén calculadas correctamente;
    • no haya direcciones duplicadas ni bloques solapados;
    • la comunicación entre sedes funcione;
    • los nombres internos se resuelvan mediante DNS;
    • los servicios obligatorios sean accesibles desde las redes autorizadas;
    • los accesos prohibidos sean realmente bloqueados;
    • el acceso exterior utilice NAT/PAT;
    • las pruebas estén documentadas;
    • el archivo de Packet Tracer se abra sin errores;
    • el README permita entender el trabajo sin una explicación oral adicional.

    Un proyecto en el que “todo puede comunicarse con todo” no cumplirá los requisitos de segmentación y seguridad.


    Las ampliaciones solo puntuarán si la parte obligatoria funciona y están correctamente explicadas.


    20. Penalizaciones importantes

    • Subredes solapadas o uso incorrecto de red/broadcast.
    • Archivo .pkt que no abre o que no coincide con la documentación.
    • Capturas de pantalla ajenas o configuraciones copiadas que el equipo no pueda explicar.
    • Uso de una sola red para evitar el trabajo de VLSM.

    21. Defensa del proyecto

    El profesor podrá seleccionar al azar cualquier dispositivo o prueba. El equipo tendrá que:

    Todos los integrantes deben conocer el proyecto completo. La división de tareas no exime de comprender el trabajo de la otra persona.


    23. Pregunta final de reflexión

    Incluid al final del README una respuesta razonada a estas cuestiones:

    • ¿Qué ventajas ofrece VLSM frente a utilizar la misma máscara en todas las redes?
    • ¿Qué ocurriría si empleados, servidores, cámaras y visitantes compartieran la misma red?
    • ¿Qué servicio causaría un impacto mayor si dejara de funcionar: DHCP, DNS o routing? Justificad la respuesta según vuestra infraestructura.
    • ¿Qué parte del diseño cambiaríais si la empresa duplicara su tamaño?

    Misión

    La red de Hawkins no debe limitarse a “tener pings”. Debe ser una infraestructura organizada, útil y defendible. Vuestro objetivo es demostrar que podéis convertir las necesidades de una organización en un diseño IP correcto, desplegar los servicios básicos y verificar que cada usuario accede únicamente a los recursos que necesita.

  • Proyecto: despliegue, ampliación y documentación de un servidor web con Ubuntu

    Proyecto: despliegue, ampliación y documentación de un servidor web con Ubuntu

    1. Presentación de la actividad

    Audio de introducción

    En esta actividad vas a desplegar y configurar un servidor web con Ubuntu siguiendo tres recursos proporcionados por el profesor. El objetivo no es limitarse a copiar comandos y realizar capturas de pantalla. Deberás comprender lo que haces, comprobar que cada elemento funciona y crear una documentación técnica que permita a otra persona repetir el proceso.

    El trabajo se desarrollará en tres partes consecutivas:

    1. Montaje del servidor web con Ubuntu.
    2. Ampliación UFW
    3. Configuración de Apache mediante archivos .htaccess.

    Cada parte amplía la anterior. Al terminar tendrás un único servidor funcional y un único documento técnico que describa todo el proyecto desde la preparación del entorno hasta las pruebas finales.

    2. Recursos obligatorios

    Debes seguir los tres recursos en el orden indicado. Puedes consultar otras fuentes para resolver problemas o ampliar las explicaciones, pero deberás citarlas en el apartado de referencias.

    3. Objetivos de aprendizaje

    Al finalizar la actividad deberás ser capaz de:

    • Preparar un sistema Ubuntu para funcionar como servidor.
    • Instalar, configurar y comprobar los servicios solicitados.
    • Identificar la función de los principales archivos, directorios, módulos, usuarios, permisos y puertos utilizados.
    • Aplicar configuraciones de Apache y comprobar sus efectos.
    • Interpretar los resultados de comandos de diagnóstico.
    • Detectar errores frecuentes y documentar su solución.
    • Valorar los riesgos de seguridad de una configuración.
    • Redactar documentación técnica clara y reproducible utilizando Markdown.
    • Organizar evidencias sin convertir el documento en una sucesión de capturas.
    • Preparar el proyecto para publicarlo posteriormente en un repositorio Git.

    4. Resultado que debes conseguir

    Debes disponer de un servidor Ubuntu desde el que se puedan demostrar las configuraciones solicitadas en las tres partes. Además, entregarás una documentación técnica completa en un archivo llamado exactamente:

    README.md

    La extensión correcta es .md, no .me. El archivo se escribirá con sintaxis Markdown.

    La documentación debe ser una ampliación razonada de los materiales. Esto significa que no debes copiar literalmente las explicaciones del profesor. Tienes que describir el proceso con tus propias palabras, explicar qué hace cada elemento importante y aportar pruebas de funcionamiento.

    5. Modalidad de realización

    • La actividad será individual, salvo que el profesor indique expresamente otra modalidad.
    • Cada estudiante deberá utilizar su propia máquina virtual o servidor asignado.
    • No se compartirán archivos README.md, capturas ni textos entre compañeros.
    • Sí se permite ayudar a localizar un error, siempre que cada estudiante comprenda y documente su propia solución.

    6. Preparación antes de comenzar

    Antes de modificar el servidor, anota en tu documentación:

    • Sistema de virtualización o equipo empleado.
    • Versión de Ubuntu.
    • Nombre de host.
    • Dirección IP del servidor.
    • Tipo de red de la máquina virtual: NAT, puente, red interna u otra.
    • Recursos asignados: CPU, memoria RAM y disco.
    • Dirección IP o nombre del equipo cliente desde el que realizarás las pruebas.

    Incluye una tabla similar a esta, completada con tus datos reales:

    ElementoConfiguración utilizada
    Sistema operativoUbuntu Server …
    Nombre del servidor…
    Dirección IP…
    CPU y RAM…
    Disco…
    Tipo de red…
    Equipo cliente…

    Recomendación previa

    Si trabajas con una máquina virtual, crea una instantánea antes de comenzar cada parte. Así podrás volver al estado anterior si una configuración deja el servidor inaccesible. Anota en el README.md cuándo has creado esas instantáneas.

    Protección de datos

    No incluyas en la entrega:

    • Contraseñas reales.
    • Claves privadas.
    • Tokens o credenciales.
    • Cookies o sesiones del Campus Virtual.
    • Direcciones públicas o datos personales que no sean necesarios.

    Oculta estos datos en las capturas. Utiliza valores de ejemplo cuando expliques credenciales.

    7. Parte 1: montaje del servidor web con Ubuntu

    Sigue el recurso de la parte 1 y documenta el proceso. Tu explicación deberá incluir, como mínimo, los siguientes bloques cuando aparezcan en el procedimiento realizado:

    7.1 Preparación del sistema

    Documenta la actualización del sistema y cualquier paquete previo necesario.

    Para cada comando importante:

    1. Escríbelo en un bloque de código.
    2. Explica qué hace.
    3. Describe las opciones o parámetros utilizados.
    4. Indica el resultado esperado.
    5. Añade una comprobación objetiva.

    Ejemplo del nivel de explicación esperado:

    sudo systemctl status apache2

    Este comando consulta el estado del servicio Apache. En la salida se debe comprobar que aparece como activo y en ejecución. No es suficiente con escribir «funciona»: hay que indicar qué dato de la salida permite afirmarlo.

    7.2 Instalación y prueba de Apache

    Debes explicar:

    • Qué es Apache y qué función cumple en el proyecto.
    • Qué paquete se instala.
    • Cómo se inicia, detiene, reinicia y consulta el servicio.
    • Qué directorio contiene inicialmente el sitio web.
    • Qué puerto utiliza HTTP.
    • Cómo accedes desde el equipo cliente.
    • Cómo compruebas el servicio desde terminal y desde navegador.

    Incluye una página web propia de prueba. No entregues únicamente la página predeterminada de Apache. La página debe mostrar, al menos, tu nombre, el título del proyecto y una indicación de que el servidor está operativo.

    7.3 Acceso remoto y transferencia de archivos

    Documenta los métodos de acceso o transferencia indicados en el recurso. Explica:

    • Qué servicio o programa interviene.
    • Qué puerto utiliza.
    • Qué usuario empleas y a qué directorio puede acceder.
    • Qué permisos has configurado.
    • Cómo has transferido o editado un archivo del sitio.
    • Cómo has verificado que el cambio aparece en el navegador.

    Si se utiliza FTP, añade una breve valoración de seguridad: diferencia entre FTP sin cifrar y alternativas como SFTP. No publiques credenciales reales.

    7.4 PHP

    Si el procedimiento incluye PHP, documenta:

    • Paquetes instalados y función de cada uno.
    • Versión instalada.
    • Integración con Apache.
    • Creación y ejecución de una página PHP de prueba.
    • Diferencia entre ejecutar PHP desde el servidor web y desde la terminal.

    Si utilizas una página con phpinfo(), elimínala o restríngele el acceso al finalizar, ya que puede mostrar información sensible del servidor. Explica esta decisión en el documento.

    7.5 Acceso mediante SSH o Visual Studio Code

    Si realizas este apartado, incluye:

    • Herramientas empleadas.
    • Configuración de la conexión sin mostrar contraseñas o claves privadas.
    • Directorio remoto abierto.
    • Prueba de edición de un archivo.
    • Evidencia del resultado servido por Apache.

    7.6 Comprobación de la parte 1

    Antes de continuar, verifica al menos:

    • El servidor responde a través de la red.
    • Apache está activo.
    • La página propia se carga desde el cliente.
    • Los archivos se encuentran en el directorio correcto.
    • PHP funciona, si forma parte del procedimiento.
    • El acceso remoto o la transferencia funciona, si se ha configurado.

    Incluye una tabla de pruebas:

    PruebaComando o acciónResultado esperadoResultado obtenidoEstado
    Estado de Apachesystemctl status apache2Servicio activo…Superada/No superada
    Acceso webAbrir http://IP_SERVIDORCarga la web propia……
    Prueba de PHPAbrir la URL de pruebaPHP genera la respuesta……

    8. Parte 2: ampliación del Campus Virtual

    Accede al recurso de la parte 2 con tu cuenta del Campus Virtual y realiza todos los pasos en el orden indicado.

    Como este bloque amplía el servidor de la parte 1, comienza explicando:

    • Qué nueva necesidad resuelve.
    • Qué servicio, componente o configuración añade.
    • Qué requisitos de la parte 1 necesita.
    • Qué cambios producirá en el servidor.

    Documentación obligatoria de cada paso

    Para cada acción relevante de la guía del campus incluye:

    1. Objetivo del paso. Qué se pretende conseguir.
    2. Comando o configuración. Escrito con el lenguaje correcto en un bloque de código.
    3. Explicación. Qué hace y por qué es necesario.
    4. Archivo afectado. Ruta completa y fragmento modificado, si corresponde.
    5. Comprobación. Comando, petición, acceso desde navegador o prueba equivalente.
    6. Resultado. Qué ocurrió realmente en tu servidor.
    7. Incidencia. Error encontrado y solución aplicada, si la hubo.

    No copies el texto completo del Campus Virtual. Reescribe el procedimiento con tus propias palabras y conserva únicamente los comandos, rutas y fragmentos de configuración necesarios.

    Comprobación de la parte 2

    Crea una tabla con todas las pruebas solicitadas por la guía. Debe quedar claro qué evidencia demuestra que la ampliación funciona y cómo podría repetirla otra persona.

    9. Parte 3: configuración de .htaccess en Apache

    Realiza la práctica de la parte 3 sobre el servidor ya configurado. Antes de empezar, crea una copia de seguridad de los archivos que vayas a modificar y documenta cómo podrías restaurarlos.

    9.1 Activación de .htaccess

    Explica:

    • Qué es un archivo .htaccess.
    • En qué directorios puede actuar.
    • Qué función cumple la directiva AllowOverride.
    • Qué diferencia existe entre AllowOverride None y AllowOverride All.
    • Qué archivo de Apache has modificado.
    • Cómo has validado la configuración antes de reiniciar o recargar el servicio.
    • Cómo has comprobado que Apache continúa funcionando.

    9.2 Autenticación básica

    Configura una zona restringida y documenta:

    • Directorio protegido.
    • Creación del archivo de usuarios.
    • Directivas de autenticación utilizadas.
    • Prueba sin autenticar, con credenciales incorrectas y con credenciales correctas.
    • Código de estado HTTP o comportamiento observado en cada caso.

    No muestres la contraseña. Investiga y explica por qué la autenticación básica debería utilizarse junto con HTTPS y por qué es preferible guardar .htpasswd fuera del directorio público cuando sea posible.

    9.3 Páginas de error personalizadas

    Crea páginas propias para los errores solicitados, por ejemplo 403 y 404. Las páginas deberán tener un diseño mínimo coherente con tu sitio.

    Comprueba cada error provocándolo de forma controlada e indica:

    • URL o acción de prueba.
    • Código esperado.
    • Código recibido.
    • Página mostrada.

    9.4 Cabeceras de seguridad

    Aplica las cabeceras propuestas en la práctica y crea una tabla como esta:

    CabeceraValor aplicadoRiesgo que ayuda a reducirMétodo de comprobación
    X-Frame-Options………
    X-Content-Type-Options………
    Referrer-Policy………
    Permissions-Policy………

    Comprueba las cabeceras con las herramientas de desarrollo del navegador o con una petición de terminal, no solo mediante una captura del archivo de configuración.

    Si el recurso incluye una cabecera considerada antigua o desaconsejada por navegadores actuales, indícalo en tu análisis y explica qué mecanismo moderno se utiliza en su lugar. Esta observación deberá estar respaldada por una fuente técnica.

    9.5 Redirecciones

    Configura y prueba las redirecciones solicitadas. Explica la diferencia entre una redirección permanente y una temporal, incluyendo:

    • Código de estado.
    • Efecto para el navegador.
    • Posible efecto en caché.
    • Uso habitual.
    • Implicaciones generales para buscadores.

    Incluye una prueba donde se puedan observar la respuesta y el destino final.

    9.6 Reescritura de URLs

    Si la guía utiliza mod_rewrite, explica:

    • Qué problema resuelve.
    • Diferencia entre redirección y reescritura interna.
    • Módulo necesario.
    • Significado de la regla aplicada.
    • URL escrita por el usuario y recurso procesado realmente.

    Debes demostrar el funcionamiento con al menos un ejemplo propio diferente del ejemplo literal de la guía.

    9.7 Resto de configuraciones del recurso

    Completa también las configuraciones adicionales incluidas en la guía, como control de indexación, protección u ocultación de recursos, caché o compresión, cuando aparezcan en el procedimiento. Para cada una explica el objetivo, la configuración aplicada, la prueba realizada y su resultado.

    9.8 Comprobación de la parte 3

    Prepara una tabla final de pruebas que incluya, como mínimo:

    • Acceso a la zona restringida.
    • Error 403.
    • Error 404.
    • Cabeceras de seguridad.
    • Redirección temporal.
    • Redirección permanente.
    • Reescritura de URL.
    • Resto de funcionalidades realizadas.

    10. Ampliaciones técnicas obligatorias

    Tu trabajo no debe ser una reproducción literal de los enlaces. Añade las siguientes ampliaciones:

    Ampliación A: mapa del sistema

    Incluye un diagrama Mermaid que muestre, al menos, el equipo cliente, el servidor Ubuntu, Apache y los componentes principales instalados. Ejemplo de sintaxis:

    flowchart LR
        A[Cliente] -->|HTTP| B[Apache en Ubuntu]
        B --> C[Sitio web]
        B --> D[PHP]

    Adapta el diagrama a tu instalación real. No copies el ejemplo sin modificarlo.

    Ampliación B: relación de puertos y servicios

    Incluye una tabla con los servicios utilizados, sus puertos, protocolo de transporte, finalidad y estado final. Si un puerto no debe quedar accesible, explícalo.

    Ampliación C: seguridad

    Identifica al menos cinco riesgos o decisiones de seguridad observados durante las tres partes. Para cada uno indica:

    • Riesgo.
    • Configuración relacionada.
    • Consecuencia posible.
    • Medida de mejora.
    • Prioridad: baja, media o alta.

    Ampliación D: diagnóstico

    Incluye una pequeña guía de resolución de problemas con un mínimo de cinco incidencias. Pueden ser errores que hayas encontrado o errores razonables que hayas reproducido de forma segura.

    SíntomaPosible causaComprobaciónSolución
    Apache no arrancaError de sintaxis……
    La web no responde desde el cliente………

    Ampliación E: comandos de comprobación

    Crea una sección de consulta rápida con los comandos que permitan comprobar el estado del servidor. No basta con enumerarlos: añade una frase que explique qué verifica cada uno.

    11. Estructura obligatoria del README.md

    El documento deberá contener, como mínimo, esta estructura:

    # Despliegue y ampliación de un servidor web con Ubuntu
    
    ## 1. Autor y datos de la práctica
    ## 2. Resumen del proyecto
    ## 3. Objetivos
    ## 4. Entorno y requisitos
    ## 5. Esquema de la infraestructura
    ## 6. Parte 1: montaje del servidor web
    ## 7. Parte 2: ampliación del Campus Virtual
    ## 8. Parte 3: configuración de .htaccess
    ## 9. Pruebas finales
    ## 10. Problemas encontrados y soluciones
    ## 11. Análisis de seguridad
    ## 12. Conclusiones
    ## 13. Referencias

    Puedes añadir subsecciones, pero no eliminar las anteriores.

    12. Requisitos de formato Markdown

    En el README.md deberás utilizar correctamente:

    • Títulos y subtítulos con #, ## y ###.
    • Párrafos breves y explicativos.
    • Listas numeradas y no numeradas.
    • Tablas.
    • Enlaces con texto descriptivo.
    • Imágenes con texto alternativo.
    • Bloques de código indicando el lenguaje: bash, apache, html, php, etc.
    • Código corto entre comillas invertidas.
    • Avisos o notas mediante citas >.
    • Al menos un diagrama Mermaid.
    • Índice con enlaces internos si el documento es largo.

    No utilices capturas para mostrar texto que puede copiarse, como comandos o configuraciones. Escríbelo en bloques de código y reserva las imágenes para demostrar resultados visuales relevantes.

    13. Capturas y evidencias

    Guarda las imágenes en una carpeta llamada img y utiliza nombres descriptivos:

    img/01-apache-activo.png
    img/02-web-desde-cliente.png
    img/03-zona-restringida.png
    img/04-error-404.png

    Insértalas con rutas relativas:

    ![Apache activo en el servidor](img/01-apache-activo.png)

    Cada evidencia debe cumplir estas condiciones:

    • Tener relación directa con una prueba.
    • Ser legible.
    • Mostrar solo la información necesaria.
    • Tener una explicación antes o después de la imagen.
    • Ocultar contraseñas, tokens y otros datos sensibles.
    • No repetir varias capturas que demuestren exactamente lo mismo.

    14. Organización de la entrega

    La carpeta deberá tener una estructura similar a esta:

    apellido-nombre-servidor-web/
    ├── README.md
    ├── img/
    │   ├── 01-apache-activo.png
    │   ├── 02-web-desde-cliente.png
    │   └── ...
    ├── web/
    │   ├── index.html
    │   ├── 403.html
    │   ├── 404.html
    │   └── ...
    └── config/
        ├── htaccess.txt
        └── ...

    Los archivos de configuración se entregarán como copia para su revisión. Si un archivo debe llamarse .htaccess en el servidor, puedes conservar ese nombre dentro de la entrega o añadir una copia legible como htaccess.txt. Nunca incluyas archivos de contraseñas reales como .htpasswd.

    15. Entrega actual mediante ZIP

    Como todavía no hemos trabajado Git, en esta primera entrega comprime la carpeta completa en un archivo ZIP con este nombre:

    apellido-nombre-servidor-web.zip

    Antes de subirlo, descomprímelo en una carpeta temporal y comprueba que:

    • Existe README.md en la raíz.
    • El documento se abre correctamente.
    • Las imágenes se muestran usando rutas relativas.
    • Se incluyen los archivos web y las configuraciones necesarias.
    • No hay contraseñas ni datos sensibles.
    • No se incluyen discos virtuales, imágenes ISO, copias completas de la máquina virtual ni carpetas innecesarias.

    Sube el ZIP al espacio de entrega indicado por el profesor.

    16. Publicación posterior en Git

    La entrega mediante ZIP es provisional. Cuando estudiemos Git y GitHub, deberás publicar esta misma actividad en un repositorio.

    Por este motivo, organiza desde ahora el trabajo como si ya fuera un repositorio:

    • Un único README.md principal en la raíz.
    • Carpetas con nombres simples, sin espacios ni tildes.
    • Rutas relativas para imágenes y enlaces internos.
    • Archivos ordenados y con nombres descriptivos.
    • Ninguna contraseña o credencial guardada.
    • Un archivo .gitignore cuando aprendamos Git, si el proyecto lo necesita.

    Más adelante se valorará la evolución del documento mediante commits. No será válido crear el repositorio al final y subir todo sin mostrar el proceso de mejora cuando se explique esa parte de la asignatura.

    17. Defensa y comprobación por parte del profesor

    El profesor podrá solicitar que el estudiante:

    • Explique cualquier comando incluido.
    • Localice un archivo de configuración.
    • Reinicie o recargue un servicio.
    • Demuestre una de las pruebas.
    • Modifique una regla sencilla.
    • Interprete un error.
    • Justifique una decisión de seguridad.

    Una configuración que funciona pero que el estudiante no puede explicar se considerará incompleta.

    18. Criterios de evaluación

    CriterioPeso
    Parte 1: instalación, configuración y pruebas20 %
    Parte 2: realización, explicación y pruebas15 %
    Parte 3: .htaccess, seguridad y pruebas25 %
    Ampliaciones técnicas y capacidad de análisis15 %
    Calidad del README.md y uso de Markdown15 %
    Organización, evidencias, referencias y entrega10 %
    Total100 %

    Para obtener una valoración alta

    El documento debe permitir reproducir el proyecto, explicar el propósito de las configuraciones, incluir pruebas objetivas, analizar riesgos y mostrar capacidad para resolver problemas.

    Penalizaciones importantes

    Podrán reducir la calificación:

    • Copiar y pegar los recursos sin elaborar explicaciones propias.
    • Incluir comandos que no se han ejecutado o resultados inventados.
    • Presentar capturas sin explicación.
    • No demostrar el funcionamiento de una parte.
    • Utilizar rutas absolutas locales para las imágenes del README.md.
    • Entregar enlaces o imágenes rotos.
    • Exponer contraseñas o credenciales.
    • No respetar la estructura de la entrega.

    La ausencia de una de las tres partes impedirá considerar el proyecto completo.

    19. Lista de comprobación final del estudiante

    Antes de entregar, confirma cada punto:

    • He completado las tres partes.
    • Mi archivo principal se llama README.md.
    • He escrito las explicaciones con mis propias palabras.
    • Puedo explicar todos los comandos que aparecen.
    • He indicado mi entorno y configuración de red.
    • He incluido un diagrama Mermaid adaptado a mi instalación.
    • He realizado y documentado pruebas objetivas.
    • He añadido las ampliaciones técnicas obligatorias.
    • He documentado al menos cinco problemas o casos de diagnóstico.
    • He analizado al menos cinco aspectos de seguridad.
    • Las imágenes tienen nombres descriptivos y rutas relativas.
    • No he incluido contraseñas, claves ni datos sensibles.
    • Las referencias utilizadas aparecen citadas.
    • He comprobado el ZIP después de descomprimirlo.
    • La estructura está preparada para convertirla posteriormente en un repositorio Git.

    20. Idea clave de la actividad

    El resultado no es solo un servidor que funciona. El verdadero producto de este proyecto es una documentación técnica que demuestre qué has construido, por qué lo has configurado así, cómo sabes que funciona y cómo podría mantenerlo o reproducirlo otra pe

  • Montando un Servidor Web con Ubuntu

    Montando un Servidor Web con Ubuntu

    En este documento veremos el proceso y comandos básicos para instalar servicios en un sistema operativo Ubuntu.


    Partiremos de un Ubuntu Server al cual accederemos vía SSH.

    Tecnologías a implementar

    SERVER – HOST

    En la primera fase prepararemos el sistema para acceso remoto con seguridad baja. En la segunda fase securizaremos el servidor.

    Servicios y herramientas:

    • SSH
    • Apache2
    • PHP
    • MySQL
    • FTP
    • CMD o PuTTY para conexión SSH
    • Workbench
    • VS Code vía SSH
    • FileZilla cliente

    1. Conexión SSH

    Primero comprobamos si SSH está instalado:

    dpkg -l | grep openssh-server
    

    Si aparece openssh-server, está instalado. Si no:

    sudo apt install ssh
    

    Una vez instalado, desde Windows o PuTTY:

    ssh usuario@ipdelservidor
    

    2. Instalación de Apache2

    Instalamos Apache:

    sudo apt install apache2
    

    Esto permitirá responder a peticiones HTTP por el puerto 80.

    Si la máquina usa IP dinámica, consulta la IP con:

    ifconfig
    

    (Instalar net-tools si no lo tienes: sudo apt install net-tools)

    Al acceder desde un navegador a la IP del servidor, deberías ver la página por defecto de Apache.

    La carpeta web se encuentra en:

    /var/www/html
    

    Aquí podrás crear tus documentos HTML.


    3. Instalación de MySQL Server

    Instalamos MySQL:

    sudo apt install mysql-server
    

    Ejecutamos script de configuración:

    mysql_secure_installation
    

    Las preguntas:

    1. Set root password? → Y
    2. Remove anonymous users? → Y
    3. Disallow root login remotely? → Y
    4. Remove test database? → Y
    5. Reload privilege tables now? → Y

    Reinicia el servicio:

    sudo systemctl restart mysql
    

    Acceso:

    sudo mysql -u root -p
    

    3.1 Conexión remota a MySQL

    Debemos modificar el archivo mysqld.cnf:

    sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
    

    Busca:

    bind-address = 127.0.0.1
    

    Cámbialo por:

    0.0.0.0
    

    (Así permitimos conexiones remotas.)

    Políticas de contraseñas MySQL

    Valores: LOW = 0, MEDIUM = 1, STRONG = 2.

    Ver configuración actual:

    SHOW VARIABLES LIKE 'validate_password%';
    

    Cambiar política:

    SET GLOBAL validate_password.policy=LOW;
    

    También puedes personalizar los requisitos:

    SET GLOBAL validate_password.length = 6;
    SET GLOBAL validate_password.number_count = 0;
    

    Según queramos podemos cambiar el valor por LOW, MEDIUM o STRONG
    Ejemplos de contraseñas:

    LOW:
    12345678
    password

    MEDIUM
    Estudiante123@
    Codificador NINZA$100
    demoPass#00

    Esta es la recomendada, por defecto solicita

    • La contraseña debe tener al menos 8 caracteres.
    • El recuento de mayúsculas y minúsculas es 1 (al menos 1 letra en minúscula y 1 letra enmayúscula)
    • El recuento de números es 1
    • El número mínimo de caracteres especiales es 1

    Otra forma de cambiar la politica de contraseñas sería:

    mysql>SET GLOBAL validate_password.policy=0;
    mysql>SET GLOBAL validate_password.policy=1;
    mysql>SET GLOBAL validate_password.policy=2;

    Tambien podemos personalizar los requisitos de cada una, ejemplo:

    mysql>SET GLOBAL validate_password.length = 6;
    mysql>SET GLOBAL validate_password.number_count = 0;

    Ahora que las reglas para una contraseña válida están claras, puedes crear un usuario con
    una contraseña válida


    3.2 Creación de usuario MySql

    Crear usuario:

    CREATE USER 'user'@'127.0.0.1' IDENTIFIED BY 'Estudiante123@';
    CREATE USER 'user'@'%' IDENTIFIED BY 'Estudiante123@';
    

    Al crear el usuario ponemos entre la @ primero el nombre y luego desde donde vamos a
    permitir que se conecte. si es desde localhost, una ip determinada o cualquier sitio.

    Ejemplos:

    CREATE USER ‘user’@’127.0.0.1’ IDENTIFIED BY ‘Estudiante123@’;

    crearemos un usuario con contraseña MEDIUM y que solo se pueda conectar desde
    localhost

    CREATE USER ‘user’@’%%’ IDENTIFIED BY ‘Estudiante123@’;

    Asignar permisos:

    GRANT CREATE, ALTER, DROP, INSERT, UPDATE, DELETE, SELECT, REFERENCES, RELOAD 
    ON *.* TO 'user'@'%' WITH GRANT OPTION;
    

    Aplicar cambios:

    FLUSH PRIVILEGES;
    

    3.3 Conexión desde Workbench

    Ahora que ya tenemos configurado nuestro gestor de mysql y hemos puesto que se pueda
    acceder desde cualquier Ip, instalamos Workbench en nuestro host y nos conectamos.

    En el cliente, instala Workbench y conecta usando:

    • IP del servidor
    • Puerto 3306
    • Usuario creado
    • Contraseña asignada

    4. Instalación del servicio FTP (VSFTPD)

    Instalar:

    sudo apt install vsftpd
    

    Hacemos backup del archivo de configuración:

    sudo cp /etc/vsftpd.conf /etc/vsftpd.conf_old
    

    Editar configuración:

    sudo nano /etc/vsftpd.conf
    

    Pegar:

    listen=NO
    listen_ipv6=YES
    anonymous_enable=NO
    local_enable=YES
    write_enable=YES
    local_umask=022
    dirmessage_enable=YES
    use_localtime=YES
    xferlog_enable=YES
    connect_from_port_20=YES
    chroot_local_user=YES
    secure_chroot_dir=/var/run/vsftpd/empty
    pam_service_name=vsftpd
    rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
    rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
    ssl_enable=NO
    pasv_enable=YES
    pasv_min_port=10000
    pasv_max_port=10100
    allow_writeable_chroot=YES
    

    Como hemos realizado una copia de seguridad podemos borrar su contenido, otro truco
    para muchos archivos de configuración en linux es comentar las lineas anteriores con #, o
    simplemente poner la nueva configuración al final del documento.


    *Ubuntu en algunas versiones, viene con un firewall llamado UFW. En este caso le debemos
    de decir que abra el puerto 20, 21 y los del 10000 al 10100 para su correcto funcionamiento

    Abrir puertos en UFW:

    sudo ufw allow from any to any port 20,21,10000:10100 proto tcp
    

    Reiniciar servicio:

    sudo systemctl restart vsftpd
    

    4.1 Acceso vía FTP desde el cliente

    Para transmitir archivos via FTP al servidor podemos usar cualquier programa de
    transmisión de archivos como Filezilla-client

    Utiliza FileZilla-client y conecta usando:

    • IP del servidor
    • Usuario FTP
    • Contraseña
    • Puerto 21

    Cada usuario tendrá acceso a su carpeta.


    4.2 Acceso FTP a la carpeta web de Apache

    Dado que nuestro objetivo es montar un servidor web, debemos tener la opción de poder
    acceder a las carpetas de de apache html, para poder transmitir los archivos de una web,
    imagenes, etc.


    Existe varios modos, veamos el que considero mas sencillo para inicial. Que consiste en
    crear un usuario donde su carpeta personal sea la www de Apache2 y dar permisos a esta
    carpeta.

    Creamos un usuario cuyo directorio sea la carpeta web:

    sudo useradd -m ftpuser
    sudo passwd ftpuser
    

    *Con la opción -m indicamos que nos cree una carpeta para el usuario

    Finalmente, podemos editar el archivo /etc/passwd para cambiar la carpeta al que el usuario
    tendrá acceso.

    sudo nano /etc/passwd   ← Cambia el directorio del usuario.
    

    También podrías jugar con los grupos de usuarios en Linux, para dar acceso a diferentes
    usuarios, algunos comandos útiles que podrías repasar podrían ser:

    Modificar grupos/permisos:

    sudo chgrp -R ftpuser www
    sudo groupadd grupo
    sudo adduser usuario grupo
    sudo chmod -R 775 www
    

    5. Instalación del intérprete PHP

    Instalamos PHP y módulos:

    sudo apt install php libapache2-mod-php php-mysql php-cli
    

    php: el propio interprete, si queremos una versión especifica podriamos poner php8.1, php7,
    etc.


    libapache2-mod-php: Libreria que permite trabajar a apache2 con php (Imprescindible en
    nuestro caso)

    php-mysql: Libreria que permite hacer conexiones desde php a mysql (Imprescindible si
    hacemos app con acceso a bases de datos).

    php-cli: Aunque para un servidor web no es necesario, si es util para ejecutar scripts de php
    directamente en la terminal, para temas de mantenimiento, tareas crontab, envio de
    mensajes, etc.

    Una vez instalado puede comprobar la versión instalada con:

    php -v
    

    Crear archivo de prueba:

    sudo nano /var/www/html/version.php
    

    Contenido:

    <?php
    phpinfo();
    ?>
    

    Dar permisos:

    sudo chmod 775 version.php
    

    Probar desde el navegador: http://IP/version.php


    Ejecución PHP desde terminal

    Crear archivo:

    sudo nano infosys.php
    

    Contenido:

    <?php 
    $os = php_uname(); 
    $cpu = shell_exec('cat /proc/cpuinfo | grep "model name" | head -n 1'); 
    $memTotal = shell_exec('cat /proc/meminfo | grep MemTotal'); 
    $memFree = shell_exec('cat /proc/meminfo | grep MemFree'); 
    $disk = shell_exec('df -h'); 
    
    echo "Información del Sistema:\n";
    echo "Sistema Operativo: $os\n";
    echo "Procesador: $cpu\n"; 
    echo "Memoria Total: $memTotal"; 
    echo "Memoria Libre: $memFree\n"; 
    echo "Espacio en Disco:\n$disk\n"; 
    ?>
    

    Ejecutar:

    php infosys.php
    

    6. Acceso por SSH desde un IDE – Visual Studio Code

    Instalar VSCode: https://code.visualstudio.com/Download

    Instalar extensión: Remote – SSH

    Crear conexión:

    1. Clic en icono de conexión remota.
    2. Add New SSH Host.
    3. Indicar un nombre sin espacios.
    4. Elegir dónde guardar el archivo de configuración.
    5. Indicar sistema operativo remoto (Linux).
    6. Escribir parámetros:
    Host Mi_conexion
      HostName 192.168.x.x
      User ubuntu
    

    Una vez guardado, podrás acceder desde VS Code, abrir carpetas del servidor y usar la terminal integrada.

  • UFW- Securizando  servicios de servidor WEB

    UFW- Securizando servicios de servidor WEB

    Configuración del Firewall en linux UFW

    Mediante el comando ufw podemos configurar el firewall de Linux de forma sencilla. Lo primero que debemos de hacer es ver si esta activo o no.

    sudo ufw status

    Esto nos mostrará la lista de puertos, o en su defecto si esta inactivo. El hecho de estar inactivo supone que tenemos todos los puertos abiertos, lo que es una seria vulnerabilidad.
    ![[Snag_5bd2428.png]]
    Para activarlo, escribimos:

    sudo ufw enable

    NOTA: Debemos tener en cuenta que si estamos conectados vía SSH por el puerto 22, al activar el firewall puede ser que nos expulse, si anteriormente no hemos abierto el puerto.

    Ahora podemos poner, sudo ufw status y nos retornara la configuración actual.

    ![[Snag_5c08db1.png]]
    En este caso, vemos que ya tenemos varios puertos abiertos dado que hemos instalado diferentes servicios.

    Lista de puertos comunes.
    Algunos de los puertos más importantes de los sistemas Linux suelen estar activados por defecto, aunque en algunos casos esto no se da. Hay que tener en cuenta que mantener SSH en el puerto 22 es considerado un riesgo a nivel de seguridad, por lo que se recomienda cambiarlo.

    | Puertos comunes |

    21 > FTP
    22 > SSH
    23 > SFTP
    25 > SMTP
    43 > WHOIS
    53 > Nameservers (sistema DNS)
    80 > HTTP (servidor web, ya sea Apache, Nginx u otro)
    110 > Protocolo POP utilizado para mail.
    111 > rpcbind
    143 > Protocolo IMAP utilizado para mail.
    443 > HTTP seguro (utilizado por certificados SSL a nivel web, https://)
    953 > rndc
    993 > IMAP bajo SSL
    995 > Protocolo POP con SSL
     
    2082 > Panel cPanel
    2083 > cPanel con SSL
    2086 > Panel WHM
    2087 > WHM con SSL
    2095 > Webmail
    2096 > Webmail con SSL
     
    3306 > MySQL
    4643 > Virtuosso
    9999 > Urchin
     
    Panel Plesk > 8443
    Panel DirectAdmin > 2222
    Panel Webmin > 10000 |
    Veamos ahora como abrir o cerrar los puertos según las necesidades de cada servidor.

    Una forma sencilla es indicar directamente el nombre del servicio utilizando la opción de allow.

    sudo ufw allow ssh

    Sin embargo, podemos escribir la regla equivalente especificando el puerto en vez del nombre del servicio. Por ejemplo, este comando funciona como el anterior:

    sudo ufw allow 22

    Si deseamos ver algo mas de información del estado de los puertos, podemos poner

    sudo ufw status verbose

    Otra opción si deseamos habilitar varios puertos que estan consecutivos, podemos indicar el rango.

    sudo ufw allow 6000:6007 /tcp
    sudo ufw allow 6000:6007 /udp

    Esto abriría los puertos del 6000 al 6007

    Cerrar puertos.

    Si deseamos cerrar un puerto que tengamos abierto, podemos cerrarlo con.

    sudo ufw deny 80 

    Esto cerraría el puerto 80 de http evitando conexiones al servidor.

    Habilitar o cerrar puertos con orígenes definidos.

    En ocasiones para mayor seguridad queremos abrir los puertos, pero solo para acceder desde una dirección ip concreta, esto lo realizaremos añadiendo la opción from

      sudo ufw allow from 03.0.113.4

    De este modo solo daremos acceso al equipo con la ip designada. Aunque lo mas común es determinar el o los puertos concretos que queremos que pueda acceder.

     Por ejemplo, si desea permitir que 203.0.113.4 se conecte al puerto 22 (SSH), utilice este comando:

    sudo ufw allow from 203.0.113.4 to any port 22

    Por último si estamos en una infraestructura con diferentes subredes, podemos determinar cual de ellas pueden acceder o no. Por ejemplo una subred para un departamento de una empresa en concreto.

    sudo ufw allow from 203.0.113.0/24

    o si queremos especificar el puerto

    sudo ufw allow from 203.0.113.0/24 to any port 22

    Por numero de regla

    Si utiliza el número de regla para eliminar reglas de firewall, lo primero que le convendrá hacer es obtener una lista de reglas de firewall. El comando “UFW status” tiene una opción para mostrar números junto a cada regla, como se muestra aquí:

    sudo ufw status numbered
    Numbered Output:Status: active
    
         To                         Action      From
         --                         ------      ----
    [ 1] 22                         ALLOW IN    15.15.15.0/24
    [ 2] 80                         ALLOW IN    Anywhere

    Si queremos eliminar la regla 2, que permite las conexiones del puerto 80 (HTTP), podemos especificarlo en un comando “UFW delete”

    sudo ufw delete 2

    Otra forma es hacerlo sin numerar poniendo directamente el servicio a borrar o el numero de puerto. Por ejemplo: desea eliminar la regla allow http, podría escribir lo siguiente:

    sudo ufw delete allow http

    También podría especificar la regla mediante allow 80 en vez de hacerlo por nombre de servicio:

    sudo ufw delete allow 80

    Otros comandos útiles pueden ser:

    Si decide que no desea utilizar UFW, puede desactivarlo con este comando:

    sudo ufw disable

    Si ya configuró reglas de UFW y decide que desea empezar de nuevo, puede utilizar el comando “reset”:

    sudo ufw reset
  • .htaccess EN APACHE (Control, Seguridad y SEO)

    .htaccess EN APACHE (Control, Seguridad y SEO)

    El objetivo de esta práctica es aprender a utilizar archivos .htaccess en un servidor Apache para configurar:

    • Autenticación
    • Gestión de errores
    • Redirecciones
    • Reescritura de URLs
    • Cabeceras de seguridad
    • Control de indexación en buscadores
    • Ocultación y restricción de carpetas
    • Optimización mediante caché y compresión

    Se realizará de forma práctica para observar los efectos directamente.


    Requisitos

    • Apache instalado y funcionando
    • Permisos para editar archivos en /var/www/html/ o carpeta equivalente

    Parte 1: Activación de .htaccess en Apache

    1. Editar el VirtualHost y localizar:
    <Directory /var/www/html>
       AllowOverride None
       Require all granted
    </Directory>
    
    1. Cambiar None por All:
    AllowOverride All
    
    1. Reiniciar Apache:
    sudo systemctl restart apache2
    
    1. Crear un archivo /var/www/html/.htaccess con este contenido:
    AddDefaultCharset UTF-8
    

    Si no hay errores, el .htaccess está funcionando.

    Para editar el VirtualHost típico en Ubuntu/Debian:

    1. Abrir el archivo de sitio por defecto:
    sudo nano /etc/apache2/sites-available/000-default.conf
    
    1. Buscar un bloque <VirtualHost *:80> que contiene algo como:
    <VirtualHost *:80>
        DocumentRoot /var/www/html
        ...
        <Directory /var/www/html>
            Options Indexes FollowSymLinks
            AllowOverride None
            Require all granted
        </Directory>
    </VirtualHost>
    
    1. Aquí vive la línea “AllowOverride” que decide si .htaccess es un ciudadano con derechos o un fantasma ignorado. Cambiar AllowOverride None por AllowOverride All.
    2. Guardar, cerrar y reiniciar Apache:
    sudo systemctl restart apache2
    

    Parte 2: Autenticación Básica con .htaccess

    1. Crear una carpeta /var/www/html/admin/ con un index.html.
    2. Crear /var/www/html/.htpasswd generando un usuario:
    htpasswd -c /var/www/html/.htpasswd admin
    
    1. Crear /var/www/html/admin/.htaccess:
    AuthType Basic
    AuthName "Zona restringida"
    AuthUserFile /var/www/html/.htpasswd
    Require valid-user
    

    Entrar a http://servidor/admin y probar el acceso.

    htpasswd

    htpasswd es una pequeña herramienta de Apache que fabrica archivos de credenciales para la autenticación HTTP básica. Básica significa sin florituras: usuario/contraseña codificados en Base64 y enviados en cabecera; útil para poner una puerta rápida delante de una carpeta, una página de administración o un endpoint casero.

    Funciona generando un fichero (normalmente .htpasswd) con uno o varios usuarios y sus contraseñas hash. Este fichero luego lo consumes desde .htaccess o desde la configuración del VirtualHost.

    1. Abres la terminal en tu servidor.
    2. Ejecutas:
    htpasswd -c /ruta/al/fichero/.htpasswd nombreusuario
    

    El -c crea el fichero. Si ya existe y quieres añadir otro usuario, lo omites:

    htpasswd /ruta/al/fichero/.htpasswd otro_usuario
    

    Al ejecutar, te pedirá contraseña y te la meterá en el fichero con hash. El algoritmo por defecto suele ser bcrypt/MD5 APR según versión; lo importante es que nunca guarda contraseñas en claro.

    Un .htpasswd típico se ve así:

    juan:$apr1$9tDRSv/.v8BxP1kF/Np7A.
    maria:$apr1$OQy4dRxr$2aCdBORded8HNoo.t2GxU.
    

    Luego en .htaccess pones la compuerta:

    AuthType Basic
    AuthName "Zona restringida"
    AuthUserFile /ruta/al/fichero/.htpasswd
    Require valid-user
    

    El navegador, al entrar en esa carpeta, lanzará un cuadro de login del siglo pasado (que sigue cumpliendo su función). En HTTPS está bien para control de acceso simple; en HTTP es como mandar postales sin sobre.

    Parte 3: Gestión de Errores Personalizados

    1. Crear 404.html y 403.html en la raíz.
    2. Añadir en /var/www/html/.htaccess:
    ErrorDocument 404 /404.html
    ErrorDocument 403 /403.html
    
    1. Probar introduciendo una URL inexistente.

    Parte 4: Cabeceras de Seguridad

    Añadir en /var/www/html/.htaccess:

    Header set X-Frame-Options "DENY"
    Header set X-Content-Type-Options "nosniff"
    Header set X-XSS-Protection "1; mode=block"
    Header set Referrer-Policy "no-referrer-when-downgrade"
    Header set Permissions-Policy "geolocation=()"
    

    Explicación breve:

    • X-Frame-Options: DENY Esta prohíbe que tu página se cargue dentro de un <iframe> de otra página. ¿Para qué sirve? Para evitar el clickjacking, un truco donde otra web maliciosa mete la tuya en un iframe invisible y coloca botones encima, de manera que el usuario cree estar haciendo una cosa y está pulsando otra. Con DENY, el navegador dice “no me meto en iframes de nadie” y así se acaba el truco de magia.
    • X-Content-Type-Options: nosniff Los navegadores suelen ser listillos: si reciben un archivo con un tipo incorrecto, intentan adivinarlo (“sniffing MIME”). Eso abre una puerta curiosa: si subes un .png que en realidad es JavaScript con una cabecera errónea, algunos navegadores podrían intentar ejecutarlo. Con nosniff el navegador promete no “oler” el tipo y usar sólo lo declarado. Evita ciertos vectores de XSS y descarga ejecutable camuflada.
    • X-XSS-Protection: 1; mode=block Esto es un modo antiguo del filtro anti-XSS integrado en algunos navegadores. Le indica al navegador que si detecta un ataque de Cross-Site Scripting reflejado, bloquee la carga de la página en vez de intentar sanearla. Hoy en día está un poco de capa caída (Chrome lo retiró en favor de Content-Security-Policy) pero en entornos legacy todavía es un salvavidas aceptable.
    • Referrer-Policy: no-referrer-when-downgrade Cada vez que pulsas un enlace, el navegador suele enviar una cabecera Referer (sin la segunda “r”, por herencia histórica) indicando desde qué página vienes. Esa miguita de pan puede revelar urls privadas, parámetros de sesión o rutas internas. no-referrer-when-downgrade ordena no enviar el Referer cuando pasas de HTTPS a HTTP (es decir, no “degradar” seguridad). Existen políticas más estrictas (strict-origin, no-referrer, etc.), pero esta ya reduce filtraciones triviales.
    • Permissions-Policy: geolocation=() Aquí entramos en una política moderna que controla APIs del navegador. Es como darle a tu web un panel de permisos: cámara, micrófono, geolocalización, sensores… geolocation=() significa “no concedo geolocalización a nadie, ni siquiera a mí”. Puedes ser más granular, por ejemplo geolocation=(self) permitiría sólo a tu propio dominio. Eso reduce el “exceso de curiosidad” del navegador y de scripts de terceros.
    • El resumen conceptual es que no protegen tu código del mal, sino que recortan la superficie de comportamiento del navegador, reduciendo trucos clásicos: iframes invisibles, tipos MIME engañosos, ejecución de scripts inesperados y filtración de metadatos. Es parecido a darle menos herramientas a un niño travieso: no podrá arreglar un coche, pero tampoco desmontar la casa.

    Más allá de estas cabeceras existen otras piezas más finas como Content-Security-Policy (CSP), que es una gramática entera para decir “qué scripts, imágenes, estilos y conexiones están permitidos”. CSP convierte el navegador en una especie de sandbox configurable, y ahí es donde el mundo del XSS moderno se vuelve deporte olímpico.

    Parte 5: Redirecciones HTTP

    1. Redirección permanente (301):
    Redirect 301 /viejo.html /nuevo.html
    
    1. Temporal (302):
    Redirect 302 /promo /promo-2026
    

    Recomendación: usar 301 solo cuando sea definitivo.

    Cuando haces una redirección 302 (Found / Moved Temporarily) estás diciendo dos cosas:

    — Primero: “el recurso sigue existiendo en la URL original, pero por ahora estoy sirviendo desde otra URL”.

    — Segundo: “no actualices tus mapas, no caches esto como definitivo”.

    Consecuencias prácticas:

    1. Los navegadores no la memorizan como algo fijo.
      No guardan en disco que la URL ha cambiado. Si mañana quitas la redirección, el navegador volverá a pedir la original sin pelearse contigo. Es como poner un cartel de “pasen por la puerta lateral mientras pintamos la principal”.
    2. Los buscadores no transfieren ‘peso’ SEO.
      A diferencia de un 301, Google y compañía no asumen que la URL nueva es la buena. Mantienen la original en sus índices. Es la forma de decirles: “no reorganices tu mapa, solo estoy haciendo obras”.
    3. No cambia los enlaces de terceros.
      Si un usuario sigue un enlace desde otra web, la redirección lo mueve, pero esa web no actualizará su enlace, porque no hay garantía de permanencia.
    4. Sirve para pruebas y mantenimiento.
      Si estás desplegando un nuevo diseño, probando un AB testing o moviendo tráfico durante un rato, una 302 te da una especie de reversibilidad instantánea.

    En contraste, un 301 (Moved Permanently) es como una mudanza registrada en el ayuntamiento: los navegadores pueden cachearla, los buscadores actualizan índices y pasan “autoridad” a la nueva URL, y los cambios tardan más en revertirse porque todos asumen que era definitivo.

    Lo temporal no cambia la cartografía del navegador ni del buscador, solo redirige el tráfico en tiempo real. Es útil cuando estás probando algo, cuando tienes dudas o cuando quieres mantener la puerta original como referencia verdadera. Luego, cuando estés seguro de la mudanza, ya haces el 301 y los mapas del mundo cambian de sitio.

    Parte 6: Reescritura de URLs con mod_rewrite

    La reescritura de URLs permite transformar una URL solicitada por el navegador en otra diferente de forma interna, sin que el usuario lo note. Se utiliza para crear URLs más limpias, eliminar extensiones (.php, .html) o implementar un patrón MVC (Front Controller).


    6.1 Activación del módulo

    Activar el módulo responsable de la reescritura:

    sudo a2enmod rewrite
    sudo systemctl restart apache2
    

    Sin este módulo, las reglas de reescritura no funcionarán.


    6.2 Requisito en el VirtualHost

    Dentro del VirtualHost debe estar permitido el uso de .htaccess. En el bloque <Directory> debe existir:

    AllowOverride All
    

    Si estuviera en None, Apache ignorará las reglas del .htaccess.


    6.3 Ejemplo simple: eliminar extensión

    Crear un archivo hola.html en el DocumentRoot (/var/www/html/).

    Crear o editar el .htaccess en el mismo directorio con:

    RewriteEngine On
    RewriteRule ^hola$ hola.html [L]
    

    • RewriteEngine On → activa el motor de reescritura
    • RewriteRule ^hola$ hola.html → si se solicita /hola, entregar hola.html
    • [L] → indica que esta es la última regla si coincide

    Prueba

    Acceder en el navegador:

    http://servidor/hola
    

    Aunque el archivo real sea hola.html, el navegador verá una URL sin extensión.


    6.4 Ejemplo avanzado: patrón MVC (Front Controller)

    Este patrón es común en frameworks y sitios dinámicos. La idea es que todas las peticiones que no sean archivos ni carpetas reales se envían a index.php.

    6.4.1 Código

    En el .htaccess del DocumentRoot:

    RewriteEngine On
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.+)$ index.php?route=$1 [L,QSA]
    

    6.4.2 Explicación de las condiciones

    • RewriteCond %{REQUEST_FILENAME} !-f
      → si lo solicitado no es un archivo físico
    • RewriteCond %{REQUEST_FILENAME} !-d
      → si lo solicitado no es un directorio

    6.4.3 Explicación de la regla

    • ^(.+)$ → coincide con cualquier ruta solicitada
    • index.php?route=$1 → envía la ruta al script index.php mediante el parámetro route
    • [L,QSA]:
      • L → última regla si coincide
      • QSA → preserva parámetros existentes (?id=3 etc.)

    6.5 Demostración práctica

    Crear un archivo index.php con:

    <?php
    echo "Ruta solicitada: " . ($_GET['route'] ?? 'ninguna');
    ?>
    

    Acceder desde el navegador a distintas rutas:

    http://servidor/productos
    http://servidor/usuarios/editar/7
    http://servidor/pepito
    

    Salida esperada:

    Ruta solicitada: productos
    Ruta solicitada: usuarios/editar/7
    Ruta solicitada: pepito
    

    Esto confirma que index.php captura todas las rutas y puede decidir qué controlador o vista cargar.


    6.6 Caso especial: archivos reales

    Si se accede a:

    /style.css
    /logo.png
    /index.php
    

    o cualquier recurso físico, NO pasa por la reescritura porque las condiciones lo impiden:

    RewriteCond %{REQUEST_FILENAME} !-f   → archivo físico
    RewriteCond %{REQUEST_FILENAME} !-d   → directorio físico
    

    De esta forma no se rompe el funcionamiento del sitio.


    6.7 Uso habitual en aplicaciones web

    Este sistema se utiliza para:

    • URLs amigables para SEO
    • Frameworks PHP (Laravel, Symfony, CodeIgniter)
    • Paneles de administración
    • APIs REST
    • Front Controllers (único punto de entrada)

    En lugar de:

    index.php?route=usuarios/listar
    

    se obtiene:

    /usuarios/listar
    

    más limpio y apto para buscadores.

    La reescritura de URLs no cambia el archivo real que se ejecuta, solo traduce internamente la ruta.
    El usuario ve una URL limpia y el servidor recibe una ruta estructurada para procesar.

    Parte 7: Control del Listado de Directorios

    Para evitar que se muestren archivos:

    Options -Indexes
    

    Crear una carpeta sin index.html y comprobar el resultado.


    Parte 8: Forzar HTTPS

    Añadir:

    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    

    Requiere certificado SSL configurado.


    Parte 9: Cacheo y Compresión

    Cache de archivos (si mod_expires activado):

    <IfModule mod_expires.c>
       ExpiresActive On
       ExpiresByType image/jpeg "access plus 30 days"
       ExpiresByType text/css "access plus 7 days"
       ExpiresByType application/javascript "access plus 7 days"
    </IfModule>
    

    Compresión (si mod_deflate activado):

    SetOutputFilter DEFLATE
    

    Cuando decíamos “cache de archivos (si mod_expires activado)” nos referíamos a una función del servidor web Apache diseñada para decirle al navegador cuánto tiempo puede guardar ciertos archivos sin volver a descargarlos.

    En castellano llano:

    La caché es la costumbre del navegador de guardar copias locales de cosas que ya descargó (como imágenes, CSS o JavaScript) para no pedirlas de nuevo al servidor cada vez que visitas la página. Si ya tienes el logo en tu disco, ¿para qué volver a bajarlo?

    El módulo mod_expires es una parte de Apache que permite controlar cuánto dura esa copia local, poniendo un “fecha de caducidad” en las respuestas.

    Si lo activas y configurás reglas como:

    ExpiresByType image/png "access plus 30 days"
    

    Estás diciendo: “los archivos PNG pueden vivir 30 días en la caché del navegador”.

    ¿Resultado práctico? La primera visita carga todo desde el servidor, las siguientes cargan desde disco; la web vuela y el servidor descansa.

    Esencialmente, es un acuerdo temporal entre servidor y navegador, parecido a:

    – Servidor: “Este archivo apenas cambia, guárdalo un mes”.
    – Navegador: “Perfecto, no te molesto hasta que pase ese mes”.

    En el ecosistema web, la caché es una de las razones por las que las páginas parecen “instantáneas” después de la primera visita, y una forma elegante de reducir gasto de CPU, ancho de banda y tiempo de espera. Sin caché, cada visita sería como entrar por primera vez en un supermercado cada día: todo el mundo preguntando todo el rato dónde están los pasillos.

    Parte 10: Interacción con Buscadores (SEO y Indexación)

    robots.txt

    Crear en raíz del sitio:

    User-agent: *
    Disallow: /admin/
    Disallow: /backup/
    

    Nota: los bots maliciosos pueden ignorarlo.

    Evitar indexación con HTTP (X-Robots-Tag)

    En .htaccess:

    Header set X-Robots-Tag "noindex, nofollow"
    

    Usos habituales:

    • PDFs
    • Paneles internos
    • Carpetas privadas

    Bloquear bots por User-Agent

    Ejemplo:

    RewriteEngine On
    RewriteCond %{HTTP_USER_AGENT} googlebot [NC]
    RewriteRule ^ - [R=403]
    

    Parte 11: Ocultación y Restricción de Carpetas

    Impedir acceso web a una carpeta:

    Dentro de la carpeta crear .htaccess:

    Require all denied
    

    O por archivo:

    <FilesMatch "\.(sql|bak|zip|tar)$">
       Require all denied
    </FilesMatch>
    

    Restringir por IP:

    Require ip 192.168.1.0/24
    

    Evitar ejecución de PHP en carpetas de subida:

    <FilesMatch "\.(php|phtml)$">
       Require all denied
    </FilesMatch>
    

    Muy útil en uploads/ o storage/.


    Con .htaccess es posible:

    • Restringir acceso
    • Personalizar errores
    • Crear URLs amigables
    • Controlar bot y rastreadores
    • Proteger información sensible
    • Forzar HTTPS
    • Mejorar SEO
    • Mejorar rendimiento

    Advertencia para producción:

    • .htaccess se evalúa en cada petición
    • Incrementa carga del servidor
    • En grandes entornos se recomienda configurar desde VirtualHost

  • ¿Qué hace systemctl?

    ¿Qué hace systemctl?

    Un servicio es un proceso de fondo (daemon) que se ejecuta sin cliente directo: servidor web, base de datos, cupón/leche… cosas que viven en silencio.

    systemd organiza los servicios como units (unidades). Una unit puede ser:

    • service → servicios
    • timer → programadores sustitutos del cron
    • mount → puntos de montaje
    • socket → servicios socket-activados
    • y más fauna, pero hoy nos interesa el zoológico *.service.

    ¿Qué hace systemctl?

    systemctl permite:

    • Iniciar/detener un servicio.
    • Habilitarlo o deshabilitarlo en arranque.
    • Ver logs y estado.
    • Ver dependencias.

    Su sintaxis general:

    systemctl <acción> <unidad>

    Ejemplo:

    systemctl start apache2.service

    Ver servicios instalados

    Esto ayuda a explorar el sistema:

    Servicios activos ahora mismo:

    
    
    
    
    
    systemctl list-units --type=service --state=running
    

    Todos los servicios cargados (activos + inactivos):

    
    
    
    
    
    systemctl list-units --type=service
    

    Servicios instalados en el sistema (cargados y no cargados):

    
    
    
    
    
    systemctl list-unit-files --type=service
    

    Estado de un servicio

    Es la acción más frecuente.

    
    
    
    
    
    systemctl status apache2.service
    

    Muestra:

    • PID
    • Logs recientes
    • “Loaded” (si está instalado)
    • “Active” (si está corriendo)

    La magia aquí es que systemd integra parte del journal, así que ya da contexto.


    Iniciar / Detener / Reiniciar

    Aquí es donde la clase empieza a levantar humo.

    Iniciar servicio:

    
    
    
    
    
    sudo systemctl start apache2.service
    

    Detener:

    
    
    
    
    
    sudo systemctl stop apache2.service
    

    Reiniciar de forma limpia:

    
    
    
    
    
    sudo systemctl restart apache2.service
    

    Recargar configuración sin detener el servicio (si lo soporta, como Nginx):

    
    
    
    
    
    sudo systemctl reload nginx.service
    

    Para puristas: restart tira y relanza, reload solo recarga configuración.


    Habilitar en el arranque

    Esto conecta systemd con los “targets” (equivalentes modernos de runlevels).

    Habilitar:

    
    
    
    
    
    sudo systemctl enable apache2.service
    

    Deshabilitar:

    
    
    
    
    
    sudo systemctl disable apache2.service
    

    Comprobar si está habilitado:

    
    
    
    
    
    systemctl is-enabled apache2.service
    

    Esto crea o elimina enlaces simbólicos en /etc/systemd/system/.


    Ver logs de un servicio

    journalctl es el diario íntimo del sistema. Útil para debugging y para descubrir que olvidaste escapar ese símbolo en la config de Postfix.

    Logs recientes del servicio:

    
    
    
    
    
    journalctl -u apache2.service
    

    Logs en tiempo real (“modo Matrix”):

    
    
    
    
    
    journalctl -u apache2.service -f
    

    Logs de hoy con timestamps:

    
    
    
    
    
    journalctl -u apache2.service --since today
    

  • Pildora – Panel de control SSH

    Pildora – Panel de control SSH

    1. Glances — El “panel de control” más completo dentro de la terminal

    https://i.ytimg.com/vi/ZwhyLD-wquk/maxresdefault.jpg?utm_source=chatgpt.com
    https://glances.readthedocs.io/en/latest/_images/screenshot-wide.png?utm_source=chatgpt.com

    Instalas, entras por SSH y pam, un dashboard con CPU, RAM, red, procesos, temperaturas… todo dinámico.

    Instalación:

    sudo apt install glances
    glances
    

    Sirve incluso como “panel web” si lo lanzas en modo servidor:

    glances -w
    

    Luego entras desde navegador:
    http://IP:61208


    2. Ytop / Bpytop / Btop — Interfaces brutales

    https://www.both.org/wp-content/uploads/2025/02/btop-08.png?utm_source=chatgpt.com
    https://itsfoss.com/content/images/2025/06/btop-catppuccin-theme.png?utm_source=chatgpt.com
    https://www.tecmint.com/wp-content/uploads/2020/11/Bpytop-Linux-Resource-Monitor-Tool.png?utm_source=chatgpt.com

    Son dashboards animados con gráficas alucinantes.

    Instalación:

    sudo apt install btop
    btop
    

    Experiencia pura de “panel local pero en SSH”.


    3. Ncdu — Panel visual para navegar disco

    https://static.linuxblog.io/wp-content/uploads/2023/11/ncdu-linux.png?utm_source=chatgpt.com
    https://opensource.com/sites/default/files/ncdu-dark.jpg?utm_source=chatgpt.com

    Ver qué ocupa espacio, borrar, entrar en carpetas… todo navegable.

    sudo apt install ncdu
    ncdu /
    

    4. Lazydocker — Un Portainer en la terminal

    https://terminalroot.com/assets/img/docker/lazydocker.jpg?utm_source=chatgpt.com
    https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5As2oxuEBalTJiEDlhbgNdsx_6LuLmKexgePTUNE8veOLWlh_iNJtidR2Opy3dvWHrGSnBKLxGhwwLgMCDygf9nFaedxLJ7TvBaFweyz9BmU_hRmNZkpxbGZZSWxrRPQ_EO6qjON8tzA/w1200-h630-p-k-no-nu/lazydocker-screenshot.png?utm_source=chatgpt.com

    Si tienes Docker, este es tu panel completo: ver contenedores, logs, stats, reiniciar, eliminar…

    Instalación:

    curl https://raw.githubusercontent.com/jesseduffield/lazydocker/master/scripts/install_update_linux.sh | bash
    lazydocker
    
    
    source ~/.profile
    
    lazydocker


    5. Cockpit (si ya quieres panel web pero gestionado desde SSH)

    https://cockpit-project.org/images/mobilenav-desktop.png?utm_source=chatgpt.com
    https://opensource.com/sites/default/files/uploads/cockpitdashboard.png?utm_source=chatgpt.com

    No es TUI, pero sí un panel web completísimo que se instala por SSH en 30 segundos.

    sudo apt install cockpit
    sudo systemctl enable --now cockpit
    

    Luego entras:
    https://IP:9090


    6. Nmon — Monitor clásico pero potente

    sudo apt install nmon
    nmon
    

    Interfaz retro, pero muy útil para rendimiento.


    EL PANEL “ECORP CONTROL NODE” – estilo Mr. Robot

    Formato TUI, aparece automáticamente al iniciar sesión SSH.


    1. ASCII ART del servidor (para la entrada dramática)

    Pon esto en:
    /etc/motd (o lo generamos desde el script).

         __  ____                ____        _           __ 
        /  |/  (_)___ ____ _    / __ \____  (_)___  ____/ /_
       / /|_/ / / __ `/ _ `/   / /_/ / __ \/ / __ \/ __  / /
      / /  / / / /_/ /  __/   / ____/ /_/ / / / / / /_/ / / 
     /_/  /_/_/\__, /\___/   /_/    \____/_/_/ /_/\__,_/_/  
              /____/             C Y B E R  N O D E           
    

    2. Script principal del panel (dashboard)

    Guárdalo en:
    /usr/local/bin/panel-mrrobot

    Dale permisos:
    sudo chmod +x /usr/local/bin/panel-mrrobot

    Contenido:

    #!/bin/bash
    
    # =============== ASCII HEADER ===============
    clear
    echo "
      ███╗   ███╗██████╗     ██████╗  ██████╗ ██████╗ ██╗   ██╗
      ████╗ ████║██╔══██╗    ██╔══██╗██╔═══██╗██╔══██╗╚██╗ ██╔╝
      ██╔████╔██║██████╔╝    ██║  ██║██║   ██║██████╔╝ ╚████╔╝ 
      ██║╚██╔╝██║██╔══██╗    ██║  ██║██║   ██║██╔═══╝   ╚██╔╝  
      ██║ ╚═╝ ██║██║  ██║    ██████╔╝╚██████╔╝██║        ██║   
      ╚═╝     ╚═╝╚═╝  ╚═╝    ╚═════╝  ╚═════╝ ╚═╝        ╚═╝    
    "
    echo "                  PANEL PRIVADO - MODO MR.ROBOT"
    echo "--------------------------------------------------------------------------------"
    echo
    
    # =============== MENU ===============
    while true; do
      echo "Selecciona una opción:"
      echo "1) Monitor del sistema (btop)"
      echo "2) Dashboard avanzado (glances)"
      echo "3) Uso de disco (ncdu)"
      echo "4) Control Docker (lazydocker)"
      echo "5) Logs en vivo (journalctl -f)"
      echo "6) Escaneo rápido de puertos (nmap localhost)"
      echo "7) Conexiones activas (ss -tunap)"
      echo "8) Salir"
      echo
      read -p "Elige (1-8): " opcion
    
      case $opcion in
        1) btop ;;
        2) glances ;;
        3) sudo ncdu / ;;
        4) lazydocker ;;
        5) sudo journalctl -f ;;
        6) sudo nmap localhost ;;
        7) ss -tunap ;;
        8) exit 0 ;;
        *) echo "Opción inválida. Intenta otra vez." ;;
      esac
    done
    

    3. Hacer que el panel aparezca AUTOMÁTICAMENTE al entrar por SSH

    Edita tu .bashrc del usuario:

    nano ~/.bashrc
    

    Añade al final:

    # Lanzar panel automáticamente en sesión SSH interactiva
    if [ -n "$SSH_CONNECTION" ]; then
        /usr/local/bin/panel-mrrobot
    fi
    

    Guarda, cierra y reconecta por SSH.

    Cuando entres, verás:

    • ASCII art potente
    • Menú visual
    • Acceso rápido a monitorización
    • Logs en vivo
    • Herramientas estilo hacker

    Una consola viva.

  • Conexión SSH segura en Ubuntu

    Conexión SSH segura en Ubuntu

    En el servidor (Ubuntu Server)

    Comprueba que SSH está activo:

    sudo systemctl status ssh

    Si no estuviera activo:

    sudo systemctl enable --now ssh

    Averigua la IP del servidor:

    ip a

    Quédate con algo como 192.168.1.50.

    En el cliente

    • Si el alumno está en Linux/macOS: ya tiene ssh.
    • Si está en Windows: puede usar PowerShell (trae ssh) o Windows Terminal.

    1) Primera conexión “normal” (para ver que funciona)

    En el cliente, conecta:

    ssh usuario@192.168.1.50

    Ejemplo:

    ssh alumno@192.168.1.50

    La primera vez saldrá el aviso de huella:

    • Are you sure you want to continue connecting (yes/no/[fingerprint])?

    Escribe:

    yes

    Mete la contraseña del usuario.

    ✅ Resultado esperado: entras y ves el prompt del servidor.


    2) Crear usuario “de trabajo” y evitar usar root

    En el servidor, crea un usuario nuevo (si no existe):

    sudo adduser operario

    Dale permisos de administración (sudo):

    sudo usermod -aG sudo operario

    Prueba desde el cliente entrar con ese usuario:

    ssh operario@192.168.1.50

    ✅ Objetivo: que el alumno use siempre un usuario normal + sudo, no root.


    3) Generar claves SSH (cliente) y copiarlas (servidor)

    3.1 Generar clave en el CLIENTE

    En el cliente:

    ssh-keygen -t ed25519 -C "operario@lab"

    Cuando pregunte dónde guardarla, ENTER.
    Cuando pregunte passphrase, pon una (recomendado). Ejemplo: ClaveMuySecreta123!

    Esto crea:

    • ~/.ssh/id_ed25519 (privada, NO se comparte)
    • ~/.ssh/id_ed25519.pub (pública, sí se comparte)

    3.2 Copiar clave pública al SERVIDOR

    Desde el cliente:

    ssh-copy-id operario@192.168.1.50

    Luego prueba entrar sin contraseña (solo con passphrase si la pusiste):

    ssh operario@192.168.1.50

    ✅ Resultado esperado: ya no te pide la contraseña del usuario (solo la passphrase de la clave si existe).


    4) Endurecer SSH: desactivar root y contraseñas

    Ahora viene lo serio: si alguien intenta fuerza bruta, no hay contraseña que adivinar.

    En el servidor, edita configuración:

    sudo nano /etc/ssh/sshd_config

    Busca (o añade) estas líneas:

    PermitRootLogin no
    PasswordAuthentication no
    PubkeyAuthentication yes

    Opcional (muy recomendable): restringir a un usuario concreto:

    AllowUsers operario

    Guarda y reinicia SSH:

    sudo systemctl restart ssh

    Prueba crítica (NO saltársela)

    1. Mantén una sesión SSH abierta por si la lías (salvavidas).
    2. Abre otra terminal nueva e intenta entrar:
    ssh operario@192.168.1.50

    ✅ Debe entrar con clave.
    ❌ Si pide contraseña y ya la desactivaste, es que la clave no está bien instalada.


    5) Cambiar el puerto SSH (reduce ruido automático)

    Esto no es “seguridad mágica”, pero quita miles de bots tontos.

    En el servidor:

    sudo nano /etc/ssh/sshd_config

    Cambia o añade:

    Port 2222

    Reinicia:

    sudo systemctl restart ssh

    Ahora para entrar desde cliente:

    ssh -p 2222 operario@192.168.1.50

    6) Activar firewall UFW y permitir solo SSH

    En el servidor:

    sudo ufw allow 2222/tcp
    sudo ufw enable
    sudo ufw status verbose

    ✅ Debe verse permitido el puerto 2222/tcp.


    7) Verificación y “pruebas de ataque” controladas

    7.1 Ver qué está escuchando

    Servidor:

    ss -tulpn | grep ssh

    Debería verse :2222.

    7.2 Probar que root NO entra

    Cliente:

    ssh -p 2222 root@192.168.1.50

    ✅ Debe fallar.

    7.3 Probar que contraseña NO sirve

    Cliente (forzando password):

    ssh -p 2222 -o PreferredAuthentications=password -o PubkeyAuthentication=no operario@192.168.1.50

    ✅ Debe fallar.


    8) Extras opcionales de seguridad (si te da tiempo)

    A) Desactivar acceso por usuario/contraseña en el propio sistema (no solo SSH)

    No siempre interesa en clase, pero es un plus.

    B) Fail2ban (bloquea IPs tras intentos)

    Instalar:

    sudo apt update
    sudo apt install fail2ban -y

    Comprobar:

    sudo systemctl status fail2ban

    Esto es “el portero del garito”: si alguien insiste, lo echa.

  • Activar HTTPS en Apache2 (Ubuntu Server) con certificado autofirmado

    Activar HTTPS en Apache2 (Ubuntu Server) con certificado autofirmado

    1) Activar SSL/TLS en Apache

    Apache en Ubuntu usa módulos. Para HTTPS necesitas ssl.

    sudo a2enmod ssl
    sudo systemctl restart apache2

    Comprueba que el módulo está activo:

    apache2ctl -M | grep ssl

    2) Crear un certificado autofirmado (OpenSSL)

    Vamos a crear:

    • clave privada (key)
    • certificado (crt)

    2.1 Crear carpeta para certificados (ordenadito)

    sudo mkdir -p /etc/apache2/ssl
    sudo chmod 700 /etc/apache2/ssl

    2.2 Generar clave + certificado (válido 365 días)

    Cambia TU_SERVIDOR por un nombre identificable (ej: asir-01, web-lab, o el FQDN si tenéis DNS).

    sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout /etc/apache2/ssl/TU_SERVIDOR.key \
    -out /etc/apache2/ssl/TU_SERVIDOR.crt

    Cuando pregunte por campos, lo importante es:

    • Common Name (CN): poned el nombre o la IP con la que vais a acceder.
      • Si accederéis por IP: poned la IP (ej 192.168.1.50)
      • Si accederéis por nombre: poned ese nombre (ej asir-01.local)

    Verifica que existen:

    sudo ls -l /etc/apache2/ssl/

    3) Crear un VirtualHost HTTPS (443)

    Apache en Ubuntu suele tener el sitio por defecto en /etc/apache2/sites-available/000-default.conf.

    Vamos a crear uno nuevo: https-lab.conf.

    3.1 Crear el archivo del sitio HTTPS

    sudo nano /etc/apache2/sites-available/https-lab.conf

    Pega esto (cambia TU_SERVIDOR y, si quieres, el ServerName):

    <VirtualHost *:443>
        ServerName TU_SERVIDOR
        DocumentRoot /var/www/html
    
        SSLEngine on
        SSLCertificateFile /etc/apache2/ssl/TU_SERVIDOR.crt
        SSLCertificateKeyFile /etc/apache2/ssl/TU_SERVIDOR.key
    
        ErrorLog ${APACHE_LOG_DIR}/https_error.log
        CustomLog ${APACHE_LOG_DIR}/https_access.log combined
    </VirtualHost>

    Guarda y sal.

    3.2 Habilitar el sitio y comprobar sintaxis

    sudo a2ensite https-lab.conf
    sudo apache2ctl configtest

    Si sale Syntax OK, reinicia:

    sudo systemctl reload apache2

    4) Comprobar que HTTPS funciona

    4.1 Ver que Apache escucha en 443

    sudo ss -lntp | grep ':443'

    4.2 Probar con curl (ignorando el aviso del certificado)

    Sustituye por la IP o nombre real:

    curl -kI https://192.168.1.50/

    Deberías ver algo como:

    • HTTP/1.1 200 OK (o 301/302 si rediriges)
    • cabeceras de Apache

    4.3 Probar desde navegador

    Entrad a:

    • https://IP_DEL_SERVIDOR/

    Saldrá aviso de seguridad (normal con autofirmados). La idea pedagógica: el cifrado funciona, pero el navegador no “confía” en la identidad.


    5) (Opcional) Redirigir HTTP (80) a HTTPS (443)

    Esto hace que todo lo que llegue por http:// vaya a https://.

    5.1 Activar módulo rewrite

    sudo a2enmod rewrite
    sudo systemctl reload apache2

    5.2 Editar el VirtualHost de puerto 80

    Edita el sitio por defecto (o el que uséis en 80):

    sudo nano /etc/apache2/sites-available/000-default.conf

    Dentro del <VirtualHost *:80>, añade esto antes del cierre </VirtualHost>:

    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

    Comprueba y recarga:

    sudo apache2ctl configtest
    sudo systemctl reload apache2

    Prueba:

    curl -I http://192.168.1.50/

    Debería devolver 301 Moved Permanently apuntando a https://....


    6) (Opcional) Endurecer un poco HTTPS (sin volverse loco)

    6.1 Activar HTTP/2 (si está disponible)

    sudo a2enmod http2
    sudo systemctl reload apache2

    En tu https-lab.conf, dentro del VirtualHost 443, añade:

    Protocols h2 http/1.1

    6.2 Cabeceras básicas (seguridad “visible”)

    Activa headers:

    sudo a2enmod headers
    sudo systemctl reload apache2

    Dentro del <VirtualHost *:443> añade:

    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"

    HSTS (solo si vais a usar HTTPS siempre; en lab puede dar guerra si cambiáis):

    Header always set Strict-Transport-Security "max-age=86400"

    7) Logs y troubleshooting (lo que siempre salva vidas)

    7.1 Ver errores de Apache en directo

    sudo tail -f /var/log/apache2/error.log

    7.2 Ver logs del sitio HTTPS

    sudo tail -f /var/log/apache2/https_error.log
    sudo tail -f /var/log/apache2/https_access.log

    7.3 Problemas típicos

    • No abre el 443: firewall/UFW o router/VLAN.
    • Apache no escucha en 443: revisa que ssl esté activo y que el sitio https-lab.conf esté habilitado. sudo a2query -m ssl
      sudo a2query -s https-lab
      sudo apache2ctl -S
    • Certificado no coincide (CN mal): recrea el cert con CN correcto.
    • Permisos: que Apache pueda leer el .crt y .key (en /etc/apache2/ssl suele ir bien con root y lectura adecuada; si te pasas bloqueando, falla).