← Volver al índice

Guía Paso a Paso: Búnker de Seguridad Perimetral con Nginx y Docker

Nginx Docker Compose Backend API Ciberseguridad

Objetivo de esta guía: Documentar el diseño de un "Búnker de Seguridad" perimetral para aislar un backend API de acceso público. Aplicamos los principios de Defensa en Profundidad (Zero Trust) y Mínimo Privilegio, restringiendo el tamaño máximo de los cuerpos de petición, mitigando ataques de denegación de servicio (DDoS/Slowloris) y garantizando la trazabilidad forense de logs mediante Nginx.

1. Arquitectura de Aislamiento en Profundidad (Zero Trust)

En la ingeniería de seguridad de infraestructura, exponer una base de datos relacional o una aplicación Java directamente a internet representa un riesgo inaceptable. Los escáneres automatizados detectan constantemente puertos abiertos (como el 8080 o 5432) intentando explotar vulnerabilidades conocidas (CVEs) o lanzar ataques de fuerza bruta.

Para mitigar este vector de ataque, aplicamos una arquitectura de Defensa en Profundidad. La base de datos y la API backend se ejecutan completamente "sordas" e invisibles al exterior dentro de una red privada virtual de Docker (secure_net). Nginx se sitúa en la frontera como un embudo de seguridad, filtrando cada petición antes de transmitirla a los contenedores internos.

Aislamiento Físico Garantizado: El backend y la base de datos PostgreSQL carecen de mapeo de puertos hacia la máquina host. Únicamente el contenedor de Nginx puede comunicarse con ellos por la red interna de Docker, y Nginx solo acepta conexiones locales originadas por el proxy Apache principal.
graph LR User((Cliente Web / App)) -- HTTPS/443 --> Apache[Apache Reverse Proxy] subgraph "Servidor Host (Linux)" Apache -- 127.0.0.1:8081 --> Nginx[Docker Nginx :80] subgraph "Red Privada Docker (secure_net)" Nginx -- Proxy Pass interno --> Backend[Docker Backend API :8080] Backend -- Red interna --> DB[(Base de Datos PostgreSQL :5432)] end end style Apache fill:#ffecb3,stroke:#fbc02d,stroke-width:2px style Nginx fill:#c8e6c9,stroke:#388e3c,stroke-width:2px style Backend fill:#ffcc80,stroke:#e65100,stroke-width:2px style DB fill:#bbdefb,stroke:#1976d2,stroke-width:2px

2. Aislamiento Físico mediante Docker Compose

Configuramos la infraestructura de contenedores de modo que la directiva ports sea suprimida por completo en el servicio del backend. Al eliminar el binding de puertos, Docker no crea ninguna interfaz de escucha en la máquina física para ese contenedor, volviéndolo inaccesible ante escaneos de IP pública.

El contenedor proxy_nginx expone su puerto 80 amarrado estrictamente a la interfaz de bucle local 127.0.0.1:8081, lo que impide que atacantes externos intenten saltarse la primera capa de cortafuegos conectándose directamente a la IP pública por el puerto 8081.

📄 docker-compose.yml (Declaración de Red Segura)
services: api_backend: build: . container_name: app_backend restart: always # AISLAMIENTO TOTAL: Se elimina 'ports' para hacerlo invisible en la máquina host networks: - secure_net proxy_nginx: image: nginx:alpine container_name: app_nginx ports: # RESTRICCIÓN PERIMETRAL: Expuesto SOLO al bucle local 127.0.0.1 - "127.0.0.1:8081:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - api_backend networks: - secure_net networks: secure_net: driver: bridge
Justificación de Diseño: Si un atacante ejecuta un escaneo masivo de puertos (ej. nmap) sobre la IP pública del servidor, Nginx permanecerá totalmente invisible porque sólo responde a llamadas originadas internamente dentro del propio servidor host.

3. Defensas Activas: Cortafuegos de Aplicación en Nginx

Partiendo del principio de Zero Trust (Confianza Cero), asumimos que cualquier tráfico entrante es potencialmente malicioso. Por ello, configuramos en Nginx políticas de estrangulamiento de peticiones y restricciones de tamaño basadas en el perfil de uso real de la API.

📄 nginx.conf (Bloque HTTP - Rate Limiting & Ocultación)
http { # 1. Ocultar la versión de Nginx en las cabeceras HTTP (Dificulta el perfilado de vulnerabilidades CVE) server_tokens off; # 2. Asignar 10MB de RAM para rastrear IPs y limitar el tráfico a un máximo de 5 peticiones por segundo limit_req_zone $binary_remote_addr zone=api_limit:10m rate=5r/s; upstream backend_servers { server api_backend:8080; } }

3.1. Reglas de Protección Anti-Exploit (Bloque Server)

Dentro de la configuración del servidor virtual de Nginx, aplicamos barreras diseñadas para descartar cargas maliciosas en la capa de red antes de que lleguen a consumir memoria o hilos de procesamiento en la aplicación Spring Boot.

Un Payload JSON legítimo emitido por una caja registradora Novapay ocupa entre 2KB y 4KB. Al establecer un límite de 56KB, proporcionamos un margen de tolerancia amplio para peticiones legítimas mientras bloqueamos de inmediato (devuelviendo HTTP 413 Payload Too Large) cualquier intento de inyección de binarios o ataques de desbordamiento de búfer.

📄 nginx.conf (Bloque Server - Barreras de Protección)
server { listen 80; # BARRERA 1: Límite estricto de tamaño de cuerpo (56 Kilobytes máximo) client_max_body_size 56k; # BARRERA 2: Timeouts defensivos contra ataques Slowloris (Corte a 10s) client_body_timeout 10s; client_header_timeout 10s; send_timeout 10s; location / { # BARRERA 3: Aplicar Rate Limiting (Permite ráfaga puntual de 10 peticiones sin retardo) limit_req zone=api_limit burst=10 nodelay; proxy_pass http://backend_servers; } }

4. Auditoría Forense y Trazabilidad de IPs en Logs

Debido a que la petición atraviesa múltiples capas de proxies (Cliente → Apache → Nginx → Backend Java), por defecto la IP origen que registraría el backend sería 127.0.0.1. Para mantener una trazabilidad forense completa en caso de incidente de seguridad, Nginx captura e inyecta las cabeceras HTTP X-Real-IP y X-Forwarded-For.

📄 nginx.conf (Propagación de Cabeceras e Formato de Log)
# Formato de log personalizado para capturar IP cliente real y User-Agent log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; location / { # Propagar la IP pública original hacia los contenedores de la red interna proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://backend_servers; }

4.1. Comandos Operativos de Inspección de Incidentes

Comandos de terminal para auditar en tiempo real las peticiones bloqueadas por las defensas perimetrales de Nginx:

# Monitorizar el flujo de logs en tiempo real atravesando el Proxy
docker logs -f app_nginx
# Filtrar las IPs que han sido bloqueadas por exceso de peticiones (Rate Limiting)
docker logs app_nginx | grep "limiting requests"
# Identificar intentos de ataques por inyección de payloads mayores a 56KB
docker logs app_nginx | grep "client intended to send too large body"
← Volver a la portada ↑ Volver arriba
🏠