Nginx como Proxy Inverso

Nginx es uno de los servidores proxy inversos más potentes y ampliamente utilizados en la infraestructura web moderna. Como proxy inverso, Nginx se sitúa entre las solicitudes de los clientes y los servidores backend, reenviando solicitudes y respuestas mientras proporciona balanceo de carga, terminación SSL, caché y características de seguridad. Esta guía completa te enseñará cómo configurar Nginx como proxy inverso, permitiéndote construir aplicaciones web escalables, seguras y de alto rendimiento.

Ya sea que estés ejecutando microservicios, aplicaciones en contenedores, servidores Node.js o aplicaciones web tradicionales, implementar Nginx como proxy inverso proporciona beneficios críticos que incluyen seguridad mejorada, rendimiento mejorado a través del almacenamiento en caché, gestión simplificada de SSL y distribución de carga sin interrupciones entre múltiples servidores backend. Comprender la configuración del proxy inverso es conocimiento esencial para cualquier administrador de sistemas o ingeniero DevOps que gestione infraestructura web moderna.

Tabla de Contenidos

Requisitos Previos

Antes de configurar Nginx como proxy inverso, asegúrate de tener:

  • Sistema Operativo: Ubuntu 20.04/22.04, Debian 10/11, CentOS 8/Rocky Linux 8, o similar
  • Versión de Nginx: 1.18.0 o posterior (se recomienda la última versión estable)
  • Aplicación Backend: Aplicación o servicio web en ejecución al cual hacer proxy
  • Acceso root o sudo: Requerido para instalar y configurar Nginx
  • Conocimientos básicos de redes: Comprensión de HTTP, puertos y direcciones IP
  • Nombre de dominio: DNS configurado apuntando a tu servidor (para uso en producción)
  • Respaldo: Respaldo actual de los archivos de configuración de Nginx existentes

Entendiendo el Proxy Inverso

¿Qué es un Proxy Inverso?

Un proxy inverso es un servidor que se sitúa frente a los servidores backend y reenvía las solicitudes de los clientes a esos servidores. A diferencia de un proxy directo que actúa en nombre de los clientes, un proxy inverso actúa en nombre de los servidores.

Características clave:

  • Los clientes se conectan al proxy inverso, no directamente a los servidores backend
  • El proxy inverso reenvía las solicitudes a los servidores backend apropiados
  • Las respuestas se envían de vuelta a través del proxy inverso a los clientes
  • Los servidores backend permanecen invisibles para los clientes

Beneficios de Usar Nginx como Proxy Inverso

Mejora de Seguridad:

  • Oculta la arquitectura y direcciones IP del servidor backend
  • Punto único para terminación SSL/TLS
  • Protección contra ataques DDoS mediante limitación de tasa
  • Aplicación centralizada de políticas de seguridad

Optimización de Rendimiento:

  • El almacenamiento en caché de contenido reduce la carga del backend
  • Agrupación de conexiones y optimización de keep-alive
  • Compresión de respuestas
  • Servicio de contenido estático

Escalabilidad:

  • Balanceo de carga entre múltiples servidores backend
  • Adición o eliminación fácil de servidores backend
  • Despliegues sin tiempo de inactividad
  • Verificaciones de salud para disponibilidad del backend

Gestión Simplificada:

  • Punto de entrada único para múltiples aplicaciones
  • Registro y monitoreo centralizados
  • Gestión unificada de certificados SSL
  • Reglas de firewall simplificadas

Casos de Uso Comunes

  1. Arquitectura de Microservicios: Enrutar solicitudes a diferentes servicios según rutas de URL
  2. Aplicaciones Node.js: Manejar contenido estático y hacer proxy de solicitudes dinámicas
  3. Contenedores Docker: Acceder a aplicaciones en contenedores a través de un punto de entrada unificado
  4. Gateway API: Punto de entrada centralizado para múltiples APIs
  5. Migración de Aplicaciones Heredadas: Migrar gradualmente de sistemas antiguos a nuevos

Configuración Básica de Proxy Inverso

Instalando Nginx

Primero, asegúrate de que Nginx esté instalado en tu sistema.

Para Ubuntu/Debian:

# Actualizar índice de paquetes
sudo apt update

# Instalar Nginx
sudo apt install nginx -y

# Iniciar y habilitar Nginx
sudo systemctl start nginx
sudo systemctl enable nginx

# Verificar instalación
nginx -v

Para CentOS/Rocky Linux:

# Instalar Nginx desde el repositorio EPEL
sudo dnf install epel-release -y
sudo dnf install nginx -y

# Iniciar y habilitar Nginx
sudo systemctl start nginx
sudo systemctl enable nginx

# Verificar instalación
nginx -v

Configuración Simple de Proxy Inverso

Crea una configuración básica de proxy inverso para un único servidor backend.

Crea un nuevo archivo de configuración:

# Ubuntu/Debian
sudo nano /etc/nginx/sites-available/reverse-proxy

# CentOS/Rocky Linux
sudo nano /etc/nginx/conf.d/reverse-proxy.conf

Agrega la siguiente configuración:

# Configuración simple de proxy inverso
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    # Registros de acceso y errores
    access_log /var/log/nginx/reverse-proxy-access.log;
    error_log /var/log/nginx/reverse-proxy-error.log;

    # Proxy inverso al servidor backend
    location / {
        # Dirección del servidor backend
        proxy_pass http://localhost:3000;

        # Preservar encabezado host original
        proxy_set_header Host $host;

        # Reenviar dirección IP del cliente
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # Reenvío de protocolo
        proxy_set_header X-Forwarded-Proto $scheme;

        # Soporte WebSocket
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Habilitar la configuración (Solo Ubuntu/Debian):

# Crear enlace simbólico para habilitar el sitio
sudo ln -s /etc/nginx/sites-available/reverse-proxy /etc/nginx/sites-enabled/

# Probar configuración
sudo nginx -t

# Recargar Nginx
sudo systemctl reload nginx

Para CentOS/Rocky Linux, la configuración se incluye automáticamente:

# Probar configuración
sudo nginx -t

# Recargar Nginx
sudo systemctl reload nginx

Hacer Proxy a Diferentes Servidores Backend

Configura múltiples servicios backend con diferentes rutas de URL:

server {
    listen 80;
    server_name example.com;

    # Proxy a aplicación Node.js
    location /api/ {
        proxy_pass http://localhost:3000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # Proxy a aplicación Python
    location /admin/ {
        proxy_pass http://localhost:8000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # Servir contenido estático directamente
    location /static/ {
        alias /var/www/static/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # Ubicación predeterminada para aplicación frontend
    location / {
        proxy_pass http://localhost:4200;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Configuración Upstream

Define servidores backend usando bloques upstream para mejor control:

# Definir servidores backend upstream
upstream backend_app {
    server localhost:3000;
}

upstream api_backend {
    server localhost:8000;
}

server {
    listen 80;
    server_name example.com;

    # Proxy a aplicación backend
    location / {
        proxy_pass http://backend_app;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # Proxy a API backend
    location /api/ {
        proxy_pass http://api_backend/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Características Avanzadas de Proxy

Configuración de Tiempos de Espera y Búferes

Configura tiempos de espera y búferes para un rendimiento óptimo:

upstream backend {
    server localhost:3000;
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;

        # Configuración de tiempos de espera
        proxy_connect_timeout 60s;      # Tiempo de espera de conexión al backend
        proxy_send_timeout 60s;         # Tiempo de espera para enviar solicitud
        proxy_read_timeout 60s;         # Tiempo de espera para leer respuesta

        # Configuración de búferes
        proxy_buffering on;             # Habilitar buffering
        proxy_buffer_size 4k;           # Búfer para encabezados de respuesta
        proxy_buffers 8 4k;             # Número y tamaño de búferes
        proxy_busy_buffers_size 8k;     # Tamaño de búferes ocupados

        # Configuración del cuerpo de la solicitud
        client_max_body_size 10M;       # Tamaño máximo de carga
        client_body_buffer_size 128k;   # Búfer para cuerpo de solicitud

        # Encabezados
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Soporte WebSocket

Habilita conexiones WebSocket a través del proxy inverso:

# Proxy inverso habilitado para WebSocket
upstream websocket_backend {
    server localhost:3000;
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    listen 80;
    server_name example.com;

    # Ubicación WebSocket
    location /ws {
        proxy_pass http://websocket_backend;

        # Encabezados WebSocket
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        # Encabezados proxy estándar
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # Tiempos de espera para conexiones de larga duración
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }

    # Tráfico HTTP regular
    location / {
        proxy_pass http://websocket_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Encabezados Personalizados y Modificación de Respuesta

Agrega o modifica encabezados en respuestas proxy:

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://localhost:3000;

        # Encabezados proxy estándar
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Encabezados de solicitud personalizados
        proxy_set_header X-Custom-Header "custom-value";
        proxy_set_header X-Request-ID $request_id;

        # Ocultar encabezados backend
        proxy_hide_header X-Powered-By;
        proxy_hide_header Server;

        # Agregar encabezados de seguridad a la respuesta
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header Referrer-Policy "strict-origin-when-cross-origin" always;

        # Encabezados CORS (si es necesario)
        add_header Access-Control-Allow-Origin "*" always;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
        add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;

        # Manejar solicitudes OPTIONS para CORS
        if ($request_method = OPTIONS) {
            return 204;
        }
    }
}

Balanceo de Carga con Proxy Inverso

Balanceo de Carga Round-Robin

Distribuye solicitudes equitativamente entre múltiples servidores backend:

# Definir servidores backend
upstream backend_cluster {
    # Round-robin por defecto
    server 192.168.1.10:3000;
    server 192.168.1.11:3000;
    server 192.168.1.12:3000;
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend_cluster;

        # Encabezados proxy
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Habilitar conexiones keep-alive al backend
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}

Métodos de Balanceo de Carga

Configura diferentes algoritmos de balanceo de carga:

# Método de menos conexiones
upstream backend_least_conn {
    least_conn;  # Enviar al servidor con menos conexiones activas

    server 192.168.1.10:3000;
    server 192.168.1.11:3000;
    server 192.168.1.12:3000;
}

# Método de hash IP (persistencia de sesión)
upstream backend_ip_hash {
    ip_hash;  # La misma IP de cliente siempre va al mismo servidor

    server 192.168.1.10:3000;
    server 192.168.1.11:3000;
    server 192.168.1.12:3000;
}

# Balanceo de carga ponderado
upstream backend_weighted {
    server 192.168.1.10:3000 weight=3;  # Recibe 3x más solicitudes
    server 192.168.1.11:3000 weight=2;  # Recibe 2x más solicitudes
    server 192.168.1.12:3000 weight=1;  # Recibe 1x solicitudes (predeterminado)
}

# Servidor con verificaciones de salud y failover
upstream backend_advanced {
    server 192.168.1.10:3000 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:3000 max_fails=3 fail_timeout=30s;
    server 192.168.1.12:3000 backup;  # Solo se usa si otros fallan
}

server {
    listen 80;
    server_name example.com;

    location / {
        # Usar upstream deseado
        proxy_pass http://backend_least_conn;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Persistencia de Sesión

Asegura que las sesiones de usuario se mantengan en el mismo servidor backend:

# Método 1: Hash IP
upstream backend_sticky {
    ip_hash;
    server 192.168.1.10:3000;
    server 192.168.1.11:3000;
}

# Método 2: Basado en cookies (requiere Nginx Plus comercial o módulo de terceros)
# Para Nginx de código abierto, usar ip_hash o almacenamiento de sesión externo (Redis)

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend_sticky;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        # Agregar información del servidor backend al encabezado de respuesta (para depuración)
        add_header X-Upstream-Server $upstream_addr always;
    }
}

Terminación SSL/TLS

Terminación SSL en el Proxy Inverso

Manejar SSL/TLS en el nivel del proxy, reenviando HTTP simple al backend:

upstream backend {
    server localhost:3000;
}

# Redireccionamiento de HTTP a HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    return 301 https://$server_name$request_uri;
}

# Servidor HTTPS con terminación SSL
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;

    # Certificados SSL
    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;

    # Configuración SSL moderna
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
    ssl_prefer_server_ciphers off;

    # Optimización SSL
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_session_tickets off;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    # Encabezados de seguridad
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;

    # Proxy al backend (HTTP)
    location / {
        proxy_pass http://backend;

        # Reenviar información del cliente
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
    }
}

Configuración de Caché

Caché Básico de Proxy

Habilita el almacenamiento en caché para mejorar el rendimiento y reducir la carga del backend:

# Definir ruta y configuración de caché
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;

upstream backend {
    server localhost:3000;
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;

        # Habilitar caché
        proxy_cache my_cache;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        proxy_cache_background_update on;
        proxy_cache_lock on;

        # Duración de caché según código de respuesta
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404 1m;

        # Clave de caché
        proxy_cache_key "$scheme$request_method$host$request_uri";

        # Agregar estado de caché al encabezado de respuesta
        add_header X-Cache-Status $upstream_cache_status;

        # Encabezados proxy estándar
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # No almacenar en caché endpoints de API
    location /api/ {
        proxy_pass http://backend;
        proxy_cache off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Caché Avanzado con Bypass

Implementa bypass de caché y caché selectivo:

# Configuración de caché
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=content_cache:20m max_size=2g inactive=120m;

# Definir cuándo omitir la caché
map $request_method $skip_cache {
    default 0;
    POST 1;
    PUT 1;
    DELETE 1;
}

map $request_uri $skip_cache_uri {
    default 0;
    ~*/admin/ 1;
    ~*/checkout/ 1;
}

upstream backend {
    server localhost:3000;
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;

        # Configuración de caché
        proxy_cache content_cache;
        proxy_cache_bypass $skip_cache $skip_cache_uri;
        proxy_no_cache $skip_cache $skip_cache_uri;

        # Configuración de caché
        proxy_cache_valid 200 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_use_stale error timeout updating;
        proxy_cache_lock on;
        proxy_cache_lock_timeout 5s;

        # Caché basado en encabezados de respuesta
        proxy_cache_valid any 1m;
        proxy_ignore_headers Cache-Control Expires;

        # Agregar encabezados de depuración
        add_header X-Cache-Status $upstream_cache_status;
        add_header X-Cache-Key "$scheme$request_method$host$request_uri";

        # Encabezados proxy
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Crear directorio de caché:

# Crear directorio de caché
sudo mkdir -p /var/cache/nginx

# Establecer permisos apropiados
sudo chown -R www-data:www-data /var/cache/nginx  # Ubuntu/Debian
# sudo chown -R nginx:nginx /var/cache/nginx      # CentOS/Rocky

# Probar configuración
sudo nginx -t

# Recargar Nginx
sudo systemctl reload nginx

Cabeceras de Seguridad y Protección

Configuración de Seguridad Integral

Implementa encabezados de seguridad y mecanismos de protección:

upstream backend {
    server localhost:3000;
}

# Zonas de limitación de tasa
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s;

# Limitación de conexiones
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

server {
    listen 443 ssl http2;
    server_name example.com;

    # Configuración SSL
    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;

    # Encabezados de seguridad
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Frame-Options "DENY" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

    # Ocultar versión de Nginx
    server_tokens off;

    # Denegar acceso a archivos ocultos
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

    # Aplicación principal con limitación de tasa
    location / {
        # Aplicar limitación de tasa
        limit_req zone=general burst=20 nodelay;
        limit_conn conn_limit 10;

        proxy_pass http://backend;

        # Encabezados proxy enfocados en seguridad
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Ocultar encabezados backend
        proxy_hide_header X-Powered-By;
        proxy_hide_header Server;
    }

    # Endpoint API con diferentes límites de tasa
    location /api/ {
        limit_req zone=api burst=50 nodelay;

        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Verificación y Pruebas

Pruebas de Funcionalidad Básica

Verifica que el proxy inverso funciona correctamente:

# Probar desde máquina local
curl -I http://example.com

# Debería mostrar a Nginx manejando la solicitud

# Verificar si el backend está recibiendo solicitudes
curl -v http://example.com

# Verificar que los encabezados se están reenviando
curl -H "X-Custom-Header: test" http://example.com

Verificación de Balanceo de Carga

Prueba el balanceo de carga entre múltiples backends:

# Agregar encabezado de depuración a la respuesta del backend para identificar el servidor
# Luego hacer múltiples solicitudes

for i in {1..10}; do
    curl -s http://example.com | grep "Server-ID"
done

# Debería mostrar diferentes servidores backend respondiendo

Verificación SSL/TLS

Probar terminación SSL:

# Probar certificado SSL
openssl s_client -connect example.com:443 -servername example.com

# Verificar calificación SSL
# Usar SSL Labs: https://www.ssllabs.com/ssltest/

# Verificar redirección HTTPS
curl -I http://example.com
# Debería mostrar redirección 301 a HTTPS

Pruebas de Caché

Verificar que el almacenamiento en caché funciona:

# Primera solicitud (caché MISS)
curl -I http://example.com
# Buscar: X-Cache-Status: MISS

# Segunda solicitud (caché HIT)
curl -I http://example.com
# Buscar: X-Cache-Status: HIT

# Limpiar caché
sudo rm -rf /var/cache/nginx/*
sudo systemctl reload nginx

Pruebas de Rendimiento

Comparar rendimiento del proxy inverso:

# Instalar Apache Bench
sudo apt install apache2-utils

# Probar rendimiento
ab -n 1000 -c 10 http://example.com/

# Probar con keep-alive
ab -n 1000 -c 10 -k http://example.com/

# Comparar con acceso directo al backend
ab -n 1000 -c 10 http://localhost:3000/

Solución de Problemas

Problemas de Conexión al Backend

Problema: Nginx no puede conectarse al servidor backend

Solución:

# Verificar que el backend está en ejecución
sudo netstat -tlnp | grep 3000
# o
sudo ss -tlnp | grep 3000

# Verificar SELinux (si aplica)
sudo getsebool httpd_can_network_connect
# Si está desactivado, habilitarlo:
sudo setsebool -P httpd_can_network_connect 1

# Probar backend directamente
curl http://localhost:3000

# Verificar registros de errores de Nginx
sudo tail -f /var/log/nginx/error.log

Error 502 Bad Gateway

Problema: Respuesta 502 Bad Gateway

Causas y soluciones:

# 1. Servidor backend está caído
sudo systemctl status your-app

# 2. Dirección proxy_pass incorrecta
# Verificar en la configuración:
sudo nginx -T | grep proxy_pass

# 3. Firewall bloqueando la conexión
sudo iptables -L | grep 3000
sudo firewall-cmd --list-all

# 4. Tiempo de espera demasiado corto
# Aumentar tiempos de espera en la configuración de nginx:
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

# 5. Verificar registros de errores
sudo tail -50 /var/log/nginx/error.log

504 Gateway Timeout

Problema: La solicitud agota el tiempo de espera

Solución:

# Aumentar valores de tiempo de espera
location / {
    proxy_pass http://backend;

    # Aumentar todos los tiempos de espera
    proxy_connect_timeout 120s;
    proxy_send_timeout 120s;
    proxy_read_timeout 120s;

    # Para solicitudes de larga duración
    proxy_buffering off;
}

Falla de Conexión WebSocket

Problema: Las conexiones WebSocket no funcionan

Solución:

# Asegurar que los encabezados WebSocket estén configurados
location /ws {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    # Aumentar tiempo de espera para conexiones de larga duración
    proxy_read_timeout 3600s;
    proxy_send_timeout 3600s;
}
# Probar conexión WebSocket
# Instalar wscat: npm install -g wscat
wscat -c ws://example.com/ws

Problemas de Rendimiento

Problema: Tiempos de respuesta lentos a través del proxy inverso

Soluciones:

# Habilitar buffering y keep-alive
location / {
    proxy_pass http://backend;

    # Habilitar buffering
    proxy_buffering on;
    proxy_buffer_size 4k;
    proxy_buffers 8 4k;

    # Habilitar keep-alive al backend
    proxy_http_version 1.1;
    proxy_set_header Connection "";

    # Habilitar caché
    proxy_cache my_cache;
    proxy_cache_use_stale updating;
}
# Monitorear rendimiento de Nginx
# Instalar nginx-module-vts o usar stub_status integrado

# Verificar estados de conexión
sudo netstat -an | grep :80 | wc -l

# Monitorear registros de acceso para solicitudes lentas
sudo tail -f /var/log/nginx/access.log

Mejores Prácticas

Organización de Configuración

  1. Usar archivos de configuración separados:
# Organizar por aplicación
/etc/nginx/conf.d/
├── app1.conf
├── app2.conf
└── api.conf
  1. Usar includes para configuraciones comunes:
# /etc/nginx/snippets/proxy-params.conf
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# Incluir en bloques de servidor
include snippets/proxy-params.conf;

Endurecimiento de Seguridad

  1. Implementar limitación de tasa:
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req zone=general burst=20 nodelay;
  1. Ocultar información del servidor:
server_tokens off;
proxy_hide_header X-Powered-By;
  1. Usar encabezados de seguridad:
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;

Optimización de Rendimiento

  1. Habilitar agrupación de conexiones:
upstream backend {
    server localhost:3000;
    keepalive 32;
}

location / {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
}
  1. Implementar caché estratégicamente:
  • Almacenar en caché contenido estático agresivamente
  • Almacenar en caché respuestas API selectivamente
  • Omitir caché para contenido específico del usuario
  1. Usar HTTP/2:
listen 443 ssl http2;

Monitoreo y Registro

  1. Registro estructurado:
log_format custom '$remote_addr - $remote_user [$time_local] '
                  '"$request" $status $body_bytes_sent '
                  '"$http_referer" "$http_user_agent" '
                  'upstream: $upstream_addr '
                  'upstream_status: $upstream_status '
                  'request_time: $request_time '
                  'upstream_response_time: $upstream_response_time';

access_log /var/log/nginx/access.log custom;
  1. Monitorear métricas clave:
  • Tiempos de respuesta
  • Tasas de error
  • Tasas de acierto de caché
  • Salud del backend

Alta Disponibilidad

  1. Múltiples servidores backend:
upstream backend {
    least_conn;
    server backend1.example.com:3000 max_fails=3 fail_timeout=30s;
    server backend2.example.com:3000 max_fails=3 fail_timeout=30s;
    server backend3.example.com:3000 backup;
}
  1. Verificaciones de salud (Nginx Plus o usar alternativas):
upstream backend {
    server backend1.example.com:3000 max_fails=2 fail_timeout=10s;
    server backend2.example.com:3000 max_fails=2 fail_timeout=10s;
}

Conclusión

Nginx como proxy inverso es un componente esencial de la infraestructura web moderna, proporcionando balanceo de carga, terminación SSL, caché y características de seguridad que mejoran el rendimiento y la confiabilidad de las aplicaciones. Al configurar correctamente Nginx como proxy inverso, creas una arquitectura robusta y escalable que puede manejar cargas de tráfico elevadas mientras proteges los servidores backend de la exposición directa.

Puntos clave de esta guía:

  • Conceptos básicos de proxy inverso: Reenviar solicitudes de clientes a servidores backend mientras se agrega valor
  • Balanceo de carga: Distribuir tráfico entre múltiples backends para escalabilidad
  • Terminación SSL: Centralizar la gestión de SSL/TLS en la capa de proxy
  • Caché: Reducir la carga del backend y mejorar los tiempos de respuesta
  • Seguridad: Implementar limitación de tasa, encabezados de seguridad y mecanismos de protección
  • Monitoreo: Rastrear el rendimiento y solucionar problemas de manera efectiva

La flexibilidad y el rendimiento de Nginx lo convierten en la opción preferida para despliegues de proxy inverso, ya sea que estés ejecutando microservicios, aplicaciones en contenedores o stacks web tradicionales. Combinado con monitoreo adecuado, endurecimiento de seguridad y optimización de rendimiento, la configuración de proxy inverso de Nginx forma la base de una infraestructura web confiable y de alto rendimiento.

Continúa aprendiendo explorando temas avanzados como características de Nginx Plus, integración con mallas de servicios, estrategias de caché avanzadas y configuración dinámica de upstream para despliegues aún más sofisticados. Las pruebas regulares, el monitoreo y la optimización aseguran que tu proxy inverso continúe cumpliendo con las demandas cambiantes de tus aplicaciones y usuarios.