Proxy inverso con Nginx en un VPS Linux

3 min
Hosting VPS/VDS

Un proxy inverso recibe el tráfico público en los puertos 80 y 443 y lo reenvía a aplicaciones que solo escuchan en local. Aporta HTTPS, varios sitios en una sola IP y un punto único para registros y límites. Esta guía lo configura en un VPS Linux Infrawire para aplicaciones Node.js, Python o Docker.

📋 Requisitos previos

  • Un VPS Linux (Ubuntu 24.04 / Debian 12 o AlmaLinux 9 / Rocky 9) con acceso SSH root. La IP y la contraseña root están en tu área de cliente.
  • Un dominio example.com con registros A/AAAA apuntando a VPS_IP.
  • Una aplicación que escuche en un puerto local, por ejemplo 127.0.0.1:3000.

📦 Instalar Nginx

Bash
# Debian / Ubuntu sudo apt update && sudo apt install -y nginx # AlmaLinux / Rocky sudo dnf install -y nginx sudo systemctl enable --now nginx

En AlmaLinux/Rocky, SELinux impide por defecto que Nginx se conecte a backends. Permítelo una vez:

Bash
sudo setsebool -P httpd_can_network_connect 1

🚀 Una primera aplicación detrás del proxy

Tu aplicación debe escuchar en 127.0.0.1, no en 0.0.0.0, para que solo sea accesible a través de Nginx. Sea cual sea el lenguaje, el patrón es el mismo: node server.js en el puerto 3000, gunicorn -b 127.0.0.1:8000 app:app para Python, o un contenedor publicado con docker run -d -p 127.0.0.1:3000:80 IMAGE.

Crea /etc/nginx/sites-available/example.com (en AlmaLinux/Rocky usa /etc/nginx/conf.d/example.com.conf):

Nginx
1server { 2 listen 80; 3 listen [::]:80; 4 server_name example.com; 5 6 location / { 7 proxy_pass http://127.0.0.1:3000; 8 proxy_http_version 1.1; 9 proxy_set_header Host $host; 10 proxy_set_header X-Real-IP $remote_addr; 11 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 12 proxy_set_header X-Forwarded-Proto $scheme; 13 } 14}

Actívalo en Debian/Ubuntu, luego valida y recarga:

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

Las cabeceras X-Forwarded-* permiten a la aplicación conocer la IP real del cliente y si el visitante usó HTTPS. Sin ellas, tu app solo ve 127.0.0.1 y puede generar enlaces http://. Muchos frameworks también deben configurarse para confiar en el proxy (por ejemplo app.set('trust proxy', 1) en Express).

🔌 Soporte de WebSocket

WebSocket necesita las cabeceras de actualización HTTP. Añade un map al inicio del contexto http (por ejemplo en /etc/nginx/conf.d/websocket.conf):

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

Luego, en el bloque location:

Nginx
proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade;

⏱️ Timeouts y tamaño del cuerpo

Los valores por defecto son 60 segundos y 1 MB. Ajústalos para endpoints lentos o subidas de archivos:

Nginx
proxy_connect_timeout 5s; proxy_read_timeout 120s; proxy_send_timeout 120s; client_max_body_size 50m;

Para un WebSocket de larga duración, aumenta proxy_read_timeout (por ejemplo 3600s) o haz que la aplicación envíe pings.

🔒 HTTPS con Certbot

Abre primero el cortafuegos para 80 y 443 y luego:

Bash
# Debian / Ubuntu sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d example.com

En AlmaLinux/Rocky, instala Certbot con sudo dnf install -y epel-release y después sudo dnf install -y certbot python3-certbot-nginx. Certbot añade el certificado a tu bloque server, ofrece la redirección de HTTP a HTTPS e instala la renovación automática. Compruébalo con:

Bash
sudo certbot renew --dry-run

🗂️ Varias aplicaciones en un VPS

Crea un bloque server por dominio, cada uno con su server_name y su propio puerto local:

Nginx
1server { 2 listen 80; 3 server_name app1.example.com; 4 location / { proxy_pass http://127.0.0.1:3000; } 5} 6 7server { 8 listen 80; 9 server_name app2.example.com; 10 location / { proxy_pass http://127.0.0.1:8000; } 11}

Repite las cabeceras de proxy en cada bloque y ejecuta Certbot con -d app1.example.com -d app2.example.com. También puedes separar por ruta (location /api/ { proxy_pass http://127.0.0.1:8000/; }); la barra final elimina entonces el prefijo.

✅ Probar

Bash
curl -I https://example.com ss -ltnp | grep -E ':(80|443|3000)' sudo tail -f /var/log/nginx/error.log

El puerto del backend debe estar enlazado solo a 127.0.0.1, mientras Nginx escucha en 80 y 443.

🛠️ Solución de problemas

502 Bad Gateway. La aplicación está detenida o en otro puerto. Comprueba con ss -ltnp e iníciala. En AlmaLinux/Rocky, un Permission denied en el registro de errores indica que falta el booleano SELinux de arriba.

504 Gateway Timeout. El backend tarda más que proxy_read_timeout. Auméntalo u optimiza el endpoint.

El WebSocket se desconecta o falla con 400/426. Faltan las cabeceras Upgrade y Connection, o no está proxy_http_version 1.1;.

IP de cliente incorrecta en los logs. X-Forwarded-For se envía pero tu aplicación no confía en el proxy. Activa el ajuste de confianza de tu framework.


🎉 Tus aplicaciones ya se sirven detrás de Nginx con HTTPS, cabeceras limpias y espacio para tantos sitios como tu VPS pueda soportar.

Mantente al día con las últimas ofertas, descuentos y promociones especiales.

Ver promociones

Utilizamos cookies

Utilizamos cookies analíticas para mejorar su experiencia en nuestro sitio. No vendemos datos a terceros. Más información en nuestra política de privacidad.