Configuración de Nginx como Proxy Inverso con SSL
TUTORIAL 8 min read fordnox

Configuración de Nginx como Proxy Inverso con SSL

Configura Nginx como proxy inverso con certificados SSL gratuitos de Let's Encrypt. Dirige múltiples dominios a diferentes servicios en un solo VPS.


Configuración de Nginx como Proxy Inverso con SSL

¿Ejecutas múltiples aplicaciones en un solo VPS? Nginx como proxy inverso te permite dirigir el tráfico a diferentes servicios, gestionar certificados SSL automáticamente y mejorar el rendimiento, todo en un único servidor. Si prefieres un enfoque nativo de Docker, consulta nuestra guía de Traefik en su lugar.

Por qué es importante

Sin un proxy inverso, necesitarías:

Un proxy inverso resuelve todo esto. Un punto de entrada, múltiples backends, HTTPS automático.

Beneficios reales:

Requisitos previos

Paso 1: Instalar Nginx

# Update packages
sudo apt update

# Install Nginx
sudo apt install nginx -y

# Start and enable
sudo systemctl start nginx
sudo systemctl enable nginx

# Verify it's running
sudo systemctl status nginx

Abre la IP de tu servidor en un navegador: deberías ver la página de bienvenida de Nginx.

Paso 2: Comprender la estructura de directorios

/etc/nginx/
├── nginx.conf              # Main config (rarely edit)
├── sites-available/        # All site configs
├── sites-enabled/          # Symlinks to active configs
├── snippets/               # Reusable config snippets
└── conf.d/                 # Additional configs

Paso 3: Configurar tu primer proxy inverso

Supongamos que tienes una aplicación Node.js ejecutándose en el puerto 3000. Crea una configuración:

sudo nano /etc/nginx/sites-available/myapp.example.com

Añade:

server {
    listen 80;
    listen [::]:80;
    server_name myapp.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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_cache_bypass $http_upgrade;
    }
}

Habilita el sitio:

# Create symlink
sudo ln -s /etc/nginx/sites-available/myapp.example.com /etc/nginx/sites-enabled/

# Test configuration
sudo nginx -t

# Reload Nginx
sudo systemctl reload nginx

Paso 4: Instalar Certbot para SSL gratuito

# Install Certbot and Nginx plugin
sudo apt install certbot python3-certbot-nginx -y

Paso 5: Obtener tu certificado SSL

sudo certbot --nginx -d myapp.example.com

Certbot hará lo siguiente:

  1. Verificar que eres el propietario del dominio
  2. Generar los certificados
  3. Configurar automáticamente Nginx para HTTPS
  4. Establecer la renovación automática

Tu configuración ahora se actualiza con los ajustes SSL automáticamente.

Paso 6: Verificar la renovación automática

# Test renewal process
sudo certbot renew --dry-run

# Check the timer
sudo systemctl status certbot.timer

Los certificados se renuevan automáticamente antes de su expiración. No se necesita intervención manual.

Paso 7: Añadir múltiples aplicaciones

Para cada nueva aplicación, crea un archivo de configuración:

Backend de API (puerto 4000):

sudo nano /etc/nginx/sites-available/api.example.com
server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://127.0.0.1:4000;
        proxy_http_version 1.1;
        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;
    }
}

Sitio web estático (directorio diferente):

server {
    listen 80;
    server_name static.example.com;

    root /var/www/static.example.com;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

Habilita y obtén SSL:

sudo ln -s /etc/nginx/sites-available/api.example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d api.example.com

Paso 8: Añadir encabezados de seguridad

Crea un snippet reutilizable:

sudo nano /etc/nginx/snippets/security-headers.conf
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;
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;

Inclúyelo en tus bloques de servidor:

server {
    # ... other config ...

    include snippets/security-headers.conf;

    location / {
        # ... proxy settings ...
    }
}

Paso 9: Configurar soporte para WebSocket

Para aplicaciones que usan WebSockets (chat, funciones en tiempo real):

location /ws {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_read_timeout 86400;  # 24 hours for long connections
}

Paso 10: Configurar limitación de velocidad

Protégete contra abusos en tu nginx.conf principal:

sudo nano /etc/nginx/nginx.conf

Añade en el bloque http:

http {
    # Define rate limit zones
    limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;

    # ... rest of config ...
}

Aplícalo en los bloques de servidor:

location / {
    limit_req zone=general burst=20 nodelay;
    proxy_pass http://127.0.0.1:3000;
    # ...
}

location /api/ {
    limit_req zone=api burst=50 nodelay;
    proxy_pass http://127.0.0.1:4000;
    # ...
}

Paso 11: Habilitar compresión Gzip

sudo nano /etc/nginx/conf.d/gzip.conf
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
    text/plain
    text/css
    text/xml
    text/javascript
    application/json
    application/javascript
    application/xml
    application/xml+rss
    application/x-javascript
    image/svg+xml;

Paso 12: Configurar balanceo de carga básico

Para múltiples servidores backend:

upstream myapp_backends {
    least_conn;  # Send to least busy server
    server 127.0.0.1:3000 weight=3;
    server 127.0.0.1:3001 weight=2;
    server 127.0.0.1:3002 backup;  # Only if others fail
}

server {
    listen 80;
    server_name myapp.example.com;

    location / {
        proxy_pass http://myapp_backends;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        # ... other headers ...
    }
}

Ejemplo completo de configuración para producción

Aquí tienes una configuración completa lista para producción:

upstream app_backend {
    server 127.0.0.1:3000;
    keepalive 32;
}

server {
    listen 80;
    listen [::]:80;
    server_name myapp.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name myapp.example.com;

    # SSL (managed by Certbot, but you can customize)
    ssl_certificate /etc/letsencrypt/live/myapp.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/myapp.example.com/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;

    # HSTS
    add_header Strict-Transport-Security "max-age=63072000" always;

    # Security headers
    include snippets/security-headers.conf;

    # Logging
    access_log /var/log/nginx/myapp.access.log;
    error_log /var/log/nginx/myapp.error.log;

    # Rate limiting
    limit_req zone=general burst=20 nodelay;

    # Proxy settings
    location / {
        proxy_pass http://app_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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_cache_bypass $http_upgrade;
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    # Static files (if served by Nginx)
    location /static/ {
        alias /var/www/myapp/static/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # Health check endpoint
    location /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }
}

Mejores prácticas

  1. Un archivo de configuración por dominio - Más fácil de gestionar y depurar (también importante para la seguridad del VPS)
  2. Siempre prueba antes de recargar - nginx -t detecta errores de sintaxis
  3. Usa includes para configuraciones comunes - El principio DRY también aplica a las configuraciones
  4. Establece tiempos de espera apropiados - No dejes que los clientes lentos ocupen conexiones
  5. Habilita HTTP/2 - Mejora de rendimiento gratuita para HTTPS
  6. Registra logs por separado para cada aplicación - Depuración y análisis más fáciles
  7. Usa bloques upstream - Incluso para servidores individuales, facilita el escalado
  8. Mantén la configuración SSL actualizada - Las mejores prácticas de seguridad evolucionan

Errores comunes a evitar

Olvidar probar la configuración - Un error tipográfico rompe todos los sitios

No habilitar los sitios - Crear una configuración sin enlace simbólico no hace nada

Barra diagonal incorrecta en proxy_pass - /api vs /api/ se comportan de manera diferente

Faltar encabezados de WebSocket - Las funciones en tiempo real fallan silenciosamente

Ignorar keepalive del upstream - Crea conexiones innecesarias

Discrepancia en el certificado SSL - El certificado debe coincidir exactamente con el server_name

Sin limitación de velocidad - Tu servidor se convierte en un objetivo de DoS

Servir archivos estáticos a través de la aplicación - Deja que Nginx maneje el contenido estático directamente

Consejos de depuración

# Check Nginx error log
sudo tail -f /var/log/nginx/error.log

# Check specific site log
sudo tail -f /var/log/nginx/myapp.error.log

# Test configuration
sudo nginx -t

# Check if port is listening
sudo ss -tlnp | grep nginx

# View active connections
sudo nginx -T | grep server_name

Preguntas frecuentes

¿Cuántos sitios puede manejar un servidor Nginx?

Nginx es increíblemente eficiente. Un Hostinger VPS modesto puede manejar fácilmente más de 50 sitios de bajo tráfico o varios de alto tráfico. La memoria suele ser el factor limitante.

¿Debería usar Apache o Nginx?

Nginx para proxy inverso, casi siempre. Maneja mejor las conexiones concurrentes y usa menos memoria. Apache está bien para alojamiento PHP tradicional con mod_php. Para una configuración aún más simple, considera un PaaS autoalojado como Coolify o Dokploy.

¿Cuál es la diferencia entre sites-available y sites-enabled?

sites-available almacena todas las configuraciones. sites-enabled contiene enlaces simbólicos a las activas. Esto te permite deshabilitar un sitio sin eliminar su configuración.

¿Cómo manejo www vs sin www?

Añade ambos al server_name y redirige uno al otro:

server {
    listen 80;
    server_name www.example.com;
    return 301 https://example.com$request_uri;
}

¿Por qué no funciona mi certificado SSL?

Causas comunes: el DNS no apunta al servidor, los puertos 80/443 están bloqueados por el firewall, server_name incorrecto, o Certbot no pudo verificar la propiedad. Verifica con sudo certbot certificates el estado.

¿Puedo usar Nginx con Docker?

¡Por supuesto! Puedes ejecutar Nginx en un contenedor o en el host haciendo proxy a contenedores Docker. Consulta nuestra guía de Docker Compose para más detalles.


Próximos pasos: Configura la monitorización para rastrear el rendimiento de tu Nginx y detectar problemas antes de que se conviertan en algo grave.

~/nginx-reverse-proxy-guide/get-started

Ready to get started?

Get the best VPS hosting deal today. Hostinger offers 4GB RAM VPS starting at just $4.99/mo.

Get Hostinger VPS — $4.99/mo

// up to 75% off + free domain included

// related topics

Nginx proxy inverso configuración SSL Let's Encrypt configuración Nginx servidor web VPS

// related guides

Andrius Putna

Andrius Putna

I am Andrius Putna. Geek. Since early 2000 in love tinkering with web technologies. Now AI. Bridging business and technology to drive meaningful impact. Combining expertise in customer experience, technology, and business strategy to deliver valuable insights. Father, open-source contributor, investor, 2xIronman, MBA graduate.

// last updated: February 6, 2026. Disclosure: This article may contain affiliate links.