Llegado a cierto punto, si tenemos más de un servidor web o API que queremos exponer, estos terminan colisionando en los puertos. Si bien podemos modificarlos o remapearlos en el caso de contenedores, los puertos por defecto para la mayoría de casos siguen siendo:

  • 80 para HTTP.
  • 443 para HTTPS.

Si uno se sale de ese estándar, se convierte en algo incómodo, ya que tienes que memorizar los puertos, o lo hace menos confiable a la hora de una navegación normal en el caso de las webs.

Para solventar esto, entra en juego lo que se conoce como Reverse Proxy o Proxy inverso.

Además, nos vemos en la situación en muchos casos de necesitar un certificado SSL. Estos, aunque tienen un precio habitualmente, también se pueden obtener de forma gratuita, pero gestionarlos y mantenerlos renovados siempre es un lío.

Para tener todo esto, haremos uso de Nginx Proxy Manager.

Requisitos

Si deseas seguir esta guía, te recomiendo disponer de lo siguiente:

  • Un entorno Docker configurado, con la posibilidad de ejecutar docker compose. Si no dispones de uno, puedes seguir esta guía: Install Docker and Portainer CE
  • Un servidor DNS para asignar nombres de dominio a los puntos de entrada. Puedes usar uno externo y abrir puertos, o si usarás NPM internamente puedes tener PiHole

Idealmente también contar con:

  • Un par de servidores WEB que desees darles visibilidad.
  • Para certificados SSL: Un dominio en posesión, con una entrada DNS apuntando a tu servidor.

¿Qué es un proxy inverso?

Un Reverse Proxy o Proxy Inverso es un servicio que se sitúa entre un cliente y un servidor, recibiendo las solicitudes de los clientes y encargándose de distribuirlas al servidor correspondiente. Esta redirección para el cliente es totalmente transparente.

Las principales ventajas y funcionalidades de un Proxy Inverso son las siguientes:

  • Centralización y balanceo de carga del tráfico entrante.
  • Simplificación y abstracción de los servicios expuestos.
  • Gestión de SSL/TLS en un único punto.
  • Posibilidad de filtrado de solicitudes maliciosas antes de llegar al servidor de destino real.
  • Capacidad de implementar una capa previa de autenticación y control de acceso.

Nginx Proxy Manager

Nginx es un servidor web clásico, que nos permite hostear nuestras páginas web estáticas. Pero tiene una funcionalidad adicional: también puede hacer de proxy inverso.

Podríamos realizar la configuración para ello de forma manual, instalando los diferentes módulos, pero se trata de una funcionalidad tan extendida que ya se empaqueta incluso en contenedores para su uso.

Este paquete, conocido como NPM o Nginx Proxy Manager incluye hasta una interfaz gráfica desde la que podremos gestionar todo lo necesario: Desde configuraciones de redirección, hasta certificados SSL y sus renovaciones automáticas.

Instalación

Para realizar la instalación, haremos uso de la imagen Docker oficial. Como se ha mencionado hay otros métodos, pero hoy día este es el recomendable, sobre todo por su comodidad.

Por simplicidad, os dejo el docker-compose.yml, y a partir de este os dejaré las adaptaciones que deberíais hacer para vuestro entorno.

Docker Compose

Fichero docker-compose.yml base para NPM:

services:
 npm:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    container_name: nginx
    ports:
     - '80:80' # Public HTTP Port
     - '443:443' # Public HTTPS Port
     - '81:81' # Admin Web Port
    volumes:
      - type: bind
        source: /home/user/nginx/data
        target: /data
        bind:
          create_host_path: true
      - type: bind
        source: /home/user/nginx/ssl
        target: /etc/letsencrypt
        bind:
          create_host_path: true

Con este fichero, estamos indicando que NPM va a usar los siguientes puertos:

  • 80 para solicitudes HTTP.
  • 443 para solicitudes HTTPS.
  • 81 para la interfaz de gestión de NPM.

De estos, no recomiendo modificarlos por simplicidad y evitar problemas de funcionamiento del proxy.

⚠️
Recuerda modificar las rutas definidas de los volúmenes bind en su propiedad device para que apunte a las rutas que desees. Estas se crearán automáticamente gracias a la propiedad create_host_path: true.

Una vez tengamos las modificaciones aplicadas, ejecutamos el siguiente comando:

sudo docker compose up -d

Esperamos un rato, y comprobamos si nuestro contenedor se ha lanzado correctamente:

sudo docker ps

Si tenemos más contenedores, saldrán listados, pero entre ellos deberíamos encontrar el de NPM.

Configuración

Tras lanzar el docker-compose.yml, podremos acceder a la interfaz web de gestión de Nginx Proxy Manager. Para ello, accederemos a la IP de nuestro servidor, seguido del puerto 81: http://ip.servidor.nginx.proxy:81

Y lo primero que nos aparecerá será el formulario para crear el usuario de administración:

Aquí tan solo tendremos que rellenarlo como prefiramos, creando nuestro primer usuario administrador de NPM al clicar en Save.

Con esto, podremos ver nuestro tablero principal:

Desde aquí es donde podremos gestionar todo lo que necesitemos.

Crear un host Proxy

Esta es la función principal de un Proxy Inverso, redirigir de un punto a otro el tráfico, enmascarando el servicio de destino.

Eso lo gestionaremos desde la sección de Proxy Host, donde actualmente no tenemos ninguno.

Para crear uno nuevo, le daremos a Add Proxy Host, y nos aparecerá el siguiente formulario:

Los campos que necesitaremos rellenar son los siguientes:

Campo Descripción
Domain Names Listado de nombres de dominio o IPs a los que este Proxy Host deberá atender y redirigir. Son el punto de entrada.
Scheme Elegir entre HTTP y HTTPS en función del protocolo de comunicación entre NPM y el servidor de destino.
Forward Hostname/IP Dirección IP o Dominio del servidor de destino. Este debe ser único.
Forward Port Puerto del servidor de destino al que redirigir.
Websockets Support Si el servidor que quieres visibilizar mediante el proxy hace uso de Websockets, deberás habilitarlo.

En mi caso, haré este de ejemplo, para redirigir el tráfico entrante a mi servicio de IT Tools, y le daré Save:

Y ahora en el listado nos sale nuestro Proxy Host, con los datos que le hemos introducido:

⚠️
En este punto, es necesario que dispongas de un servidor DNS con un dominio apuntando a NPM con el nombre que desees.

Este DNS puede ser externo mediante proveedores si deseas publicar estos servidores; o interno con servicios como PiHole

Si no tenemos dado de alta el dominio que hemos introducido, es el momento de hacerlo, y una vez lo tengamos, accederemos a él en una nueva pestaña de nuestro navegador. Al ser mi ejemplo con IT Tools, me sale la siguiente página, verificando por tanto que el Proxy Host ha hecho su trabajo:

Control de acceso

Otra de las grandes ventajas de usar NPM como Reverse Proxy es la capacidad de implementar un control de acceso.

Por ejemplo, en mi caso anterior donde he configurado el Proxy Host de IT Tools, podríamos exigir que se inicie sesión con un usuario y contraseña para verificar si se tiene o no acceso al servicio, antes siquiera de cargar la solicitud.

Toda esta configuración la haríamos desde la sección Acces Lists.

Le damos a Add Access Lists para que se nos abra el formulario de creación, donde le podremos introducir el nombre de la lista, además de, para este ejemplo, activar Satisfy Any, esto lo que hará es que deberemos cumplir cualquiera de las condiciones de control, con una será suficiente, en nuestro caso, usuario y contraseña:

Ahora iremos a la pestaña de Authorizations:

Es aquí donde se nos permitirá crear uno o varios usuarios para esta lista de acceso.

Le damos a Save y se nos creará la lista de acceso, apareciendo ahora en el listado:

Si regresamos a nuestros Proxy Hosts desde el desplegable del menú de Hosts, y editamos el que hemos creado anteriormente, podremos seleccionar la lista de control de acceso:

Elegimos nuestra nueva lista, y si ahora refrescamos la página que teníamos de nuestro servidor, veremos que aparece lo siguiente:

Se trata de la autenticación básica. Será aquí donde introduciremos los datos de uno de los usuarios creados anteriormente, y al hacerlo veremos que carga adecuadamente:

Con esto ya podemos limitar el acceso a ciertos servicios mediante usuario y contraseña.

ℹ️
Las Access Lists también permiten filtrado por direcciones IP de origen y otras funcionalidades.

Certificados SSL y uso de HTTPS

Como mencionaba al inicio del post, otra de las funcionalidades relevantes de Nginx Proxy Manager es la facilidad que nos da para solicitar, renovar y gestionar certificados SSL.

Para este punto, sí que es necesario tener un dominio contratado, sea con el proveedor que sea, y configurar el DNS del proveedor para que apunte a nuestra IP (usando DDNS o Cloudflare tunnels). En resumen, nuestro servidor de NPM debe ser visible desde el exterior al menos el puerto 443.

Una vez tengamos tengamos lo anterior listo, vamos a la sección de Certificates.

Le daremos a Add Certificate y nos aparecerá un formulario. Aquí agregaremos los dominios que deseemos. En mi caso, voy a utilizar los que tengo publicados y configurados en mi proveedor DNS:

Le damos a Save, y ahora nos aparecerá en la lista de certificados disponibles, con su estado. Aquí nos indicará la fecha de caducidad, si se está usando, y la opción de renovarlo.

Ahora podríamos regresar a nuestro Proxy Host y editarlo nuevamente, modificando el Scheme a HTTPS y luego yendo a la pestaña de SSL:

Seleccionamos ahora el certificado creado y le damos a guardar.

Ahora podremos acceder a nuestra web mediante HTTPS sin problemas y con un certificado válido.

Conclusión

Nginx Proxy Manager como Reverse Proxy o Proxy Inverso nos facilita enormemente la gestión de acceso a nuestros servicios web, junto con sus certificados y controles.

Ahora ya sabemos instalarlo y configurarlo adecuadamente para nuestras necesidades, pudiendo tener nuestros servicios publicados, con SSL/TLS y securizados con listas de acceso si fuera necesario.

Referencias

Lista de referencias empleadas para realizar este post:

Vídeo

0:00
/2:17