Autor: ciberkaos

  • 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).

  • [Reto] – Infraestructura virtualizada con Ubuntu Server

    [Reto] – Infraestructura virtualizada con Ubuntu Server

    El objetivo de esta práctica es diseñar, instalar, configurar y documentar una pequeña infraestructura virtual compuesta por varias máquinas Ubuntu Server conectadas en red local.

    Cada máquina deberá tener una función concreta dentro del sistema y deberá relacionarse con las demás. El alumno tendrá que demostrar conocimientos de instalación de sistemas operativos, virtualización, configuración de red, instalación de servicios, administración del sistema, seguridad, automatización y documentación técnica.

    Requisitos del proyecto

    Debes crear al menos 3 máquinas virtuales Ubuntu Server con IP fija:

    • un servidor web
    • un servidor de base de datos
    • un servidor de administración o mantenimiento

    Debes realizar, como mínimo, las siguientes tareas

    • instalar Ubuntu Server en las máquinas virtuales
    • configurar la red local y las IP fijas
    • instalar y configurar Apache en el servidor web
    • instalar y configurar MySQL o MariaDB en el servidor de base de datos
    • comprobar la comunicación entre el servidor web y el de base de datos
    • administrar servicios con systemctl
    • consultar registros con journalctl
    • aplicar reglas básicas de seguridad con ufw
    • crear scripts Bash de mantenimiento
    • automatizar tareas con cron
    • documentar todo el proceso en un README técnico

    La entrega deberá incluir

    • README.md principal
    • capturas o evidencias organizadas por apartados
    • scripts utilizados
    • archivos de configuración relevantes
    • comprobaciones finales de funcionamiento

    Importante

    No se valorará únicamente que “funcione”, sino que el trabajo esté bien explicado, justificado y documentado. Cada apartado debe mostrar comandos, explicación de su uso, resultado obtenido y evidencias del funcionamiento.

    Objetivos didácticos

    Con este proyecto el alumno deberá demostrar que sabe:

    • Crear y configurar máquinas virtuales
    • Instalar Ubuntu Server
    • Asignar IP fija a cada máquina
    • Configurar red local entre máquinas
    • Instalar y administrar servicios como:
      • Apache o Nginx
      • MySQL o MariaDB
    • Gestionar servicios con systemctl
    • Consultar registros con journalctl
    • Configurar reglas básicas de seguridad con ufw
    • Crear scripts Bash para tareas de mantenimiento
    • Programar tareas automáticas con cron
    • Verificar conectividad y dependencias entre sistemas
    • Documentar de forma técnica el trabajo realizado

    Propuesta de arquitectura

    ┌─────────────────────────────────────────────────────────────┐
    │                 ENTORNO DE VIRTUALIZACIÓN                   │
    │         (VirtualBox / VMware / Proxmox / similar)           │
    └─────────────────────────────────────────────────────────────┘
                               │
                               ▼
    ┌─────────────────────────────────────────────────────────────┐
    │                  RED LOCAL VIRTUALIZADA                     │
    │                     192.168.50.0/24                         │
    └─────────────────────────────────────────────────────────────┘
            │                         │                         │
            ▼                         ▼                         ▼
    
    ┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
    │      web01      │     │      db01       │     │     admin01     │
    │ 192.168.50.10   │     │ 192.168.50.20   │     │ 192.168.50.30   │
    ├─────────────────┤     ├─────────────────┤     ├─────────────────┤
    │ Ubuntu Server   │     │ Ubuntu Server   │     │ Ubuntu Server   │
    │ Apache / HTTP   │     │ MySQL / MariaDB │     │ SSH / Scripts   │
    │ Página web      │     │ Base de datos   │     │ Cron / Control  │
    └─────────────────┘     └─────────────────┘     └─────────────────┘
            │                         ▲                         │
            │ consulta datos          │                         │
            └─────────────────────────┘                         │
                      conexión remota                           │
                                                                │
                                                                │ administración,
                                                                │ comprobación,
                                                                │ mantenimiento
                                                                ▼
                                            ┌──────────────────────────────┐
                                            │  Scripts + logs + cron +     │
                                            │      comprobaciones          │
                                            └──────────────────────────────┘

    Para que el proyecto tenga sentido, conviene que las máquinas tengan relación entre sí.

    Máquina 1: servidor web

    • Nombre: web01
    • IP fija: 192.168.1.10
    • Servicios:
      • Apache2
      • Página web de prueba
    • Función:
      • Servir una web que muestre información del sistema
      • Conectarse a la base de datos remota para validar que existe comunicación

    Máquina 2: servidor de base de datos

    • Nombre: db01
    • IP fija: 192.168.1.20
    • Servicios:
      • MySQL Server o MariaDB
    • Función:
      • Alojar una base de datos
      • Permitir conexión desde web01
      • Tener usuarios y permisos configurados

    Máquina 3: servidor de administración / monitorización básica

    • Nombre: admin01
    • IP fija: 192.168.1.30
    • Servicios y funciones:
      • Acceso por SSH a las otras máquinas
      • Scripts de mantenimiento
      • Tareas programadas por cron
      • Recolección de información del sistema
    • Función:
      • Ejecutar scripts
      • Hacer comprobaciones de red
      • Centralizar tareas administrativas básicas

    Relación de dependencia entre máquinas

    • web01 depende de db01 porque debe conectarse a la base de datos remota
    • admin01 depende de web01 y db01 porque debe administrarlas o comprobar su estado
    • todas deben estar en la misma red local virtual y responder entre sí
    graph TD
        A[Entorno de virtualización] --> B[Red local virtual 192.168.50.0/24]
    
        B --> C[web01<br>192.168.50.10<br>Ubuntu Server<br>Apache]
        B --> D[db01<br>192.168.50.20<br>Ubuntu Server<br>MySQL / MariaDB]
        B --> E[admin01<br>192.168.50.30<br>Ubuntu Server<br>SSH / Scripts / Cron]
    
        C -->|Consulta remota| D
        E -->|Administración y comprobación| C
        E -->|Administración y comprobación| D
    
        C --> F[Servicio web activo]
        D --> G[Base de datos activa]
        E --> H[Scripts de mantenimiento]
        E --> I[Tareas automáticas con cron]
        E --> J[Comprobación de logs y servicios]
    
        C --> K[UFW]
        D --> K
        E --> K
    
        F --> L[Documentación README]
        G --> L
        H --> L
        I --> L
        J --> L
        K --> L

    Requisitos mínimos del proyecto

    El alumno deberá cumplir, como mínimo, lo siguiente:

    Virtualización

    • Crear 3 máquinas virtuales
    • Asignar recursos coherentes
    • Instalar Ubuntu Server en todas

    Red

    • Configurar una red local virtual
    • Asignar IP fija a cada máquina
    • Verificar conectividad con ping

    Servicios

    • Instalar Apache en web01
    • Instalar MySQL o MariaDB en db01
    • Comprobar que el servicio web funciona desde navegador o con curl
    • Comprobar que la base de datos acepta conexiones

    Administración

    • Usar comandos de terminal durante todo el proyecto
    • Gestionar servicios con systemctl
    • Consultar logs con journalctl

    Seguridad

    • Activar y configurar ufw
    • Permitir solo los puertos necesarios
    • Explicar qué puertos se abren y por qué

    Automatización

    • Crear al menos 2 scripts Bash
    • Programar al menos 2 tareas con cron

    Fases del proyecto

    flowchart TD
        A[Planificación] --> B[Virtualización]
        B --> C[Instalación de sistemas]
        C --> D[Configuración de red]
        D --> E[Conectividad]
    
        E --> F[Servidor web]
        E --> G[Servidor de base de datos]
    
        F --> H[Comunicación entre servicios]
        G --> H
    
        H --> I[Administración de servicios]
        I --> J[Revisión de logs]
        J --> K[Seguridad con UFW]
        K --> L[Scripts de mantenimiento]
        L --> M[Tareas automáticas con cron]
        M --> N[Pruebas finales]
        N --> O[Documentación README y evidencias]

    Fase 1. Creación de la infraestructura virtual

    Tareas

    1. Instalar el software de virtualización
      • VirtualBox, VMware o similar
    2. Crear 3 máquinas virtuales
    3. Asignar nombre a cada una
    4. Instalar Ubuntu Server en cada una

    Evidencias obligatorias

    • Captura del software de virtualización mostrando las 3 máquinas
    • Captura del proceso de instalación o del sistema ya instalado
    • Tabla con nombre, RAM, disco y función de cada VM

    Qué debe explicar en el README

    • Qué programa de virtualización ha utilizado
    • Qué recursos ha asignado a cada VM
    • Por qué ha organizado así la infraestructura

    Fase 2. Configuración de red

    Tareas

    1. Configurar red local entre las máquinas
    2. Asignar IP fija a cada sistema
    3. Comprobar conectividad

    Ejemplo de tabla de red

    MáquinaIPMáscaraPuerta de enlaceFunción
    web01192.168.50.10255.255.255.0192.168.50.1 o vacía si no aplicaWeb
    db01192.168.50.20255.255.255.0192.168.50.1 o vacía si no aplicaBD
    admin01192.168.50.30255.255.255.0192.168.50.1 o vacía si no aplicaAdministración

    Comprobaciones que deben hacer

    • ip a
    • hostnamectl
    • ping entre máquinas

    Evidencias obligatorias

    • Archivo de configuración de red o capturas del mismo
    • Resultado de ip a
    • Resultado de pings exitosos entre las máquinas

    Qué debe explicar en el README

    • Cómo ha configurado la IP fija
    • Qué problemas encontró
    • Cómo comprobó que la red funciona

    Fase 3. Instalación y configuración del servidor web

    Tareas

    En web01:

    1. Instalar Apache2
    2. Arrancar y habilitar el servicio
    3. Crear una página de prueba
    4. Comprobar acceso desde la propia máquina y desde otra

    Comandos que deberían usar

    sudo apt update
    sudo apt install apache2 -y
    sudo systemctl enable apache2
    sudo systemctl start apache2
    sudo systemctl status apache2

    Página mínima sugerida

    Una página HTML que muestre:

    • nombre del servidor
    • IP
    • fecha
    • descripción del proyecto

    Evidencias obligatorias

    • Captura de systemctl status apache2
    • Captura del navegador o curl http://192.168.50.10
    • Captura del contenido de la página web

    Qué debe explicar en el README

    • Qué hace Apache
    • Dónde se encuentra el directorio web
    • Cómo ha comprobado que el servicio está funcionando

    Fase 4. Instalación y configuración del servidor de base de datos

    Tareas

    En db01:

    1. Instalar MySQL o MariaDB
    2. Habilitar y arrancar el servicio
    3. Crear una base de datos
    4. Crear un usuario con permisos
    5. Permitir acceso desde web01

    Posible estructura

    • Base de datos: empresa
    • Tabla: servicios
    • Usuario remoto: webuser

    Evidencias obligatorias

    • Captura de systemctl status mysql
    • Captura del acceso al cliente MySQL
    • Captura o volcado SQL con creación de base y usuario

    Qué debe explicar en el README

    • Qué motor ha instalado
    • Qué usuario creó y con qué permisos
    • Qué diferencia hay entre usuario local y remoto
    • Cómo ha validado la conexión

    Fase 5. Comunicación entre servidor web y servidor de base de datos

    Aquí está la gracia del invento. No queremos máquinas decorativas.

    Tareas

    Desde web01:

    1. Comprobar conectividad con db01
    2. Instalar cliente MySQL si hace falta
    3. Conectarse a la base de datos remota
    4. Insertar o consultar datos

    Evidencias obligatorias

    • ping 192.168.50.20
    • conexión por cliente a MySQL remoto
    • captura de consulta SQL exitosa

    Qué debe explicar en el README

    • Por qué web01 depende de db01
    • Qué configuración fue necesaria para permitir el acceso remoto
    • Qué medidas de seguridad tomó

    Fase 6. Gestión de servicios y logs

    Tareas

    En las distintas máquinas:

    1. Consultar el estado de Apache y MySQL
    2. Reiniciar y detener servicios
    3. Ver logs con journalctl

    Comandos mínimos que deben demostrar

    sudo systemctl status apache2
    sudo systemctl restart apache2
    sudo systemctl stop apache2
    sudo systemctl start apache2
    journalctl -u apache2
    journalctl -u mysql
    journalctl -xe

    Evidencias obligatorias

    • Captura de systemctl status
    • Captura de journalctl -u apache2
    • Captura de journalctl -u mysql o equivalente

    Qué debe explicar en el README

    • Qué diferencia hay entre iniciar, parar, reiniciar y habilitar un servicio
    • Para qué sirve journalctl
    • Qué información útil encontró en los logs

    Fase 7. Seguridad básica con UFW

    Tareas del alumno

    En cada máquina:

    1. Instalar o activar ufw
    2. Definir política básica
    3. Abrir solo los puertos necesarios

    Ejemplo

    • web01: permitir 22 y 80
    • db01: permitir 22 y 3306 solo si procede
    • admin01: permitir 22

    Comandos orientativos

    sudo ufw enable
    sudo ufw status verbose
    sudo ufw allow 22/tcp
    sudo ufw allow 80/tcp
    sudo ufw allow 3306/tcp

    Evidencias obligatorias

    • Captura de ufw status verbose
    • Explicación de qué puertos se han abierto
    • Justificación de seguridad

    Qué debe explicar en el README

    • Qué es un firewall
    • Qué puertos necesita cada máquina
    • Qué riesgos existirían si se abrieran más puertos de la cuenta

    Fase 8. Scripts de mantenimiento

    Tareas

    Crear al menos dos scripts Bash.

    Script 1: comprobación del sistema

    Debe mostrar:

    • hostname
    • IP
    • uso de disco
    • uso de memoria
    • fecha
    • estado de un servicio

    Script 2: copia de logs o informe de mantenimiento

    Debe:

    • crear una carpeta de copias o informes
    • guardar fecha y hora
    • copiar un log o generar un resumen del sistema a un archivo

    Ejemplo de ideas

    • check_web.sh
    • backup_logs.sh
    • estado_sistema.sh

    Evidencias obligatorias

    • Código de los scripts
    • Captura de ejecución
    • Explicación línea por línea o por bloques

    Qué debe explicar en el README

    • Para qué sirve cada script
    • Cómo se ejecuta
    • Qué permisos necesita
    • Qué salida genera

    Fase 9. Automatización con cron

    Tareas

    Programar al menos dos tareas automáticas:

    • una para ejecutar un script de mantenimiento
    • otra para generar un informe o copia

    Comandos esperados

    crontab -e
    crontab -l

    Evidencias obligatorias

    • Captura de crontab -l
    • Captura o prueba del archivo generado por cron
    • Explicación del formato del cron

    Qué debe explicar en el README

    • Qué tarea automatizó
    • Cada cuánto se ejecuta
    • Cómo verificó que realmente se ejecutó


    Plantilla de README

    Puedes darles esta estructura para obligarles a documentar bien.

    # Proyecto: infraestructura virtualizada con Ubuntu Server
    
    ## 1. Datos del alumno
    - Nombre:
    - Curso:
    - Módulo:
    - Fecha:
    
    ## 2. Introducción
    Explica brevemente en qué consiste el proyecto y cuáles son sus objetivos.
    
    ## 3. Diseño de la infraestructura
    ### 3.1 Máquinas virtuales creadas
    | Máquina | Función | IP | Sistema operativo |
    |---|---|---|---|
    
    ### 3.2 Relación entre máquinas
    Explica cómo se comunican y de qué depende cada una.
    
    ## 4. Instalación de Ubuntu Server
    Describe el proceso de creación e instalación de cada máquina virtual.
    
    ### Evidencias
    - Capturas
    - Configuración asignada
    - Observaciones
    
    ## 5. Configuración de red
    Explica cómo configuraste la IP fija en cada máquina.
    
    ### Comandos utilizados
    ~~~bash
    ip a
    ping

    Estructura de entrega recomendada

    Puedes utilizar esta estructura para la documentación:

    proyecto/
    │
    ├── README.md
    ├── evidencias/
    │   ├── 01-virtualizacion/
    │   ├── 02-red/
    │   ├── 03-web/
    │   ├── 04-bd/
    │   ├── 05-seguridad/
    │   ├── 06-scripts/
    │   └── 07-cron/
    │
    ├── scripts/
    │   ├── check_web.sh
    │   └── backup_logs.sh
    │
    ├── configuracion/
    │   ├── netplan-web01.yaml
    │   ├── netplan-db01.yaml
    │   └── netplan-admin01.yaml
    │
    └── sql/
        └── bd_inicial.sql

    Evidencias que puedes incluir en la documentación

    (capturas y explicación)

    Instalación y configuración de Apache

    Explica la instalación del servidor web en web01.

    Comandos utilizados

    sudo apt update
    sudo apt install apache2 -y

    Verificación

    Explica cómo comprobaste que funciona.

    Instalación y configuración de MySQL/MariaDB

    Explica la instalación del servidor de base de datos en db01.

    Comandos utilizados

    sudo apt install mysql-server -y

    Verificación

    Explica cómo comprobaste que funciona.

    Comunicación entre servicios

    Explica cómo el servidor web accede al servidor de base de datos.

    Pruebas realizadas

    • ping
    • conexión remota
    • consulta SQL

    Gestión de servicios con systemctl

    Explica qué comandos usaste para iniciar, parar, reiniciar y habilitar servicios.

    Consulta de logs con journalctl

    Indica qué logs revisaste y qué información encontraste.

    Seguridad con UFW

    Explica qué reglas configuraste y por qué.

    Scripts de mantenimiento

    Script 1

    • Nombre:
    • Función:
    • Código:
    • Resultado:

    Script 2

    • Nombre:
    • Función:
    • Código:
    • Resultado:

    Tareas programadas con cron

    Explica qué tareas automatizaste y cómo las comprobaste.

    Comprobaciones finales

    Incluye evidencias de:

    • IP fija
    • conectividad entre máquinas
    • Apache funcionando
    • MySQL funcionando
    • firewall activo
    • scripts funcionando
    • cron funcionando

    Problemas encontrados y soluciones

    Describe los errores o dificultades y cómo los resolviste.

    Cómo verificar que realmente ha hecho el trabajo

    Esto es clave. Hay que pedir pruebas que huelan a trabajo real y no a “copié cuatro cosas de internet y recé”. Para demostrar que es una implementación real, puedes ir incluyendo en la documentación (Donde toque) el resultado de algunso comandos.

    Identificación del sistema

    En cada máquina:

    hostnamectl
    ip a
    lsb_release -a

    Estado de servicios

    systemctl status apache2
    systemctl status mysql

    Logs reales

    journalctl -u apache2 --no-pager | tail -n 20
    journalctl -u mysql --no-pager | tail -n 20

    Firewall

    sudo ufw status verbose

    Cron

    crontab -l

    Scripts

    Ejecutar los scripts y mostrar salida:

    bash check_web.sh
    bash backup_logs.sh

    Red

    ping -c 4 192.168.50.20
    ping -c 4 192.168.50.10

    Web

    Desde otra máquina:

    curl http://192.168.50.10

    Base de datos

    Desde web01:

    mysql -h 192.168.50.20 -u webuser -p
  • Proyecto guiado: servidor GitLab personal con Docker Compose

    1. Objetivo del proyecto

    El objetivo es instalar un servidor GitLab Self-Managed sobre una máquina con Ubuntu Server.

    Este servidor permitirá:

    • Guardar proyectos de programación.
    • Centralizar scripts personales.
    • Mantener archivos de configuración.
    • Trabajar desde diferentes ordenadores.
    • Controlar las versiones de los archivos.
    • Recuperar versiones anteriores.
    • Desplegar proyectos en otros servidores.
    • Automatizar despliegues mediante GitLab CI/CD.
    • Mantener copias de seguridad de todos los repositorios.

    Aunque muchas veces se utiliza la expresión “instalar un GitHub”, realmente instalaremos GitLab, que ofrece un servicio similar a GitHub, pero alojado en nuestro propio servidor.

    La arquitectura inicial será:

    Ordenador personal
            │
            │ Git mediante SSH o HTTPS
            ▼
    https://gitlab.tudominio.es
            │
            ▼
    Router de Internet
            │
            │ Puertos 80, 443 y 2222
            ▼
    Ubuntu Server
            │
            ▼
    Docker Compose
            │
            ▼
    GitLab Community Edition
    

    Fase 0. Planificación y requisitos

    0.1. Requisitos recomendados

    Para una instalación personal se recomienda:

    • Ubuntu Server 22.04 LTS o 24.04 LTS.
    • Procesador de 64 bits.
    • 4 núcleos de CPU recomendados.
    • 8 GB de RAM recomendados.
    • 50 GB de almacenamiento como mínimo.
    • Dirección IP local fija.
    • Dominio propio.
    • Acceso a la configuración del router.
    • Conexión a Internet sin CG-NAT, o con posibilidad de abrir puertos.
    • Usuario de Ubuntu con permisos sudo.

    GitLab consume bastantes más recursos que un servidor Git básico. Con 4 GB de RAM puede funcionar para pruebas, pero para un uso continuado es preferible disponer de 8 GB o más.

    0.2. Datos utilizados en los ejemplos

    Durante la documentación utilizaremos estos datos:

    Dominio: gitlab.tudominio.es
    IP local del servidor: 192.168.1.50
    Puerto web HTTP: 80
    Puerto web HTTPS: 443
    Puerto SSH de GitLab: 2222
    Directorio de instalación: /srv/gitlab
    

    El puerto SSH externo será el 2222 porque el puerto 22 normalmente ya está siendo utilizado por el servicio SSH de Ubuntu Server.

    0.3. Comprobar la versión de Ubuntu

    lsb_release -a
    

    También podemos utilizar:

    cat /etc/os-release
    

    0.4. Comprobar procesador, memoria y almacenamiento

    Procesador:

    lscpu
    

    Memoria:

    free -h
    

    Espacio en disco:

    df -h
    

    0.5. Actualizar Ubuntu Server

    sudo apt update
    sudo apt upgrade -y
    

    Reiniciamos si se ha actualizado el kernel:

    sudo reboot
    

    Fase 1. Configuración de red y dominio

    1.1. Asignar una IP fija al servidor

    El servidor debe mantener siempre la misma dirección IP dentro de la red local.

    Tenemos dos posibilidades:

    1. Crear una reserva DHCP en el router.
    2. Configurar una IP estática en Ubuntu Server.

    La opción más sencilla suele ser crear una reserva DHCP en el router asociando la dirección MAC del servidor con una IP, por ejemplo:

    192.168.1.50
    

    Para consultar la dirección IP actual:

    ip address
    

    Versión abreviada:

    ip -br address
    

    Para conocer la puerta de enlace:

    ip route
    

    1.2. Comprobar la IP pública

    Desde el servidor podemos ejecutar:

    curl https://ifconfig.me
    

    También podemos consultar la IP pública desde el panel del router.

    1.3. Crear el registro DNS

    En el proveedor del dominio debemos crear un registro de tipo A.

    Ejemplo:

    Tipo: A
    Nombre: gitlab
    Destino: IP_PUBLICA
    TTL: Automático
    

    El resultado será:

    gitlab.tudominio.es → IP pública del router
    

    Si la conexión utiliza una IP pública dinámica, será necesario configurar un servicio de DNS dinámico o actualizar automáticamente el registro DNS.

    El dominio debe resolver públicamente hacia el servidor para que GitLab pueda solicitar automáticamente el certificado HTTPS de Let’s Encrypt.

    1.4. Comprobar la resolución DNS

    Desde otro ordenador:

    nslookup gitlab.tudominio.es
    

    En Linux o macOS también podemos utilizar:

    dig gitlab.tudominio.es
    

    El resultado debe mostrar nuestra IP pública.

    1.5. Configurar la redirección de puertos

    En el router debemos crear estas reglas NAT o Port Forwarding:

    Puerto externoIP internaPuerto internoProtocolo
    80192.168.1.5080TCP
    443192.168.1.50443TCP
    2222192.168.1.502222TCP

    Los puertos 80 y 443 deben ser accesibles desde Internet para la validación y renovación automática del certificado de Let’s Encrypt.

    1.6. Comprobar si existe CG-NAT

    Compara:

    • La IP pública mostrada por el router.
    • La IP obtenida con curl https://ifconfig.me.

    Si son diferentes, es posible que la conexión esté detrás de CG-NAT.

    En ese caso, las redirecciones de puertos no funcionarán directamente. Las alternativas serían:

    • Solicitar una IP pública al proveedor.
    • Utilizar una VPN como WireGuard o Tailscale.
    • Utilizar un túnel inverso.
    • Alojar GitLab en un VPS.

    Fase 2. Instalación de Docker y Docker Compose

    2.1. Eliminar paquetes incompatibles

    Antes de instalar Docker desde su repositorio oficial eliminamos posibles versiones anteriores:

    sudo apt remove -y \
    docker.io \
    docker-compose \
    docker-compose-v2 \
    docker-doc \
    podman-docker \
    containerd \
    runc
    

    No ocurre nada si algunos de estos paquetes no estaban instalados.

    Docker recomienda utilizar su repositorio oficial de APT e instalar el complemento moderno docker compose, en lugar del antiguo ejecutable independiente docker-compose.

    2.2. Instalar las dependencias

    sudo apt update
    sudo apt install -y ca-certificates curl
    

    2.3. Añadir la clave oficial de Docker

    sudo install -m 0755 -d /etc/apt/keyrings
    
    sudo curl -fsSL \
    https://download.docker.com/linux/ubuntu/gpg \
    -o /etc/apt/keyrings/docker.asc
    
    sudo chmod a+r /etc/apt/keyrings/docker.asc
    

    2.4. Añadir el repositorio

    sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
    Types: deb
    URIs: https://download.docker.com/linux/ubuntu
    Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
    Components: stable
    Architectures: $(dpkg --print-architecture)
    Signed-By: /etc/apt/keyrings/docker.asc
    EOF

    Actualizamos la información de paquetes:

    sudo apt update
    

    2.5. Instalar Docker

    sudo apt install -y \
    docker-ce \
    docker-ce-cli \
    containerd.io \
    docker-buildx-plugin \
    docker-compose-plugin
    

    2.6. Comprobar el servicio

    sudo systemctl status docker
    

    Debe aparecer:

    active (running)
    

    Para salir de la pantalla de estado pulsamos:

    q
    

    2.7. Activar Docker durante el arranque

    sudo systemctl enable docker
    

    2.8. Probar Docker

    sudo docker run --rm hello-world
    

    2.9. Comprobar Docker Compose

    sudo docker compose version
    

    Debe aparecer una versión de Docker Compose.

    2.10. Permitir utilizar Docker sin sudo

    Añadimos nuestro usuario al grupo docker:

    sudo usermod -aG docker "$USER"
    

    Cerramos la sesión cambiado de usuario o reiniciando.

    Volvemos a conectarnos por SSH y comprobamos:

    docker ps
    

    Pertenecer al grupo docker proporciona privilegios elevados sobre el sistema. Solamente deben añadirse usuarios de confianza.


    Fase 3. Preparación del servidor GitLab

    3.1. Crear la estructura de directorios

    sudo mkdir -p /srv/gitlab
    

    Creamos los directorios persistentes:

    sudo mkdir -p /srv/gitlab/config
    sudo mkdir -p /srv/gitlab/logs
    sudo mkdir -p /srv/gitlab/data
    sudo mkdir -p /srv/gitlab/backups
    

    Asignamos los directorios al usuario actual:

    sudo chown -R "$USER":"$USER" /srv/gitlab
    

    Entramos en el directorio:

    cd /srv/gitlab
    

    3.2. Función de los directorios

    Directorio del servidorDirectorio del contenedorContenido
    /srv/gitlab/config/etc/gitlabConfiguración y secretos
    /srv/gitlab/logs/var/log/gitlabRegistros
    /srv/gitlab/data/var/opt/gitlabRepositorios y datos
    /srv/gitlab/backupsCopias adicionales

    La imagen oficial de GitLab utiliza precisamente /etc/gitlab, /var/log/gitlab y /var/opt/gitlab para conservar la configuración, los registros y los datos.


    Fase 4. Instalación de GitLab con Docker Compose

    4.1. Elegir una versión

    GitLab ofrece:

    • GitLab Community Edition: gitlab/gitlab-ce
    • GitLab Enterprise Edition: gitlab/gitlab-ee

    Para este proyecto personal utilizaremos Community Edition.

    Para una primera prueba se puede utilizar:

    gitlab/gitlab-ce:latest
    

    Sin embargo, cuando el servidor esté funcionando conviene fijar una versión concreta:

    gitlab/gitlab-ce:19.x.x-ce.0
    

    GitLab recomienda fijar una versión específica en entornos estables y utilizar latest principalmente para pruebas.

    4.2. Crear el archivo .env

    nano /srv/gitlab/.env
    

    Contenido:

    GITLAB_HOSTNAME=gitlab.tudominio.es
    GITLAB_IMAGE=gitlab/gitlab-ce:latest
    

    Guardamos con:

    Ctrl + O
    Enter
    Ctrl + X
    

    4.3. Crear compose.yaml

    nano /srv/gitlab/compose.yaml
    

    Contenido:

    services:
      gitlab:
        image: gitlab/gitlab-ce:latest
        container_name: gitlab
        hostname: 192.168.1.14
        restart: unless-stopped
    
        environment:
          GITLAB_OMNIBUS_CONFIG: |
            external_url 'http://192.168.1.14:8929'
    
            nginx['listen_port'] = 80
            nginx['listen_https'] = false
            letsencrypt['enable'] = false
    
            gitlab_rails['gitlab_shell_ssh_port'] = 2222
    
        ports:
          - "8929:80"
          - "2222:22"
    
        volumes:
          - ./config:/etc/gitlab
          - ./logs:/var/log/gitlab
          - ./data:/var/opt/gitlab
    
        shm_size: "256m"
    

    La configuración utiliza:

    Puerto 80 del servidor  → puerto 80 de GitLab
    Puerto 443 del servidor → puerto 443 de GitLab
    Puerto 2222 del servidor → puerto 22 del contenedor
    

    El valor:

    gitlab_rails['gitlab_shell_ssh_port'] = 2222
    

    indica a GitLab que debe mostrar el puerto 2222 en las direcciones de clonación SSH. La documentación oficial contempla configurar un puerto SSH externo diferente cuando el puerto 22 del servidor está ocupado.

    4.4. Validar el archivo

    cd /srv/gitlab
    docker compose config
    

    Si no aparecen errores, la sintaxis es correcta.

    4.5. Descargar la imagen

    docker compose pull
    

    4.6. Iniciar GitLab

    docker compose up -d
    

    4.7. Consultar el estado

    docker compose ps
    

    4.8. Consultar los registros

    docker compose logs -f gitlab
    

    Para dejar de visualizar los registros:

    Ctrl + C

    La primera inicialización es más lenta que los siguientes arranques porque GitLab debe configurar PostgreSQL, Redis, NGINX, Gitaly y el resto de sus componentes internos.

    4.9. Comprobar el estado interno

    docker exec -it gitlab gitlab-ctl status
    

    También podemos comprobar el endpoint de estado:

    curl -I https://gitlab.tudominio.es
    

    Fase 5. Primer acceso y configuración inicial

    5.1. Obtener la contraseña inicial

    docker exec -it gitlab \
    grep 'Password:' /etc/gitlab/initial_root_password
    

    El usuario inicial es:

    root
    

    El archivo con la contraseña inicial se elimina automáticamente después del primer reinicio transcurridas aproximadamente 24 horas, por lo que conviene obtenerla y cambiarla cuanto antes.

    5.2. Entrar en GitLab

    Revisa la configuración persistente

    Como /srv/gitlab/config es persistente, puede conservarse la dirección anterior.

    Ejecuta:

    grep -n "external_url" /srv/gitlab/config/gitlab.rb

    Si aparece:

    external_url 'https://gitlab.tudominio.es'

    edita el archivo:

    sudo nano /srv/gitlab/config/gitlab.rb

    Cámbialo por:

    external_url 'http://192.168.1.14:8929'

    Introducimos:

    Usuario: root
    Contraseña: la obtenida anteriormente
    

    5.3. Cambiar la contraseña de root

    Dentro de GitLab:

    Avatar
    → Edit profile
    → Password
    

    Debemos utilizar una contraseña larga y exclusiva.

    5.4. Crear un usuario personal

    Es preferible no trabajar diariamente con root.

    Entramos en:

    Admin
    → Overview
    → Users
    → New user
    

    Ejemplo:

    Nombre: Antonio Otero
    Usuario: antonio
    Correo: correo@tudominio.es
    

    Podemos marcar el usuario como administrador si realmente necesitamos administrar GitLab desde esa cuenta.

    5.5. Desactivar el registro público

    Como el servidor está expuesto a Internet y será de uso personal, debemos impedir que cualquier visitante pueda crear una cuenta.

    Ruta:

    Admin
    → Settings
    → General
    → New user account restrictions
    

    Desmarcamos:

    Allow new user accounts
    

    GitLab recomienda plantearse la desactivación del registro en instancias públicas donde no se espera que usuarios externos creen cuentas.

    5.6. Limitar la visibilidad predeterminada

    En:

    Admin
    → Settings
    → General
    → Visibility and access controls
    

    Configuramos:

    Default project visibility: Private
    Default snippet visibility: Private
    Default group visibility: Private
    

    5.7. Activar autenticación de dos factores

    En la cuenta personal:

    Avatar
    → Edit profile
    → Account
    → Two-factor authentication
    

    Guardamos los códigos de recuperación en un lugar seguro.


    Fase 6. Configuración de Git y claves SSH

    GitLab permite trabajar mediante HTTPS o SSH. Para trabajar habitualmente desde varios equipos utilizaremos SSH, que GitLab recomienda como método de autenticación para clonar repositorios.

    6.1. Instalar Git en Ubuntu o Debian

    sudo apt update
    sudo apt install -y git
    

    6.2. Instalar Git en Windows

    Puede instalarse Git for Windows y utilizar:

    • Git Bash.
    • PowerShell.
    • Visual Studio Code.
    • Un IDE compatible con Git.

    6.3. Comprobar la instalación

    git --version
    

    6.4. Configurar el nombre y el correo

    En cada ordenador:

    git config --global user.name "Antonio Otero"
    
    git config --global user.email "correo@tudominio.es"
    

    Comprobamos:

    git config --global --list
    

    6.5. Crear una clave SSH

    En Linux, macOS, PowerShell o Git Bash:

    ssh-keygen -t ed25519 -C "portatil-personal"
    

    Cuando pregunte dónde guardar la clave, pulsamos Enter.

    Ruta habitual:

    Linux/macOS:
    ~/.ssh/id_ed25519
    ~/.ssh/id_ed25519.pub
    
    Windows:
    C:\Users\USUARIO\.ssh\id_ed25519
    C:\Users\USUARIO\.ssh\id_ed25519.pub
    

    Es recomendable establecer una contraseña para proteger la clave privada.

    6.6. Mostrar la clave pública

    Linux o macOS:

    cat ~/.ssh/id_ed25519.pub
    

    Windows PowerShell:

    Get-Content $HOME\.ssh\id_ed25519.pub
    

    Copiamos el contenido completo.

    6.7. Añadir la clave a GitLab

    En GitLab:

    Avatar
    → Edit profile
    → Access
    → SSH keys
    → Add new key
    

    Indicamos un nombre identificativo:

    MacBook Pro
    PC principal
    Portátil Windows
    Equipo del trabajo
    

    Cada ordenador debe tener su propia clave. No es recomendable copiar la misma clave privada entre todos los equipos.

    6.8. Configurar el puerto SSH personalizado

    Creamos o editamos:

    nano ~/.ssh/config
    

    Contenido:

    Host gitlab-personal
        HostName gitlab.tudominio.es
        User git
        Port 2222
        IdentityFile ~/.ssh/id_ed25519
        IdentitiesOnly yes
    

    Protegemos el archivo:

    chmod 600 ~/.ssh/config
    

    6.9. Probar la conexión

    ssh -T gitlab-personal
    

    La primera vez aparecerá una pregunta sobre la huella del servidor.

    Después de comprobar que el nombre del servidor es correcto, respondemos:

    yes
    

    El resultado esperado será parecido a:

    Welcome to GitLab, @antonio!
    

    También podemos probar directamente:

    ssh -T -p 2222 git@gitlab.tudominio.es
    

    Fase 7. Crear y utilizar el primer repositorio

    7.1. Crear un proyecto en GitLab

    Entramos en:

    New project
    → Create blank project
    

    Ejemplo:

    Project name: scripts-linux
    Project slug: scripts-linux
    Visibility level: Private
    

    Podemos marcar:

    Initialize repository with a README
    

    7.2. Clonar el repositorio

    Utilizando el alias SSH:

    git clone gitlab-personal:antonio/scripts-linux.git
    

    Entramos en el proyecto:

    cd scripts-linux
    

    7.3. Crear un archivo

    nano informacion-sistema.sh
    

    Contenido:

    #!/bin/bash
    
    echo "Nombre del equipo:"
    hostname
    
    echo
    echo "Sistema operativo:"
    cat /etc/os-release
    
    echo
    echo "Memoria:"
    free -h
    
    echo
    echo "Almacenamiento:"
    df -h
    

    Guardamos y damos permisos:

    chmod +x informacion-sistema.sh
    

    7.4. Consultar el estado

    git status
    

    7.5. Añadir los cambios

    git add informacion-sistema.sh
    

    También podríamos añadir todos los archivos:

    git add .
    

    7.6. Crear un commit

    git commit -m "Añadido script de información del sistema"
    

    7.7. Subir los cambios

    git push
    

    7.8. Flujo de trabajo habitual

    Cada vez que comencemos a trabajar:

    git pull
    

    Después modificamos los archivos y ejecutamos:

    git status
    git add .
    git commit -m "Descripción clara de los cambios"
    git push
    

    Fase 8. Trabajar desde varios ordenadores

    8.1. Primer ordenador

    En el primer equipo:

    git clone gitlab-personal:antonio/scripts-linux.git
    cd scripts-linux
    

    Modificamos y subimos cambios:

    git add .
    git commit -m "Cambios realizados desde el PC principal"
    git push
    

    8.2. Segundo ordenador

    Configuramos su propia clave SSH y la añadimos a GitLab.

    Después:

    git clone gitlab-personal:antonio/scripts-linux.git
    cd scripts-linux
    

    Antes de trabajar:

    git pull
    

    Realizamos los cambios:

    git add .
    git commit -m "Cambios realizados desde el portátil"
    git push
    

    8.3. Regla fundamental

    Antes de empezar una sesión de trabajo:

    git pull
    

    Después de terminar:

    git add .
    git commit -m "Explicación de los cambios"
    git push
    

    8.4. Evitar conflictos

    No conviene modificar simultáneamente las mismas líneas del mismo archivo desde dos equipos sin haber sincronizado antes.

    Flujo recomendado:

    git pull
    

    Trabajamos.

    git add .
    git commit -m "Cambios"
    git push
    

    8.5. Resolver un conflicto sencillo

    Si git pull detecta un conflicto, el archivo mostrará algo parecido a:

    <<<<<<< HEAD
    Contenido local
    =======
    Contenido procedente del servidor
    >>>>>>> origin/main
    

    Debemos editar el archivo y dejar solamente el contenido definitivo.

    Después:

    git add archivo-conflictivo
    git commit -m "Resuelto conflicto de sincronización"
    git push
    

    Fase 9. Organización de los repositorios personales

    Para mantener el servidor ordenado podemos crear un grupo llamado:

    personal
    

    Dentro del grupo podemos crear repositorios como:

    personal/scripts-linux
    personal/scripts-windows
    personal/docker-compose
    personal/configuraciones
    personal/wordpress
    personal/php
    personal/java
    personal/python
    personal/documentacion
    personal/proyectos-clase
    

    9.1. Qué debe guardarse

    Ejemplos adecuados:

    • Código fuente.
    • Scripts Bash.
    • Scripts PowerShell.
    • Archivos Docker Compose.
    • Plantillas HTML y CSS.
    • Documentación Markdown.
    • Configuraciones sin credenciales.
    • Proyectos Java, PHP, Python o JavaScript.
    • Consultas SQL.
    • Diagramas.
    • Archivos pequeños relacionados con el proyecto.

    9.2. Qué no debe guardarse directamente

    No deben subirse:

    • Contraseñas.
    • Claves privadas SSH.
    • Tokens de acceso.
    • Archivos .env con credenciales.
    • Copias completas de bases de datos con datos sensibles.
    • Directorios de dependencias regenerables.
    • Imágenes de máquinas virtuales.
    • Archivos temporales.
    • Copias de seguridad grandes.
    • Certificados privados.

    9.3. Utilizar .gitignore

    Ejemplo para un proyecto PHP:

    .env
    vendor/
    node_modules/
    *.log
    .DS_Store
    .vscode/
    .idea/
    

    Ejemplo para Java:

    target/
    bin/
    .classpath
    .project
    .settings/
    *.class
    *.jar
    .idea/
    

    Ejemplo para Python:

    __pycache__/
    *.pyc
    .venv/
    venv/
    .env
    

    Fase 10. Importar un proyecto existente

    Supongamos que tenemos un proyecto en:

    /home/antonio/proyectos/mi-web
    

    Entramos en él:

    cd /home/antonio/proyectos/mi-web
    

    Inicializamos Git:

    git init
    

    Creamos la rama principal:

    git branch -M main
    

    Añadimos los archivos:

    git add .
    

    Creamos el primer commit:

    git commit -m "Importación inicial del proyecto"
    

    Creamos un proyecto vacío en GitLab y añadimos el remoto:

    git remote add origin \
    ssh://git@gitlab.tudominio.es:2222/antonio/mi-web.git
    

    Subimos el proyecto:

    git push -u origin main
    

    Para consultar el remoto:

    git remote -v
    

    Fase 11. Despliegue manual en otro ordenador

    GitLab almacenará el proyecto, pero también queremos desplegarlo en otros servidores.

    Supongamos que tenemos un servidor web con Ubuntu en:

    192.168.1.80
    

    11.1. Instalar Git en el servidor destino

    sudo apt update
    sudo apt install -y git
    

    11.2. Crear una clave exclusiva de despliegue

    En el servidor destino:

    ssh-keygen -t ed25519 -C "despliegue-servidor-web"
    

    Mostramos la clave pública:

    cat ~/.ssh/id_ed25519.pub
    

    11.3. Añadir una Deploy Key

    En el proyecto de GitLab:

    Settings
    → Repository
    → Deploy keys
    → Add new key
    

    Introducimos:

    Title: Servidor web
    Key: contenido de id_ed25519.pub
    

    Para un despliegue que solamente descarga archivos, no activamos permisos de escritura.

    Las Deploy Keys están pensadas precisamente para permitir que servidores externos accedan a repositorios sin asociar el acceso a la clave personal de un usuario.

    11.4. Configurar SSH en el servidor destino

    nano ~/.ssh/config
    

    Contenido:

    Host gitlab-personal
        HostName gitlab.tudominio.es
        User git
        Port 2222
        IdentityFile ~/.ssh/id_ed25519
        IdentitiesOnly yes
    

    Permisos:

    chmod 600 ~/.ssh/config
    

    11.5. Clonar el proyecto

    sudo mkdir -p /var/www
    sudo chown "$USER":"$USER" /var/www
    
    cd /var/www
    git clone gitlab-personal:antonio/mi-web.git
    

    11.6. Actualizar el despliegue

    Cuando subamos cambios a GitLab:

    cd /var/www/mi-web
    git pull origin main
    

    Este sería el despliegue manual más sencillo.


    Fase 12. Crear un script de despliegue

    En el servidor destino:

    sudo nano /usr/local/bin/desplegar-mi-web.sh
    

    Contenido:

    #!/bin/bash
    
    set -e
    
    PROYECTO="/var/www/mi-web"
    RAMA="main"
    
    echo "Iniciando despliegue..."
    
    cd "$PROYECTO"
    
    echo "Descargando cambios..."
    git fetch origin
    
    echo "Actualizando la rama $RAMA..."
    git reset --hard "origin/$RAMA"
    
    echo "Corrigiendo permisos..."
    sudo chown -R www-data:www-data "$PROYECTO"
    
    echo "Despliegue terminado correctamente."
    

    Damos permisos:

    sudo chmod +x /usr/local/bin/desplegar-mi-web.sh
    

    Ejecutamos:

    sudo /usr/local/bin/desplegar-mi-web.sh
    

    El uso de:

    git reset --hard origin/main
    

    garantiza que el directorio desplegado coincida exactamente con el contenido del repositorio remoto.

    Debe utilizarse solamente en un directorio de despliegue donde no se hagan cambios manuales que queramos conservar.


    Fase 13. Introducción al despliegue automático con GitLab Runner

    En una fase posterior podemos automatizar el despliegue mediante GitLab CI/CD.

    El flujo será:

    Ordenador
       │
       │ git push
       ▼
    GitLab
       │
       │ Ejecuta pipeline
       ▼
    GitLab Runner
       │
       │ Conecta por SSH
       ▼
    Servidor de despliegue
    

    GitLab Runner puede ejecutarse dentro de un contenedor Docker y ejecutar los trabajos definidos en .gitlab-ci.yml.

    13.1. Ejemplo conceptual de .gitlab-ci.yml

    stages:
      - comprobar
      - desplegar
    
    comprobar:
      stage: comprobar
      script:
        - echo "Comprobando el proyecto"
        - test -f index.html
    
    desplegar:
      stage: desplegar
      script:
        - echo "Desplegando proyecto"
        - ssh usuario@servidor-destino "/usr/local/bin/desplegar-mi-web.sh"
      only:
        - main
    

    Las claves privadas utilizadas por CI/CD no deben ser las claves personales del usuario. GitLab recomienda utilizar claves específicas para la automatización y almacenarlas de forma protegida.

    La instalación y configuración completa de Runner debe realizarse como una fase independiente después de dominar:

    • Repositorios.
    • Clonado.
    • Commits.
    • Push y pull.
    • Claves SSH.
    • Deploy Keys.
    • Despliegue manual.

    Fase 14. Copias de seguridad

    Un repositorio Git distribuido ya proporciona copias parciales en los equipos donde se ha clonado, pero eso no sustituye una copia completa de GitLab.

    La copia de GitLab debe incluir:

    • Base de datos.
    • Repositorios.
    • Archivos subidos.
    • Configuración.
    • Secretos.
    • Certificados.
    • Archivo compose.yaml.
    • Archivo .env.

    GitLab advierte de que debe conservarse también gitlab-secrets.json, porque contiene secretos necesarios para descifrar determinados datos durante una recuperación.

    14.1. Crear una copia desde el contenedor

    docker exec -t gitlab gitlab-backup create
    

    La copia se guardará normalmente dentro de:

    /srv/gitlab/data/backups
    

    Consultamos:

    sudo ls -lh /srv/gitlab/data/backups
    

    14.2. Copiar la configuración

    Creamos una carpeta con la fecha:

    FECHA=$(date +%Y-%m-%d_%H-%M)
    mkdir -p "/srv/gitlab/backups/$FECHA"
    

    Copiamos la configuración:

    sudo cp -a \
    /srv/gitlab/config \
    "/srv/gitlab/backups/$FECHA/"
    

    Copiamos Compose y las variables:

    cp /srv/gitlab/compose.yaml \
    "/srv/gitlab/backups/$FECHA/"
    
    cp /srv/gitlab/.env \
    "/srv/gitlab/backups/$FECHA/"
    

    14.3. Crear un archivo comprimido

    cd /srv/gitlab/backups
    
    sudo tar -czf "gitlab-config-$FECHA.tar.gz" "$FECHA"
    

    14.4. Copia externa

    La copia debe trasladarse a otro equipo o almacenamiento:

    rsync -avh \
    /srv/gitlab/backups/ \
    usuario@servidor-copias:/copias/gitlab/
    

    También se puede utilizar:

    • NAS.
    • Disco USB.
    • Otro servidor.
    • Almacenamiento cifrado en la nube.
    • rclone.
    • Copia mediante scp.

    Una copia guardada únicamente en el mismo disco que GitLab no protege frente a una avería física de ese disco.


    Fase 15. Automatizar las copias

    15.1. Crear un script

    sudo nano /usr/local/sbin/copiar-gitlab.sh
    

    Contenido:

    #!/bin/bash
    
    set -euo pipefail
    
    FECHA=$(date +%Y-%m-%d_%H-%M-%S)
    ORIGEN="/srv/gitlab"
    DESTINO="/srv/gitlab/backups/$FECHA"
    
    echo "Creando copia interna de GitLab..."
    
    docker exec -t gitlab gitlab-backup create
    
    echo "Copiando configuración..."
    
    mkdir -p "$DESTINO"
    
    cp -a "$ORIGEN/config" "$DESTINO/"
    cp "$ORIGEN/compose.yaml" "$DESTINO/"
    cp "$ORIGEN/.env" "$DESTINO/"
    
    echo "Comprimiendo configuración..."
    
    tar -czf "/srv/gitlab/backups/gitlab-config-$FECHA.tar.gz" \
    -C "/srv/gitlab/backups" "$FECHA"
    
    rm -rf "$DESTINO"
    
    echo "Eliminando copias de configuración antiguas..."
    
    find /srv/gitlab/backups \
    -type f \
    -name "gitlab-config-*.tar.gz" \
    -mtime +14 \
    -delete
    
    echo "Copia terminada: $FECHA"
    

    Damos permisos:

    sudo chmod 700 /usr/local/sbin/copiar-gitlab.sh
    

    15.2. Probar el script

    sudo /usr/local/sbin/copiar-gitlab.sh
    

    15.3. Programarlo con cron

    sudo crontab -e
    

    Añadimos:

    0 3 * * * /usr/local/sbin/copiar-gitlab.sh >> /var/log/copiar-gitlab.log 2>&1
    

    Esto ejecutará la copia todos los días a las 03:00.


    Fase 16. Restauración básica

    La restauración debe probarse antes de depender de ella.

    GitLab exige que la instalación utilizada para restaurar tenga la misma versión y edición que la instalación que creó la copia.

    16.1. Consultar la versión instalada

    docker exec -it gitlab gitlab-rake gitlab:env:info
    

    También podemos consultar la imagen:

    docker inspect gitlab \
    --format='{{.Config.Image}}'
    

    Debemos anotar el resultado.

    Ejemplo:

    gitlab/gitlab-ce:19.x.x-ce.0
    

    16.2. Detener los servicios que escriben en la base de datos

    docker exec -it gitlab gitlab-ctl stop puma
    docker exec -it gitlab gitlab-ctl stop sidekiq
    

    16.3. Consultar las copias disponibles

    ls -lh /srv/gitlab/data/backups
    

    Supongamos que existe:

    1750000000_2026_07_20_19.x.x_gitlab_backup.tar
    

    El identificador de la copia sería:

    1750000000_2026_07_20_19.x.x
    

    16.4. Ejecutar la restauración

    docker exec -it gitlab \
    gitlab-backup restore \
    BACKUP=1750000000_2026_07_20_19.x.x
    

    16.5. Reiniciar GitLab

    docker restart gitlab
    

    16.6. Comprobar la instalación

    docker exec -it gitlab gitlab-rake gitlab:check SANITIZE=true
    

    Fase 17. Actualización de GitLab

    No debemos actualizar una instalación estable utilizando latest sin revisar previamente los cambios.

    17.1. Consultar la imagen actual

    docker inspect gitlab \
    --format='{{.Config.Image}}'
    

    17.2. Crear una copia

    sudo /usr/local/sbin/copiar-gitlab.sh
    

    17.3. Cambiar la versión

    Editamos:

    nano /srv/gitlab/.env
    

    Cambiamos:

    GITLAB_IMAGE=gitlab/gitlab-ce:VERSION-ce.0
    

    17.4. Descargar y recrear el contenedor

    cd /srv/gitlab
    docker compose pull
    docker compose up -d
    

    17.5. Consultar los registros

    docker compose logs -f gitlab
    

    17.6. Comprobar el estado

    docker exec -it gitlab gitlab-rake gitlab:check SANITIZE=true
    

    GitLab recomienda crear una copia antes de actualizar. Para saltos grandes también puede exigir versiones intermedias obligatorias, por lo que no debe pasarse directamente de una versión muy antigua a la última sin revisar la ruta de actualización.


    Fase 18. Firewall básico

    18.1. Instalar UFW

    sudo apt install -y ufw
    

    18.2. Permitir SSH del servidor

    Antes de activar el firewall:

    sudo ufw allow OpenSSH
    

    18.3. Permitir GitLab

    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo ufw allow 2222/tcp
    

    18.4. Activar el firewall

    sudo ufw enable
    

    18.5. Consultar las reglas

    sudo ufw status numbered
    

    Resultado esperado:

    22/tcp    ALLOW
    80/tcp    ALLOW
    443/tcp   ALLOW
    2222/tcp  ALLOW
    

    Fase 19. Mantenimiento habitual

    19.1. Consultar contenedores

    docker ps
    

    19.2. Consultar el espacio ocupado

    docker system df
    
    sudo du -sh /srv/gitlab/*
    

    19.3. Consultar los registros recientes

    docker compose logs --tail=100 gitlab
    

    19.4. Reiniciar GitLab

    cd /srv/gitlab
    docker compose restart gitlab
    

    19.5. Detener GitLab

    docker compose stop
    

    19.6. Iniciar GitLab

    docker compose start
    

    19.7. Recrear el contenedor

    docker compose up -d
    

    19.8. Comprobar internamente GitLab

    docker exec -it gitlab gitlab-rake gitlab:check SANITIZE=true
    

    19.9. Consultar el estado de sus componentes

    docker exec -it gitlab gitlab-ctl status
    

    Fase 20. Comprobaciones finales

    Al terminar el proyecto deben cumplirse los siguientes puntos:

    • El servidor tiene una IP local fija.
    • El dominio apunta a la IP pública.
    • Los puertos 80, 443 y 2222 están redirigidos.
    • GitLab se abre mediante HTTPS.
    • El certificado es válido.
    • El registro público de usuarios está desactivado.
    • Los proyectos nuevos son privados.
    • Se ha creado un usuario personal.
    • La cuenta tiene autenticación de dos factores.
    • Cada ordenador dispone de su propia clave SSH.
    • Se puede clonar un repositorio.
    • Se pueden realizar pull, commit y push.
    • Un servidor externo puede clonar mediante una Deploy Key.
    • Existe un procedimiento de despliegue.
    • Se realizan copias automáticas.
    • Las copias se guardan fuera del disco principal.
    • Se conoce la versión exacta de GitLab.
    • Se ha probado al menos una restauración.

    Resultado final

    Al completar todas las fases tendremos una infraestructura personal parecida a esta:

                             INTERNET
                                 │
                      gitlab.tudominio.es
                                 │
                          HTTPS / SSH
                                 │
                             ROUTER
                                 │
                      ┌──────────┴──────────┐
                      │                     │
                   80/443                 2222
                      │                     │
                      └──────────┬──────────┘
                                 │
                        UBUNTU SERVER
                                 │
                          DOCKER COMPOSE
                                 │
                             GITLAB CE
                                 │
           ┌─────────────────────┼─────────────────────┐
           │                     │                     │
       Repositorios          Copias             CI/CD futuro
           │
     ┌─────┼─────────┬───────────────┐
     │     │         │               │
    PC   MacBook   Portátil      Servidor web
    

    El servidor GitLab será el punto central de trabajo, pero cada equipo conservará también una copia local de los repositorios que utilice.

    El flujo diario será:

    git pull
    

    Trabajar sobre el proyecto.

    git add .
    git commit -m "Descripción de los cambios"
    git push
    

    Y el flujo de despliegue inicial será:

    cd /var/www/proyecto
    git pull origin main
    

    Posteriormente podrá sustituirse por un pipeline automático de GitLab CI/CD.

  • Google Hacking

    Google Hacking

    Google Hacking es una técnica de búsqueda utilizada para encontrar información específica en los motores de búsqueda, como Google.

    [!NOTA]
    Este tipo de búsquedas no son invasivas, ya que no hacen peticiones al servidor del objetivo, por lo que podemos utilizar estas técnicas libremente.

    Google Hacking Database

    https://www.exploit-db.com/google-hacking-database

    La Google Hacking Database (GHDB) es una colección de comandos de búsqueda de Google y técnicas de búsqueda avanzadas que se utilizan para encontrar información que puede ser útil en la realización de pruebas de penetración y en la investigación de seguridad.

    La GHDB fue creada por Johnny Long, un experto en seguridad informática, y es mantenida por una comunidad de profesionales de la seguridad informática. La GHDB contiene miles de comandos de búsqueda de Google y técnicas de búsqueda avanzadas que se utilizan para encontrar información confidencial, como contraseñas, información de inicio de sesión, archivos de configuración, archivos de registro y más.

    Los comandos de búsqueda de Google en la GHDB se organizan en categorías, como «Vulnerabilities», «Files containing passwords» y «Sensitive Directories». Cada comando de búsqueda viene con una descripción detallada de lo que busca y cómo se puede utilizar.

    La GHDB se utiliza comúnmente en pruebas de penetración y en la investigación de seguridad para buscar información confidencial que puede ser utilizada en un ataque. Es importante tener en cuenta que la GHDB debe utilizarse con precaución y solo con el permiso del propietario del sitio web o de la red que se está probando. También es importante asegurarse de que cualquier información confidencial descubierta se informe al propietario del sitio web o a las autoridades apropiadas.

    Google Dorks

    Los Google Dorks son combinaciones específicas de palabras o frases que se usan para realizar búsquedas avanzadas en Google y obtener resultados que no se pueden obtener mediante una búsqueda normal.

    Es importante tener en cuenta que los Google Dorks no son herramientas de hacking en sí mismas, sino una técnica para realizar búsquedas avanzadas en Google. Sin embargo, los Google Dorks pueden ser utilizados por los hackers para encontrar información sensible que puede ser utilizada en ataques posteriores. Por lo tanto, se recomienda utilizar los Google Dorks de manera responsable y con fines éticos, especialmente si se utilizan en el campo de la seguridad informática.

    OperadorDescripciónEjemploExplicación del ejemplo
    site:Limita resultados a un dominio específico.site:example.comEncuentra todas las páginas accesibles en example.com.
    inurl:Busca un término dentro de la URL.inurl:loginLocaliza páginas de inicio de sesión.
    filetype:Filtra por tipo de archivo.filetype:pdfEncuentra documentos PDF descargables.
    intitle:Busca un término en el título de la página.intitle:"confidential report"Busca documentos titulados “informe confidencial” o similares.
    intext: / inbody:Busca dentro del cuerpo del texto.intext:"password reset"Encuentra páginas con “restablecimiento de contraseña”.
    cache:Muestra la versión en caché de Google.cache:example.comVe contenido antiguo o previo de example.com.
    link:Encuentra páginas que enlazan a otra.link:example.comMuestra webs que tienen enlaces hacia example.com.
    related:Encuentra páginas parecidas a otra.related:example.comDescubre sitios similares a example.com.
    info:Muestra información básica sobre un sitio.info:example.comTítulo, descripción y datos del sitio.
    define:Busca definiciones de una palabra.define:phishingObtiene la definición de phishing.
    numrange:Busca números dentro de un rango.site:example.com numrange:1000-2000Busca páginas de ese dominio con números entre 1000 y 2000.
    allintext:Todas las palabras deben aparecer en el texto.allintext:admin password resetLocaliza páginas que contienen ambas palabras.
    allinurl:Todas las palabras deben aparecer en la URL.allinurl:admin panelBusca URLs con “admin” y “panel”.
    allintitle:Todas las palabras deben estar en el título.allintitle:confidential report 2023Busca títulos con esas tres palabras.
    ANDExige que todos los términos aparezcan.site:example.com AND (inurl:admin OR inurl:login)Busca paneles admin o login en example.com.
    ORAcepta cualquiera de los términos."linux" OR "ubuntu" OR "debian"Busca páginas que mencionen cualquiera de esos sistemas.
    NOTExcluye resultados con un término.site:bank.com NOT inurl:loginExcluye las páginas de login.
    * (comodín)Sustituye cualquier palabra/caracter.site:socialnetwork.com filetype:pdf user* manualEncuentra “user guide”, “user manual”, etc.
    .. (rango)Busca valores dentro de un intervalo numérico.site:ecommerce.com "price" 100..500Busca productos entre 100 y 500.
    "" (comillas)Busca coincidencia exacta."information security policy"Busca esa frase exacta.
    - (menos)Excluye un término concreto.site:news.com -inurl:sportsNoticias sin resultados deportivos.

    Ejemplos de uso:

    Google DorkDescripción
    intitle:"Index of" password.txtMuestra directorios que contienen archivos llamados “password.txt”.
    intitle:"Index of" /adminMuestra directorios de administración.
    filetype:xls inurl:"email.xls"Muestra listados de emails expuestos.
    inurl:"login" site:example.comEncuentra páginas de inicio de sesión en un sitio concreto.
    filetype:log inurl:"password.log"Encuentra logs cuyo nombre contiene “password”.
    intitle:index.of id_rsa -id_rsa.pubEncuentra claves privadas SSH expuestas.
    site:.gov intitle:"secret" filetype:pdfEncuentra archivos PDF gubernamentales expuestos.
    intext:"Welcome to phpMyAdmin"Encuentra instalaciones de phpMyAdmin accesibles.
    inurl:/wp-content/uploads/ filetype:pdfBusca PDFs dentro de uploads de WordPress.
    intitle:"Index of" /backupEncuentra directorios de backups accesibles.
    site:example.com ext:sqlBusca bases de datos SQL en ese dominio.
    intitle:"index of" "database.sql"Busca archivos SQL expuestos.
    intitle:"SQL Injection" site:example.comEncuentra páginas del sitio que mencionan SQL Injection.
    site:example.com ext:docBusca documentos Word en ese sitio.
    site:example.com ext:xmlBusca archivos XML.
    site:example.com ext:confBusca archivos de configuración accesibles.
    inurl:"/cgi-bin/pass.txt"Busca archivos “pass.txt” en cgi-bin.
    intitle:"WebcamXP 5"Encuentra cámaras accesibles por WebcamXP 5.
    site:example.com inurl:configBusca archivos/configs dentro del sitio.
    intitle:"index of" intext:config.phpEncuentra directorios con config.php.
    intitle:"index of" intext:.htpasswdMuestra directorios con .htpasswd.
    intitle:"index of" intext:.envBusca directorios con archivos .env.
    intitle:"index of" "wp-content/uploads" site:example.comBusca uploads de WordPress indexados.
    filetype:xls inurl:"email.xls"Encuentra Excel que contienen “email.xls”.
    intext:"Powered by phpBB"Encuentra webs que usan phpBB.
    intext:"Powered by WordPress"Encuentra webs que usan WordPress.
    intext:"@outlook.com" site:example.comBusca correos @outlook.com dentro del sitio.
    inurl:/dana-na/ filetype:cgiBusca CGIs dentro de /dana-na/.
    inurl:server-info "Apache Server Information"Muestra información del servidor Apache.
    intext:"sql syntax near"Muestra webs con errores SQL visibles.
    intext:"confidential" site:example.comPáginas del sitio que contienen “confidencial”.
    inurl:/proc/self/cwdMuestra el directorio actual del servidor (grave exposición).
    intitle:"index of" intext:web.configDirectorios indexados con web.config.
    filetype:reg reg HKEY_CURRENT_USER usernameBusca archivos de registro que contengan “username”.
    inurl:"ViewerFrame?Mode="Encuentra cámaras accesibles por ese visor.
    intext:"powered by vBulletin"Encuentra webs que usan vBulletin.
    intitle:"index of" inurl:ftpFTPs accesibles de forma pública.
    intitle:"index of" "WhatsAppDB.csv"Directorios con bases de datos de WhatsApp expuestas.
    filetype:env intext:APP_ENVBusca archivos .env con info sensible.
    inurl:"/phpinfo.php"Encuentra páginas phpinfo expuestas.
    intitle:"index of" intext:sftp-config.jsonDirectorios con configuraciones SFTP.
    A continuación se muestran algunos ejemplos comunes de Google Dorks; para obtener más ejemplos, consulte la Google Hacking Database:

    Encontrar páginas de inicio de sesión:

    • site:example.com inurl:login
    • site:example.com (inurl:login OR inurl:admin)

    Identificar de archivos expuestos:

    • site:example.com filetype:pdf
    • site:example.com (filetype:xls OR filetype:docx)

    Descubrir archivos de configuración:

    • site:example.com inurl:config.php
    • site:example.com (ext:conf OR ext:cnf)(busca extensiones comúnmente utilizadas para archivos de configuración)

    Localizar copias de seguridad de bases de datos:

    • site:example.com inurl:backup
    • site:example.com filetype:sql

    Automatización: Google Dorking Helper

    Podemos automatizar la generación de Google Dorks con herramientas cómo Google Dorking Helper, que nos permite arrastrar operadores para ir construyendo nuestro dork. Una vez que lo hemos generado podemos darle directamente a «Buscar en Google» para abrirlo en el navegador.

    CASO DE USO: Detectando archivos expuestos en un dominio con Google Dorks

    Imagina que quieres comprobar example.com (o cualquier dominio propio de prácticas) expone algún archivo de configuración, backups o bases de datos de forma accidental.

    1. Entramos en GoogleDorks (la web recopilatoria)

    Hay varias webs que recopilan dorks ya probados, como:

    • Exploit-DB Google Hacking Database (GHDB)
    • googledorks.com
    • publicdorks repos en GitHub

    Las usan solo como referencia, nunca para atacar sistemas reales.

    2. Elegimos un dork útil para auditoría

    Por ejemplo, un clásico para detectar bases de datos expuestas:

    site:example.com ext:sql

    Este dork busca archivos .sql accesibles desde el navegador.

    3. Lo probamos en Google

    En un entorno de práctica (por ejemplo, un dominio controlado por el aula), lo que vemos es algo así:

    • /backup/database.sql
    • /db/export_2023.sql
    • /old/backup.sql

    Si Google muestra entradas similares, quiere decir que los archivos son accesibles públicamente y están indexados. Eso convierte una simple curiosidad en un aviso rojo.

    4. Interpretamos el resultado

    Les explicas a los alumnos:

    • Si Google lo indexa, quiere decir que el servidor lo publica sin restricciones
    • Esto no es hacking activo; es lectura pública de lo que ya está expuesto.
    • Archivos .sql suelen contener tablas, usuarios, hashes de contraseña, etc.

    Aquí entra tu guiño filosófico habitual: el buscador es como un telescopio enorme; si apuntas a una ventana con luz encendida, no estás entrando en la casa, solo ves lo que ellos dejaron abierto.

    5. Propones medidas de mitigación

    Esto les ayuda a cerrar el círculo mental del auditor:

    • Sacar carpetas de backup fuera del public_html o document root.
    • Configurar .htaccess o reglas en el servidor que impidan servir .sql, .env, .conf
    • Quitar directorios listados (“Index of”).
    • Desactivar el autoindex en Apache/Nginx.
    • Aplicar permisos adecuados del sistema.

    6. Otro ejemplo más avanzado desde GoogleDorks.com

    En GoogleDorks encuentran típicamente entradas como:

    intitle:"index of" /backup

    Lo combinan con su dominio de pruebas:

    site:example.com intitle:"index of" /backup

    Resultado (en un entorno controlado):
    Google podría mostrar un listado de backups accesibles.

    Aquí se ve el poder del dork: localizar un error de configuración sin escaneo activo ni intrusiones.

    CASO DE USO: “Ventanas Abiertas en la Red”

    La pantalla parpadea. No estás hackeando nada. Solo observas. Lo que Google muestra es lo que ya estaba ahí, flotando en la superficie como un mensaje en una botella. Elliot lo explica con su serenidad afilada:

    «El buscador es un espejo gigante. Refleja lo que los servidores enseñan sin darse cuenta. Si sabes dónde mirar, puedes encontrar más de lo que cualquier administrador admitiría».

    Elliot abre una pestaña, teclea despacio, casi ritual:

    site:example.com ext:sql

    Darlene levanta una ceja. «¿Ya? ¿Así de simple?»

    Él asiente. «El truco nunca es forzar la cerradura; es descubrir que la puerta estaba abierta desde siempre».

    La búsqueda devuelve un par de enlaces inocentes: /backup/database.sql, /old/export_2022.sql. Como si fuera normal. Como si no contuvieran medio corazón de ese servidor, latido a latido.

    Darlene sonríe, ese tipo de sonrisa que solo aparece cuando ve un fallo que podría haberse evitado con dos minutos de atención. «Archivos SQL, backups… Esto es como dejar el diario íntimo abierto en medio de la calle», murmura.

    Elliot continúa:

    «O mira este, es más evidente»:

    intitle:"index of" /backup

    La pantalla muestra un directorio listado. El índice, los archivos, las fechas. Casi puedes sentir la gravedad del error. Es información pública; Google solo la ha descubierto primero.

    Elliot apoya los codos en la mesa.

    «Esto es Google Dorking. Nada ilegal. Buscamos lo que ya está expuesto. Como revisar los candados de tu propia casa. Y si encuentras una ventana rota, la arreglas antes de que otro la vea».

    Darlene mira al techo. «La gente piensa que la seguridad es un bunker. Pero casi siempre es una persiana mal echada».

    Los dos siguen navegando entre dorks como quien pasea entre sombras familiares. No hay urgencia, solo una especie de calma lúcida: la fase previa a cualquier intrusión ética, el territorio gris donde la información pública se mezcla con la negligencia.

    Elliot concluye, casi en un susurro:
    «El buscador es el confidente más indiscreto de internet. Si le preguntas bien, te lo cuenta todo».

    Buscadores alternativos y meta-buscadores

    Cuando Google te cierra puertas, otros motores silenciosos dejan ventanas abiertas. No son magia negra; simplemente indexan distinto.

    DuckDuckGo
    – Respeta privacidad y deja ver cosas que Google a veces filtra.

    Shodan
    – El “Google del IoT”: cámaras, routers, PLCs, servidores expuestos.
    – Ideal para investigación forense o ética.

    Censys
    – Similar a Shodan pero con enfoque más académico.
    – Perfecto para investigaciones de superficie de ataque.

    Bing + Yandex
    – Indexan directorios de manera más permisiva en algunos casos.


    Herramientas que automatizan Google Dorks (con cabeza)

    No siempre quieres escribir cien consultas a mano. Estas herramientas generan, prueban y organizan dorks.

    GHDB – Google Hacking Database (Exploit-DB)
    – La biblia. Miles de dorks clasificados por categorías (login pages, archivos sensibles, cámaras…).
    – La referencia imprescindible.

    DorkSearch / DorkTester
    – Pequeñas herramientas web para probar dorks rápidamente.
    – Útiles para investigaciones rápidas sin automatizar demasiado.

    Dork-Scanner (Python)
    – Frameworks que lanzan series de dorks y analizan respuestas.
    – Exigen ética e IP propia porque Google puede bloquearte.

    Katana + Nuclei (ProjectDiscovery)
    – No son dorks, pero se llevan muy bien con ellos.
    – Puedes sacar URLs con Katana y luego comprobar hallazgos con Nuclei.


    Extensiones de navegador

    No subestimes las pequeñas utilidades de un clic.

    Google Search Operators Helper
    – Te rellena operadores avanzados.

    Search Diggity (BishopFox)
    – Conjunto de herramientas de OSINT con módulos de dorking seguro.
    – Muy usado en auditorías.


    Herramientas OSINT que complementan Google Dorks

    Porque un dork es solo un portal: después debes investigar.

    theHarvester
    – Extrae correos, dominios, hosts desde motores de búsqueda.
    – Combinación perfecta con filetype:xls, pdf, txt…

    FOCA
    – Analiza metadatos de documentos encontrados con dorks.
    – Joyas ocultas en PDFs y Word.

    SpiderFoot
    – Rastrea información relacionada con dominios, subdominios y filtraciones.

    Amass
    – Recon de subdominios.
    – Combinado con site: y inurl: puedes descubrir puertas laterales.


    Herramientas forenses relacionadas

    Cuando los dorks son parte de una investigación forense, estos compañeros hacen el resto:

    Wayback Machine (Archive.org)
    – Para ver versiones antiguas de páginas descubiertas con dorks.
    – Oro puro cuando el contenido ha sido borrado.

    Exiftool
    – Para explorar metadatos de imágenes encontradas.

    Binwalk
    – Si encuentras firmware expuesto con un dork (sí, pasa), esta herramienta lo destripa.


    Pequeño “arsenal” recomendado según objetivo

    Localizar archivos sensibles: Google + GHDB + FOCA
    Enumerar infraestructura: Google + Shodan + Amass
    Investigación forense: Google + Wayback + Exiftool
    Bug bounty: GHDB + Dork-scanner + Nuclei

  • Actividad: Mi primera guía en Markdown

    Actividad: Mi primera guía en Markdown

    1. Introducción

    En esta actividad aprenderás a crear un documento utilizando Markdown.

    Markdown permite elaborar documentación mediante archivos de texto con extensión .md. Se utiliza habitualmente para documentar proyectos informáticos en plataformas como GitHub y GitLab.

    En esta actividad no tendrás que instalar, programar ni configurar ningún servicio. El objetivo es únicamente aprender a crear documentación clara, ordenada y visual.

    2. Tarea que debes realizar

    Debes crear una guía titulada:

    Cómo organizar archivos y carpetas en un ordenador

    La guía explicará cómo crear y organizar una carpeta para una asignatura.

    La estructura que deberás explicar será parecida a esta:

    ASIR/
    ├── Implantación de Aplicaciones Web/
    │   ├── Apuntes/
    │   ├── Actividades/
    │   └── Proyecto/
    └── Seguridad y Alta Disponibilidad/
        ├── Apuntes/
        ├── Actividades/
        └── Proyecto/

    Puedes realizar las capturas en Windows, macOS o Linux.

    3. Objetivos

    Al finalizar la actividad deberás saber:

    • Crear un archivo README.md.
    • Escribir títulos y subtítulos.
    • Crear párrafos y listas.
    • Utilizar negrita y cursiva.
    • Insertar imágenes.
    • Crear enlaces.
    • Mostrar correctamente una estructura de carpetas.
    • Visualizar un documento Markdown.
    • Organizar los archivos de una documentación.

    4. Preparación de la actividad

    Crea una carpeta llamada:

    actividad-01-markdown

    Dentro de ella crea la siguiente estructura:

    actividad-01-markdown/
    ├── README.md
    └── img/

    El archivo README.md contendrá la documentación.

    La carpeta img contendrá las imágenes utilizadas en el documento.

    5. Herramientas

    Puedes utilizar:

    • Visual Studio Code para escribir el documento.
    • El explorador de archivos de tu sistema operativo.
    • La herramienta de captura de pantalla de Windows, macOS o Linux.

    No es necesario instalar programas adicionales.

    6. Contenido obligatorio del README

    Tu documento deberá contener los siguientes apartados.

    6.1 Título

    El documento comenzará con un título principal:

    # Cómo organizar archivos y carpetas en un ordenador

    6.2 Introducción

    Escribe un pequeño párrafo explicando por qué es importante mantener organizados los archivos.

    El texto debe estar redactado con tus propias palabras.

    6.3 Material necesario

    Crea una lista que indique lo necesario para seguir la guía.

    Ejemplo:

    ## Material necesario
    
    - Un ordenador.
    - Un sistema operativo.
    - Acceso al explorador de archivos.

    6.4 Procedimiento

    Explica cómo crear la estructura de carpetas.

    Debes dividir el procedimiento en pasos:

    ## Procedimiento
    
    ### Paso 1. Crear la carpeta principal
    
    Explicación del primer paso.
    
    ### Paso 2. Crear las carpetas de las asignaturas
    
    Explicación del segundo paso.
    
    ### Paso 3. Crear las subcarpetas
    
    Explicación del tercer paso.

    Cada paso deberá incluir:

    • Un subtítulo.
    • Una explicación.
    • Una captura de pantalla.

    6.5 Resultado final

    Incluye una captura en la que se vea la estructura completa de carpetas.

    Debajo de la captura, explica brevemente el resultado obtenido.

    6.6 Ventajas de organizar los archivos

    Incluye una lista con al menos tres ventajas.

    Por ejemplo:

    • Encontrar los archivos con mayor rapidez.
    • Evitar la pérdida de trabajos.
    • Separar los contenidos de cada asignatura.

    6.7 Enlace externo

    Añade un enlace a una página relacionada con la organización de archivos, Markdown o Visual Studio Code.

    La sintaxis es:

    [Texto que verá el lector](https://direccion-de-la-pagina.es)

    6.8 Conclusiones

    Escribe un párrafo final respondiendo a estas preguntas:

    • ¿Qué has aprendido?
    • ¿Qué parte te ha resultado más fácil?
    • ¿Qué dificultad has encontrado?
    • ¿Para qué crees que puede servir un README?

    No debes copiar las preguntas. Utilízalas como orientación para redactar tu conclusión.

    7. Cómo insertar las imágenes

    Guarda todas las capturas dentro de la carpeta img.

    Utiliza nombres descriptivos y sin espacios:

    img/
    ├── carpeta-principal.png
    ├── carpetas-asignaturas.png
    └── resultado-final.png

    Para insertar una imagen en el README utiliza:

    ![Descripción de la imagen](img/carpeta-principal.png)

    No utilices nombres como:

    Captura de pantalla 2026-09-09.png
    foto1.png
    imagen nueva final.png

    Utiliza nombres que permitan reconocer el contenido:

    crear-carpeta-principal.png
    estructura-asignaturas.png
    resultado-final.png

    8. Requisitos de las capturas

    Las capturas deberán:

    • Mostrar únicamente la zona necesaria.
    • Tener suficiente calidad para poder leerlas.
    • Estar relacionadas con la explicación.
    • Aparecer después del paso que representan.
    • No mostrar contraseñas ni información personal.
    • Incluir un texto alternativo descriptivo.

    No se admitirán capturas sin una explicación asociada.

    9. Formato Markdown obligatorio

    El documento deberá utilizar, como mínimo:

    • Un título principal.
    • Cinco subtítulos.
    • Una lista con viñetas.
    • Una lista numerada.
    • Texto en negrita.
    • Texto en cursiva.
    • Tres imágenes.
    • Un enlace externo.
    • Un bloque con la estructura de carpetas.

    10. Visualización del documento

    Abre README.md con Visual Studio Code.

    Para mostrar su vista previa:

    • En Windows y Linux: Ctrl + Shift + V
    • En macOS: Cmd + Shift + V

    También puedes utilizar el botón de vista previa situado en la esquina superior derecha del editor.

    Antes de entregar, comprueba que:

    • Los títulos se muestran correctamente.
    • Las imágenes aparecen.
    • El enlace funciona.
    • No se ven los símbolos de Markdown en la vista previa.
    • No hay apartados vacíos.

    11. Entrega

    Debes entregar una carpeta comprimida llamada:

    apellido-nombre-actividad-01.zip

    Ejemplo:

    garcia-ana-actividad-01.zip

    El archivo comprimido deberá contener:

    actividad-01-markdown/
    ├── README.md
    └── img/
        ├── crear-carpeta-principal.png
        ├── estructura-asignaturas.png
        └── resultado-final.png

    No debes entregar un documento Word ni convertir el README a PDF.

    12. Lista de comprobación

    Antes de entregar, comprueba lo siguiente:

    • El archivo se llama README.md.
    • El README contiene un título principal.
    • He utilizado títulos y subtítulos.
    • He incluido al menos tres imágenes.
    • Las imágenes están guardadas en img.
    • Todas las imágenes se muestran en la vista previa.
    • He utilizado negrita y cursiva.
    • He creado una lista.
    • He añadido un enlace.
    • He escrito una conclusión personal.
    • He revisado la ortografía.
    • La carpeta tiene el nombre solicitado.