Como exponer un servicio o app fácil (SSL) • Nginx
Preámbulo
Bienvenido a un tutorial corto para una pieza de software que desborda en funciones. No se va a encontrar nada más potente que Nginx, que a día de hoy se utiliza para:
- Servidor web HTTP (soporta SSL/TLS): entrega contenido HTML, HTM, PHP, etc.
- Cachear contenido: se puede construir un CDN muy potente y para una infinidad de formatos de archivo.
- Proxy inverso: la solución para conectar un servicio que escucha en un puerto y redirigirlo a otro. Por ejemplo, una API en NodeJs / Python que está en el puerto 3000, pero que se desea montar en el puerto 80 de la ruta “api.desistemas.blog”.
- Balanceador de carga: seleccionar servidores o recursos de forma inteligente para nivelar las peticiones de clientes entre todos los servidores.
- Servidor proxy TCP/UDP
- Servidor proxy de correo
En este post se va a enseñar a exponer una app / servicio en un puerto específico mediante proxy inverso (reverse proxy).
También se verá como obtener un certificado SSL gratis.
La implementación se basa en las que hago regularmente en empresas. Siempre funciona como “el primer día”, y sin arañar más recursos de los necesarios.
Equipo del tutorial
- 1 núcleo Intel Brodwell
- 1GB de RAM
- 10GB SSD
- Debian 13.1
- Nginx 1.26.3
- Dominio: vite.desistemas.blog
Apuntar correctamente los DNS
Para averiguar la IP del servidor hay dos opciones:
- Revisar el dato en el panel de control del servidor, en el hosting que se contrató.
- Consultar api.ipify.org desde la terminal:
curl https://api.ipify.org/
Cualquiera de estas dos opciones informará la IP.
Una vez se consigue este dato, se debe ir a la zona DNS del proveedor del dominio y crear un registro de tipo A.
Los DNS tipo “A” son los que vinculan una dirección URL a una IPv4, como por ejemplo, 186.160.160.14.
En la siguiente imágen, se muestra como realizar esto:

De esta forma, se consigue que cuándo alguien busque “vite.desistemas.blog”, el servidor DNS apunte a la IP del servidor que se está configurando. Así, el usuario llega al servidor nginx, que toma la solicitud y la pasa por el proxy inverso que se configurará más adelante.
Esto también es clave para poder configurar el certificado SSL. Se verá más adelante.
Comprobar la expansión de DNS
Se puede consultar el sitio web DNS Checker y escribir la URL que se está configurando (vite.desistemas.blog). En cuestión de segundos se verá que el dominio apunta correctamente a la IP del servidor.

Sólo falta generar el certificado SSL y la configuración de Nginx.
Actualización de los repositorios
Para poder instalar algo, primero se deben ejecutar dos comandos:
- Elevar permisos como usuario root:
su -
- Actualizar los repositorios de paquetes (APT):
apt update
Ahora, será posible instalar el servidor Nginx.
Instalación de Nginx
Con los permisos elevados, se ejecuta:
apt install nginx -y
Nginx deberá ser configurado después de generar el certificado SSL.
Generar el certificado SSL
Instalación de las dependencias
Como usuario root debe ejecutarse el siguiente comando, que instalará “certbot” y el plugin para nginx:
apt install certbot python3-certbot-nginx -y
Generar el certificado con Certbot
Este proceso es sencillo. Realizará unas breves preguntas y luego solicitará el certificado. Para lograrlo, debe ejecutarse este comando como usuario root (para el caso del tutorial, se quiere solicitar un certificado para el nuevo sub-dominio “vite.desistemas.blog”):
certbot --nginx -d vite.desistemas.blog
Cuándo Certbot finaliza exitosamente, lo indicará de la siguiente manera:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/vite.desistemas.blog/fullchain.pem
Key is saved at: /etc/letsencrypt/live/vite.desistemas.blog/privkey.pem
This certificate expires on 2026-02-14.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
Deploying certificate
Successfully deployed certificate for vite.desistemas.blog to /etc/nginx/sites-enabled/default
Congratulations! You have successfully enabled HTTPS on https://vite.desistemas.blog
Es importante mencionar que se configura la renovación automática del certificado, por lo cuál no debería haber problema de certificado (TODO / EXPANDIR INFO).
Las rutas dónde se guarda el certificado
Tal cuál indicó certbot, el certificado se guardó en:
/etc/letsencrypt/live/vite.desistemas.blog/fullchain.pem
Y la clave se almacenó en:
/etc/letsencrypt/live/vite.desistemas.blog/privkey.pem
Se debe tomar nota de estas rutas, porque deberán especificarse en la configuración de Nginx.
Configuración de Nginx
Nginx es un motor HTTP que recibe peticiones de clientes y las procesa. Explicar el funcionamiento “detrás del telón” es importante para que el administrador del sistema entienda qué configura. A continuación, se enumera un caso de ejemplo para que se comprenda el funcionamiento:
- Un cliente tipea “vite.desistemas.blog” en su navegador web.
- El router de ese cliente recibe la petición, y consulta a un servidor DNS a qué servidor debe entrar
- Por eso es importante Apuntar correctamente los DNS, caso contrario, los usuarios no podrán saber a qué servidor apunta “vite.desistemas.blog”.
- El servidor DNS devuelve la IP del servidor HTTP.
- El cliente consulta nuestro servidor con un HEADER HTTP. Entre los datos que envía en ese header, está la dirección URL.
- El servidor recibe la dirección URL que se consultó mediante el HEADER y, si coincide con la URL configurada en Nginx, le entrega al cliente la página web o recurso que el administrador haya configurado para ese dominio.
Nginx, entonces, recibe peticiones que indican qué URL quiere mostrarse. Por ende, un mismo servidor puede atender consultas de dominios como desistemas.blog, vite.desistemas.blog, inforce.cloud, google.com, yahoo.com, etc; siempre y cuándo los servidores DNS del mundo sepan que todos esos dominios apuntan a un mismo servidor (y por ende, misma IP).
Baja del sitio “default”
Certbot se configuró en el sitio default, pero se creará un nuevo “sitio” llamado app. Allí, residirá la configuración que hace posible que:
- Se redirija el tráfico HTTP a HTTPS.
- Se vincule el certificado y la clave, para activar SSL/TLS.
- Se cree un proxy inverso para conectar el puerto 443 al de la aplicación Vite que se desea exponer a internet.
Para que el sitio default no moleste, se procede a eliminar (como root) el vínculo simbólico que lo habilita:
rm /etc/nginx/sites-available/default
Es posible que la terminal consulte si se desea eliminar este enlace, a lo que se responde con la tecla Y y luego ENTER.
Configuración del nuevo sitio a exponer
En la ruta /etc/nginx/sites-available se debe crear el archivo de configuración app.
touch /etc/nginx/sites-available/app
Y luego, se edita con nano:
nano /etc/nginx/sites-available/app
La configuración que se debe copiar y pegar es la siguiente. Podés ver la breve explicación de cada línea importante acá.
# Redirección de HTTP a HTTPS
server {
listen 80;
server_name vite.desistemas.blog;
location / {
return 301 https://$host$request_uri;
}
}
# Proxy inverso en HTTPS
server {
listen 443 ssl;
server_name vite.desistemas.blog;
# Certificados SSL
ssl_certificate /etc/letsencrypt/live/vite.desistemas.blog/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/vite.desistemas.blog/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://localhost:5173;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Al terminar de editar este archivo, se presiona CTRL + O + ENTER para guardar el archivo, y CTRL + X para cerrar nano.
Explicación del archivo
Dentro del primer objeto server es clave identificar varias líneas:
- server_name vite.desistemas.blog;
- Esta línea indica que para los usuarios que busquen la dirección vite.desistemas.blog, nginx va a responder
- return 301 https://$host$request_uri;
- Esto, dentro de
location /, indica que las solicitudes serán redirigidas de forma permanente a la misma URL solicita por el cliente, pero en su versión segura HTTPS.
- Esto, dentro de
En el segundo objeto server, se escucha en el puerto 443, el que siempre se usa para la versión segura de los sitios web.
Se indica la ruta para el certificado SSL, que está comentado porque aún no se dio el alta del dominio (esto será hecho más adelante en este mismo tutorial).
Las líneas más importantes (además del detalle que server_name debería coincidir con el objeto server de más arriba) son:
- ssl_certificate
- Si se observa el archivo
/etc/nginx/sites-available/default, se observa que este parámetro tiene un archivo “.crt”. Sin embargo, el archivo que genera Certbot es extensión “pem” y es totalmente válido.
- Si se observa el archivo
- ssl_certificate_key
- xxx
- proxy_pass http://localhost:5173;
- Esto indica que al recibir solicitudes HTTPS a vite.desistemas.blog, nginx entregará lo que sea que esté en el puerto 5173 del servidor. En el caso del tutorial, es una aplicación escrita en Vue 3 (con el wrapper Vite).
Habilitar la nueva configuración
Esto se hace de forma simple, realizando un enlace simbólico entre el archivo que se acaba de escribir y guardar hacia la carpeta sites-enabled de nginx:
ln -s /etc/nginx/sites-available/app /etc/nginx/sites-enabled/
Comprobar el archivo app
Se comprueba la sintáxis del archivo de configuración con el comando:
nginx -t
Este comando informará que todo está bien:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Como nginx.conf está incluyendo los archivos de /etc/nginx/sites-enabled, también está aclarando que el archivo app creado en este tutorial también está “ok”
Reiniciar nginx
systemctl restart nginx
Comprobar que el proxy funcione
python3 está instalado por defecto. Se va a aprovechar para crear un pequeño servidor que responda un texto simple.
- Se debe situar la terminal en la carpeta del usuario root:
cd ~
- Se crea y abre el archivo servidor_test.py:
nano servidor_test.py
- Se pega el siguiente código:
from http.server import BaseHTTPRequestHandler, HTTPServer
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
print("¡La aplicación funciona! desistemas.blog")
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write("¡La aplicación funciona! desistemas.blog")
HTTPServer(('', 5173), Handler).serve_forever()
Y dentro de la aplicación nano, se guarda con CTRL + O + ENTER, y sale con las teclas CTRL + X.
- Se ejecuta el código:
python3 servidor_test.py
- Se visita la URL vite.desistemas.blog para comprobar que todo está bien.

Epílogo
Hoy el administrador en sistemas aprendió a crear un sencillo proxy inverso con Nginx, dotandolo de seguridad de punto a punto, con una versión actualizada de nginx y en menos de 30 minutos.
Nos vemos en un próximo artículo 😇