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:
- Una IP pública separada para cada aplicación
- Gestión manual de certificados SSL por servicio
- Que cada aplicación maneje sus propios encabezados de seguridad
- Sin registro centralizado ni limitación de velocidad
Un proxy inverso resuelve todo esto. Un punto de entrada, múltiples backends, HTTPS automático.
Beneficios reales:
- Ejecuta más de 10 aplicaciones en un VPS con una sola IP
- SSL automático y gratuito mediante Let’s Encrypt
- Lugar centralizado para encabezados de seguridad
- Balanceo de carga cuando escales
- Soporte de WebSocket para aplicaciones en tiempo real
Requisitos previos
- Un VPS con Ubuntu 22.04+ (recomendamos Hostinger VPS por su rendimiento y fácil gestión de DNS)
- Un nombre de dominio apuntando a tu servidor
- Acceso root o sudo
- Aplicaciones ejecutándose en puertos de localhost
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:
- Verificar que eres el propietario del dominio
- Generar los certificados
- Configurar automáticamente Nginx para HTTPS
- 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
- Un archivo de configuración por dominio - Más fácil de gestionar y depurar (también importante para la seguridad del VPS)
- Siempre prueba antes de recargar -
nginx -tdetecta errores de sintaxis - Usa includes para configuraciones comunes - El principio DRY también aplica a las configuraciones
- Establece tiempos de espera apropiados - No dejes que los clientes lentos ocupen conexiones
- Habilita HTTP/2 - Mejora de rendimiento gratuita para HTTPS
- Registra logs por separado para cada aplicación - Depuración y análisis más fáciles
- Usa bloques upstream - Incluso para servidores individuales, facilita el escalado
- 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.
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
// related guides
$1 VPS Hosting 2026: Cheapest VPS Servers Starting at $1/Month
Looking for $1 VPS hosting? Compare the cheapest VPS providers starting from $1-3/month. Real specs, no hidden fees, honest reviews of budget VPS options.
tutorialCaddy Reverse Proxy Guide 2026: Automatic HTTPS Made Easy
Set up Caddy as a reverse proxy with automatic HTTPS, zero-config SSL, and simple Caddyfile syntax. Complete VPS deployment guide.
tutorialCloudflare Tunnel VPS Guide 2026: Expose Services Without Opening Ports
Set up Cloudflare Tunnel on your VPS to expose web apps securely without opening ports or revealing your server IP. Complete guide with Docker and DNS config.
tutorialCoolify VPS Setup Guide 2026: Self-Hosted Vercel Alternative
Deploy Coolify on your VPS for a self-hosted Vercel/Netlify experience. Complete setup guide with Docker, SSL, and app deployments.
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.