# PRACTICA: Nginx como proxy

### Escenario Real: TechStore S.L. <a href="#escenario-real-techstore-sl" id="escenario-real-techstore-sl"></a>

> TechStore es una tienda online de productos tecnológicos que necesita dos entornos: **desarrollo** (para pruebas del equipo) y **producción** (acceso público). El objetivo es configurar Nginx en máquinas virtuales para enrutar tráfico según parámetros y virtual hosts, simulando infraestructura empresarial.

* **Dominios**: `techstore.local` (sitio principal), `admin.techstore.local` (panel administración)

En esta práctica nginx actuará como **intermediario inteligente** entre los clientes (navegadores) y los servidores backend (VM2). Recibe todas las peticiones HTTP en el puerto 80 y decide a qué backend reenviarlas según reglas configuradas.

* Los clientes solo conocerán la IP del gateway (MV2 - 10.0.0.10)​
* Nginx reenviará peticiones a backends internos.
* Oculta la arquitectura real y protege servidores backend

```
Cliente (navegador)
    ↓ Solicita: techstore.local/?env=dev
[VM1 Nginx - Proxy Inverso]
    ↓ Analiza parámetro ?env=dev
    ↓ Traduce a: http://192.168.56.11:8080
[VM2 Backend - Puerto 8080]
    ↓ Responde con HTML desarrollo
[VM1 Nginx]
    ↓ Reenvía respuesta al cliente
Cliente ve contenido sin saber origen real
```

<figure><img src="https://539580950-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiKvwltOme7zTxep3LVyW%2Fuploads%2FEXvNgBxHCYWxzP8Ofm0c%2Fimage.png?alt=media&#x26;token=4d378370-96b7-42f0-9284-b99a6f9b4bf2" alt="" width="563"><figcaption></figcaption></figure>

El cliente nunca accede directamente a VM2, siempre pasa por el proxy Nginx en VM1, que además añade headers como `X-Real-IP` y `X-Forwarded-For` para que los backends sepan la IP original del cliente.

***

## Paso 1: Crear VMs en VirtualBox <a href="#parte-1-preparacin-de-las-mquinas-virtuales" id="parte-1-preparacin-de-las-mquinas-virtuales"></a>

1. Crea **VM1 - Nginx Gateway**:
   * Red NAT con IP estática: 10.0.0.10/24
2. Crea **VM2 - Backend Servers**:
   * Red NAT con IP estática: 10.0.0.11/24

{% hint style="info" %}
Para configurar las IP estáticas recuerda editar `/etc/netplan/*.yaml`

```yaml
network:
  version: 2
  ethernets:
    enp0s3:
      addresses: [10.0.0.10/24]
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]
```

Aplicar: `sudo netplan apply`
{% endhint %}

Verifica conectividad con `ping` desde VM1 y viceversa.

***

## Paso 2: Configuración Backend (VM2) <a href="#parte-2-configuracin-backend-vm2" id="parte-2-configuracin-backend-vm2"></a>

### 2.1 Instalar Nginx y Node.js

```bash
sudo apt update && sudo apt upgrade -y
sudo apt install -y nginx nodejs npm
sudo systemctl enable nginx
```

En esta máquina configuraremos dos webs diferentes con dos sites diferentes. Un site sera el de "development" y el otro sera de "production". Adicionalmente le añadiremos un panel de administración por lo que repetiremos el mismo proceso tres veces:

### 2.2 Crear Aplicación TechStore - Entorno Desarrollo

```bash
sudo mkdir -p /var/www/techstore-dev
sudo chown -R $USER:$USER /var/www/techstore-dev
nano /var/www/techstore-dev/index.html
```

<details>

<summary><strong>Contenido de la web (Entorno dev):</strong></summary>

```html
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TechStore - Desarrollo</title>
    <style>
        body { font-family: Arial; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 
               color: white; text-align: center; padding: 50px; }
        .container { background: rgba(255,255,255,0.1); padding: 40px; border-radius: 15px; }
        .badge { background: #ffc107; color: black; padding: 10px 20px; border-radius: 20px; }
        .products { display: flex; justify-content: center; gap: 20px; margin-top: 30px; }
        .product { background: white; color: black; padding: 20px; border-radius: 10px; width: 200px; }
    </style>
</head>
<body>
    <div class="container">
        <h1>🛒 TechStore S.L.</h1>
        <div class="badge">ENTORNO DE DESARROLLO</div>
        <p>Backend Server: 10.0.0.11:8080</p>
        <div class="products">
            <div class="product">
                <h3>💻 Laptop Dell XPS</h3>
                <p>€1299 [TEST PRICE]</p>
            </div>
            <div class="product">
                <h3>🖱️ Ratón Logitech</h3>
                <p>€45 [BETA]</p>
            </div>
        </div>
        <p style="margin-top: 30px; font-size: 12px;">Version: 2.1.0-dev | Build: 2026-02-09</p>
    </div>
</body>
</html>
```

</details>

### 2.3 Crear Aplicación TechStore - Entorno Producción

```bash
sudo mkdir -p /var/www/techstore-prod
sudo chown -R $USER:$USER /var/www/techstore-prod
nano /var/www/techstore-prod/index.html
```

<details>

<summary><strong>Contenido de la web (Entorno Prod)</strong>:</summary>

```html
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TechStore - Tienda Oficial</title>
    <style>
        body { font-family: Arial; background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%); 
               color: white; text-align: center; padding: 50px; }
        .container { background: rgba(255,255,255,0.1); padding: 40px; border-radius: 15px; }
        .badge { background: #e74c3c; color: white; padding: 10px 20px; border-radius: 20px; }
        .products { display: flex; justify-content: center; gap: 20px; margin-top: 30px; }
        .product { background: white; color: black; padding: 20px; border-radius: 10px; width: 200px; }
        button { background: #e74c3c; color: white; border: none; padding: 10px 20px; 
                border-radius: 5px; cursor: pointer; margin-top: 10px; }
    </style>
</head>
<body>
    <div class="container">
        <h1>🛒 TechStore S.L.</h1>
        <div class="badge">PRODUCCIÓN</div>
        <p>Servidor Oficial - Alta Disponibilidad</p>
        <div class="products">
            <div class="product">
                <h3>💻 Laptop Dell XPS 15</h3>
                <p><strong>€1499</strong></p>
                <button>Comprar Ahora</button>
            </div>
            <div class="product">
                <h3>🖱️ Ratón Logitech MX Master</h3>
                <p><strong>€89</strong></p>
                <button>Añadir al Carrito</button>
            </div>
        </div>
        <p style="margin-top: 30px; font-size: 12px;">© 2026 TechStore S.L. | Version: 2.0.5</p>
    </div>
</body>
</html>
```

</details>

### 2.4 Crear Panel de Administración

```bash
sudo mkdir -p /var/www/admin-panel
sudo chown -R $USER:$USER /var/www/admin-panel
nano /var/www/admin-panel/index.html
```

<details>

<summary><strong>Contenido HTML (Admin)</strong>:</summary>

```html
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Panel Admin - TechStore</title>
    <style>
        body { font-family: 'Courier New'; background: #1e1e1e; color: #0f0; padding: 20px; }
        .terminal { background: black; padding: 20px; border-radius: 5px; border: 2px solid #0f0; }
        h1 { color: #ff6b6b; }
        table { width: 100%; margin-top: 20px; border-collapse: collapse; }
        th, td { border: 1px solid #0f0; padding: 10px; text-align: left; }
        th { background: #333; }
    </style>
</head>
<body>
    <div class="terminal">
        <h1>⚙️ PANEL DE ADMINISTRACIÓN</h1>
        <p>> Sistema de gestión TechStore</p>
        <p>> Servidor: backend-servers (10.0.0.11:9090)</p>
        <table>
            <tr><th>Métrica</th><th>Valor</th></tr>
            <tr><td>Pedidos Hoy</td><td>47</td></tr>
            <tr><td>Usuarios Activos</td><td>1.203</td></tr>
            <tr><td>Stock Crítico</td><td>3 productos</td></tr>
        </table>
        <p style="margin-top: 20px;">> Acceso permitido desde Nginx Gateway</p>
    </div>
</body>
</html>
```

</details>

### 2.5 Configurar Nginx en VM2 (Puertos Múltiples)

Crearemos un server (virtualhost) en nginx de los tres backends cada uno en un puerto diferente:

```bash
sudo nano /etc/nginx/sites-available/techstore-backends
```

Cuya configuración será la siguiente:

```nginx
# Entorno Desarrollo - Puerto 8080
server {
    listen 8080;
    listen [::]:8080;
    root /var/www/techstore-dev;
    index index.html;
    server_name _;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

# Entorno Producción - Puerto 8081
server {
    listen 8081;
    listen [::]:8081;
    root /var/www/techstore-prod;
    index index.html;
    server_name _;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

# Panel Admin - Puerto 9090
server {
    listen 9090;
    listen [::]:9090;
    root /var/www/admin-panel;
    index index.html;
    server_name _;
    
    location / {
        try_files $uri $uri/ =404;
    }
}
```

{% hint style="info" %}
Nota que lo único que cambia es el puerto y la carpeta donde se encuentra el contenido a desplegar. En esta configuración no ponemos nada de dominios ni URL solamente funcionaremos por puerto (de ahí el tema de gateway nginx).
{% endhint %}

Activar configuración:

```bash
sudo ln -s /etc/nginx/sites-available/techstore-backends /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl restart nginx
```

Puedes verificar puertos con:

&#x20;`sudo netstat -tlnp | grep nginx` (debe mostrar 8080, 8081, 9090)

Instala netstat con sudo apt install netstat.

***

## Paso 3: Configuración Nginx Gateway (VM1) <a href="#parte-3-configuracin-nginx-gateway-vm1" id="parte-3-configuracin-nginx-gateway-vm1"></a>

En esta máquina lo que configuraremos será el proxy que reenviará las peticiones al backend según parámetros. Los primeros pasos serán los mismos en ambas máquinas:

### 3.1 Instalar Nginx

```bash
sudo apt update && sudo apt install -y nginx
sudo systemctl enable nginx
```

### 3.2 Crear Página de Bienvenida Principal

```bash
sudo mkdir -p /var/www/techstore-main
sudo chown -R $USER:$USER /var/www/techstore-main
nano /var/www/techstore-main/index.html
```

<details>

<summary>Contenido:</summary>

```html
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>TechStore - Bienvenida</title>
    <style>
        body { font-family: Arial; background: #34495e; color: white; text-align: center; padding: 100px; }
        .btn { display: inline-block; margin: 20px; padding: 20px 40px; background: #3498db; 
               color: white; text-decoration: none; border-radius: 5px; font-size: 18px; }
        .btn:hover { background: #2980b9; }
    </style>
</head>
<body>
    <h1>🌐 TechStore - Gateway Nginx</h1>
    <p>Selecciona entorno de acceso:</p>
    <a href="/?env=prod" class="btn">🟢 Producción</a>
    <a href="/?env=dev" class="btn">🟡 Desarrollo</a>
    <p style="margin-top: 50px; font-size: 14px;">Administración: <a href="http://admin.techstore.local" style="color: #e74c3c;">Panel Admin</a></p>
</body>
</html>
```

</details>

* Nota como podremos pasar de una a otro con los botones tan solo cambiando el parámetro de "`/?env=prod`" del navegador gracias al protocolo HTTP.

### 3.3 Configuración Maestro Nginx con Routing Inteligente

Para esto simplemente crearemos otro server (virtualhost) en esta máquina

```bash
sudo nano /etc/nginx/sites-available/techstore-gateway
```

Con la siguiente configuración completa:

```nginx
# Mapa para traducir parámetro env a puerto backend
map $arg_env $backend_port {
    default 8081;  # Por defecto producción
    "dev"   8080;  # Desarrollo
    "prod"  8081;  # Producción explícita
}

# Sitio Principal - techstore.local
server {
    listen 80;
    listen [::]:80;
    server_name techstore.local www.techstore.local;
    
    # Logs específicos
    access_log /var/log/nginx/techstore-access.log;
    error_log /var/log/nginx/techstore-error.log;
    
    # Si viene parámetro ?env, hacer proxy a backend correspondiente
    location / {
        if ($arg_env != "") {
            proxy_pass http://10.0.0.11:$backend_port;
            break;
        }
        
        # Sin parámetro: mostrar página de bienvenida
        root /var/www/techstore-main;
        index index.html;
        try_files $uri $uri/ =404;
    }
    
    # Headers de seguridad
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Gateway "Nginx-TechStore" always;
}

# Panel de Administración - admin.techstore.local
server {
    listen 80;
    listen [::]:80;
    server_name admin.techstore.local;
    
    access_log /var/log/nginx/admin-access.log;
    error_log /var/log/nginx/admin-error.log;
    
    location / {
        proxy_pass http://192.168.56.11:9090;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
```

Activar:

```bash
sudo ln -s /etc/nginx/sites-available/techstore-gateway /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl restart nginx
```

***

## Parte 4: Verificación <a href="#parte-4-configuracin-dns-local-mquina-host" id="parte-4-configuracin-dns-local-mquina-host"></a>

### 4.1 Editar Hosts en Linux/Mac

Para la verificación podemos usar una máquina virtual ubuntu desktop con mozilla para hacer las verificaciones por dominio. Esta máquina debe estar conectada dentro la misma red NAT.

Primero para evitarnos temas de DNS vamos a ir a lo sencillo y vamos a editar el archivo hosts:

```bash
sudo nano /etc/hosts
```

Añadir:

```
10.0.0.10 techstore.local www.techstore.local
10.0.0.10 admin.techstore.local
```

**Ahora desde un navegador en host y deberias comprobar:**

| URL                                | Resultado Esperado            | Verificación                      |
| ---------------------------------- | ----------------------------- | --------------------------------- |
| `http://techstore.local/`          | Página bienvenida con botones | Fondo gris, 2 botones visibles    |
| `http://techstore.local/?env=prod` | TechStore PRODUCCIÓN (verde)  | Precios €1499/€89, botones compra |
| `http://techstore.local/?env=dev`  | TechStore DESARROLLO (morado) | Badge "DESARROLLO", precios test  |
| `http://admin.techstore.local/`    | Panel admin terminal negro    | Tabla métricas, fondo negro/verde |

### 4.3 Pruebas con cURL

**En caso que no dispongas suficiente RAM puedes hacer las verificaciones desde la propia maquina VM1 o host con los siguientes comandos:**

```bash
# Verificar routing desarrollo
curl -s "http://techstore.local/?env=dev" | grep "DESARROLLO"

# Verificar routing producción
curl -s "http://techstore.local/?env=prod" | grep "PRODUCCIÓN"

# Verificar admin
curl -s "http://admin.techstore.local/" | grep "ADMINISTRACIÓN"

# Test múltiples requests
for i in {1..10}; do
    ENV=$(shuf -e dev prod -n1)
    echo "Request $i → Env: $ENV"
    curl -s "http://techstore.local/?env=$ENV" | grep -o "ENTORNO DE [A-Z]*"
done
```

### 4.4 Análisis de Logs

**Revisa los logs en VM1 con:**

```bash
# Ver accesos en tiempo real
sudo tail -f /var/log/nginx/techstore-access.log

# Contar requests por parámetro env
sudo grep "env=dev" /var/log/nginx/techstore-access.log | wc -l
sudo grep "env=prod" /var/log/nginx/techstore-access.log | wc -l

# Verificar admin
sudo tail /var/log/nginx/admin-access.log
```
