En ocasiones tenemos servicios o aplicaciones web que escuchan directamente en un puerto interno. Para evitar acceder a dichas aplicaciones por la IP del servidor o por puertos no estándar, podemos utilizar un proxy inverso con Nginx.
Esta configuración nos ofrece varias ventajas, como poder acceder mediante un dominio o subdominio y habilitar un certificado SSL fácilmente con Let's Encrypt.
En este tutorial explicaremos cómo configurar Nginx para que actúe como proxy hacia un puerto interno, de modo que sea Nginx quien gestione las peticiones externas, incluyendo HTTPS. Partimos de la base de que Nginx ya está instalado y en funcionamiento en el servidor.
Requisitos previos
Antes de comenzar, asegúrate de tener instalados los siguientes paquetes:
apt install nginx certbot python3-certbot-nginxAdemás, el dominio o subdominio que vayas a usar debe apuntar correctamente a la IP pública del servidor.
Configuración de Nginx Proxy
Tendremos que crear o editar nuestro fichero de configuración para Nginx de nuestra aplicación, por lo general se debería de encontrar en /etc/nginx/sites-enabled y depende de si tenemos certificado SSL o no se deberá de hacer de una manera u otra.
Generar certificado SSL con Certbot
Si todavía no tienes certificado SSL, lo más recomendable es generarlo con el método webroot de Certbot. Este método permite validar el dominio sin necesidad de detener Nginx, ya que la validación se realiza a través de una ruta temporal servida por el propio Nginx.
Primero, creamos un pequeño bloque de servidor para la validación y redirección HTTP a HTTPS. Este bloque debe estar en /etc/nginx/sites-enabled y puede tener el siguiente contenido:
server {
listen 80;
server_name [SUB_DOMINIO];
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location / {
return 301 https://$host$request_uri;
}
}[DOMINIO] por el dominio o subdominio que necesites configurar y que esté apuntando a la IP del servidor.Recargamos el servicio de Nginx con la nueva configuración:
systemctl reload nginxA continuación, creamos el directorio para los archivos temporales de validación y generamos el certificado:
mkdir -p /var/www/letsencrypt
certbot certonly --webroot -w /var/www/letsencrypt -d [DOMINIO][SUB_DOMINIO] por el dominio o subdominio que necesites configurar y que esté apuntando a la IP del servidor.Si la validación es correcta, se generará el certificado en:
- /etc/letsencrypt/live/[DOMINIO]/fullchain.pem
- /etc/letsencrypt/live/[DOMINIO]/privkey.pem
Certbot también configura una tarea automática para renovar el certificado periódicamente. Puedes probar la renovación en cualquier momento con:
certbot renew --dry-runConfiguración del Proxy Nginx con el SSL generado
Una vez generado el certificado, creamos el bloque de servidor que actuará como proxy inverso. Este bloque gestionará el tráfico HTTPS, reenviando las peticiones al puerto interno donde escucha nuestra aplicación o servicio.
server {
listen 80;
server_name [SUB_DOMINIO];
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name [SUB_DOMINIO];
ssl_certificate /etc/letsencrypt/live/[SUB_DOMINIO]/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/[SUB_DOMINIO]/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:[PUERTO_INTERNO];
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass_header Server;
proxy_redirect off;
proxy_set_header Connection "";
}
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header Content-Security-Policy "upgrade-insecure-requests";
access_log /var/log/nginx/[SUB_DOMINIO]_access.log;
error_log /var/log/nginx/[SUB_DOMINIO]_error.log warn;
}[SUB_DOMINIO] y [PUERTO_INTERNO] por los correspondientes a tu aplicación.Ejemplo práctico con una APP
Por ejemplo, si tenemos una aplicación ejecutándose en el puerto interno 3000, la configuración sería:
server {
listen 80;
server_name miapp.voidnull.es;
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name miapp.voidnull.es;
ssl_certificate /etc/letsencrypt/live/miapp.voidnull.es/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/miapp.voidnull.es/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass_header Server;
proxy_redirect off;
proxy_set_header Connection "";
}
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header Content-Security-Policy "upgrade-insecure-requests";
access_log /var/log/nginx/miapp.voidnull.es_access.log;
error_log /var/log/nginx/miapp.voidnull.es_error.log warn;
}Verificación y reinicio del servicio
Antes de reiniciar Nginx, es importante comprobar que la configuración es válida:
nginx -tSi no hay errores, recarga el servicio para aplicar los cambios:
systemctl reload nginxRenovación automática
Certbot crea una tarea automática mediante systemd o cron para renovar los certificados antes de su expiración. Puedes verificar el estado o forzar una prueba de renovación con:
certbot renew --dry-runCon la configuración anterior (usando el método webroot), la renovación se realizará sin necesidad de detener Nginx ni modificar la configuración.
Conclusión
Con esta configuración, Nginx actuará como proxy inverso hacia cualquier servicio o aplicación que escuche en un puerto interno, ofreciendo acceso mediante HTTPS con Let’s Encrypt y cabeceras de seguridad adicionales.
Es una forma sencilla, segura y estandarizada de exponer aplicaciones internas con certificados válidos y redirección automática desde HTTP a HTTPS.
Más sobre ./voidNull
- 📖 Aprende todos sobre los comandos de GNU/Linux en nuestro Diccionario "De la A a la Z: Los comandos de GNU/Linux"
- 💪 ¡Forma parte de la Comunidad de ./voidNull!
- 🤖 Disfruta de todos nuestros Cursos sobre Ansible, Proxmox, Home Assistant entre otros.
- 📩 Mantente actualizado con lo último en GNU/Linux y Software Libre. Recibe nuestra Newsletter mensual.
Comentarios