Configuración de Nginx como Proxy Inverso para aplicaciones Spring Boot con Let’s Encrypt SSL en Ubuntu Server 24.04

Introducción

En este tutorial, te mostraré cómo configurar un servidor Ubuntu Server 24.04 con Nginx para actuar como proxy inverso para dos aplicaciones Spring Boot. Además, te guiaré en la instalación y configuración de certificados SSL con Let’s Encrypt para los dominios controlgastospersonales.app y su subdominio api.controlgastospersonales.app.

Requisitos Previos
  • Un servidor Ubuntu Server 24.04 (en este caso, alojado en Linode).
  • Dos aplicaciones Spring Boot en los puertos 8080 y 8081.
  • Un dominio principal y subdominio:
    • Dominio principal: controlgastospersonales.app
    • Subdominio: api.controlgastospersonales.app
  • Nginx instalado en el servidor.
  • Certbot para gestionar los certificados SSL de Let’s Encrypt.
Paso 1: Instalar Nginx

Si no tienes Nginx instalado, primero ejecuta los siguientes comandos:

Bash
sudo apt update
sudo apt install nginx

Paso 2: Configurar Nginx como Proxy Inverso

Configuración para la WebApp (controlgastospersonales.app)

Crea un archivo de configuración para el dominio principal en /etc/nginx/sites-available/controlgastospersonales.app:

Bash
sudo nano /etc/nginx/sites-available/controlgastospersonales.app

Agrega el siguiente contenido para dirigir el tráfico a la aplicación Spring Boot que corre en el puerto 8080:

Bash
server {
		 listen 80;
		 server_name controlgastospersonales.app www.controlgastospersonales.app;

		 location / {
		     proxy_pass http://localhost:8080;
		     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;
		 }
	}

Configuración para el REST API (api.controlgastospersonales.app)

Crea el archivo de configuración para el subdominio en /etc/nginx/sites-available/api.controlgastospersonales.app:

Bash
sudo nano /etc/nginx/sites-available/api.controlgastospersonales.app

Agrega la siguiente configuración para redirigir el tráfico al puerto 8081 donde corre la API:

Bash
server {
		 listen 80;
		 server_name api.controlgastospersonales.app;

		 location / {
		     proxy_pass http://localhost:8081;
		     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;
		 }
	}

Habilitar las configuraciones

Ahora, habilita las configuraciones creando enlaces simbólicos a los archivos en el directorio sites-enabled:

Bash
sudo ln -s /etc/nginx/sites-available/controlgastospersonales.app /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/api.controlgastospersonales.app /etc/nginx/sites-enabled/

Paso 3: Probar y Recargar Nginx

Antes de recargar Nginx, verifica que no haya errores en la configuración:

Bash
sudo nginx -t

Se debería ver una salida como la siguiente:

Bash
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Si no hay errores, recarga Nginx para que los cambios surtan efecto:

Bash
sudo systemctl reload nginx

Paso 4: Instalar Certbot y Configurar SSL

Instalar Certbot: Ejecuta el siguiente comando para instalar Certbot y el complemento para Nginx:

Bash
sudo apt install certbot python3-certbot-nginx

Obtener Certificados SSL:

Para el dominio principal (controlgastospersonales.app) ejecuta el siguiente comando:

Bash
sudo certbot --nginx -d controlgastospersonales.app -d www.controlgastospersonales.app

Se debería ver una salida como la siguiente:

Bash
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): ivanetinajero@gmail.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.4-April-3-2024.pdf. You must agree in
order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: n
Account registered.
Requesting a certificate for controlgastospersonales.app and www.controlgastospersonales.app

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/controlgastospersonales.app/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/controlgastospersonales.app/privkey.pem
This certificate expires on 2025-01-16.
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 controlgastospersonales.app to /etc/nginx/sites-enabled/controlgastospersonales.app
Successfully deployed certificate for www.controlgastospersonales.app to /etc/nginx/sites-enabled/controlgastospersonales.app
Congratulations! You have successfully enabled HTTPS on https://controlgastospersonales.app and https://www.controlgastospersonales.app

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Para el subdominio (api.controlgastospersonales.app) ejecuta el siguiente comando:

Bash
sudo certbot --nginx -d api.controlgastospersonales.app

Se debería de ver una salida como la siguiente:

Bash
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for api.controlgastospersonales.app

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/api.controlgastospersonales.app/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/api.controlgastospersonales.app/privkey.pem
This certificate expires on 2025-01-16.
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 api.controlgastospersonales.app to /etc/nginx/sites-enabled/api.controlgastospersonales.app
Congratulations! You have successfully enabled HTTPS on https://api.controlgastospersonales.app

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Esto configurará automáticamente los certificados SSL y actualizará la configuración de Nginx.

Paso 5. Verificar que SSL esté configurado correctamente

Certbot debería haber modificado tus archivos de configuración de Nginx para que ahora se vean así para el dominio principal controlgastospersonales.app:

Bash
server {

    server_name controlgastospersonales.app www.controlgastospersonales.app;

    location / {
        proxy_pass http://localhost:8080;
        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;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/controlgastospersonales.app/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/controlgastospersonales.app/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {

    if ($host = www.controlgastospersonales.app) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = controlgastospersonales.app) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name controlgastospersonales.app www.controlgastospersonales.app;
    return 404; # managed by Certbot

}

Y para el subdominio api.controlgastospersonales.app:

Bash
server {

    server_name api.controlgastospersonales.app;

    location / {
        proxy_pass http://localhost:8081;
        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;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/api.controlgastospersonales.app/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/api.controlgastospersonales.app/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {

    if ($host = api.controlgastospersonales.app) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name api.controlgastospersonales.app;
    return 404; # managed by Certbot

}

Probar nuevamente Nginx:

Bash
sudo nginx -t
sudo systemctl reload nginx

Conclusión

Con estos pasos, ahora tienes Nginx configurado como proxy inverso para tus aplicaciones Spring Boot, y tu servidor está asegurado con certificados SSL de Let’s Encrypt. Esto te garantiza un acceso seguro a tus dominios controlgastospersonales.app y api.controlgastospersonales.app.