Nginx: configuración como proxy inverso

En este tutorial dedicado a Nginx, explicaré cómo configurarlo para tener un proxy inverso.

Antes de llegar al meollo del asunto, le presentaré rápidamente Nginx y lo que es un proxy inverso.

Para este tutorial, utilicé una máquina con Ubuntu 20.04.

Introducción a Nginx

Nginx es un servidor web como Apache2 o IIS que tiene la «filosofía» de ser ligero y rápido. Está disponible en varios sistemas operativos (Windows, Linux…).

Hoy en día, hay dos versiones:

  • Una versión comunitaria abierta y gratuita disponible aquí : nginx.org
  • Una versión comercial que incluye características avanzadas de configuración, seguridad y administración disponible en nginx.com.

Nginx permite «de forma nativa» configurar una solución de proxy inverso, en su infancia, Nginx se usaba principalmente para eso.

¿Qué es un proxy inverso? y ¿por qué usar uno?

Un proxy inverso funciona de la misma manera que un proxy interno para ir a Internet, pero en la dirección opuesta, es decir, captura la solicitud HTTP destinada al servidor web de Internet y la procesa él mismo.

El uso de un proxy inverso tiene varios intereses:

  • Guardar direcciones IP públicas: en la misma dirección IP pública es posible publicar varios sitios web alojados en uno o más servidores en DMZ, por ejemplo.
  • Optimice el rendimiento y reduzca la carga de los servidores web, el servidor proxy puede actuar como un caché para la cantidad de solicitudes al servidor que aloja el sitio, para sitios de alto tráfico, también puede usarse como una descarga SSL.
  • Facilitar la gestión de certificados SSL, al utilizar la descarga SSL y al gestionar los certificados desde el proxy inverso, se tiene un único servidor a gestionar, lo que ahorra tiempo y evita descuidos a la hora de renovar un certificado, especialmente al utilizar comodines (*.xxxxxxx. aa).
  • La seguridad, que también es una de las principales ventajas, ya que te permite modificar la cabecera HTTP ocultando el servidor detrás de ella, sumado al uso de fail2ban o crowsec, puedes proteger todos los servidores publicados. También es posible, mediante las ubicaciones de las directivas, restringir el acceso a determinadas áreas (/wp-admin para WordPress, acceso a PowerShell para Exchange…).
  • Equilibrio de carga, Nginx permite el equilibrio de carga.

Instalación de Nginx

Para tener la versión más reciente de Nginx, es posible configurar el repositorio nginx.org

En este tutorial, usaré el repositorio de Ubuntu para tener el paquete nginx-extras, que instala varios complementos que veremos en este tutorial.

En la carpeta /etc/apt/sources.list.d/ cree un archivo nginx.list.

sudo touch /etc/apt/sources.list.d/nginx.list

Luego edite el archivo usando nano (o lo que sea).

sudo nano /etc/apt/sources.list.d/nginx.list

Agregue las siguientes líneas en él:

deb [arch=amd64] http://nginx.org/packages/mainline/ubuntu/ focal nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ focal nginx
Add nginx repo

Ahora ejecute las 2 líneas a continuación para instalar la firma del repositorio:

wget http://nginx.org/keys/nginx_signing.key 
sudo apt-key add nginx_signing.key

Actualizar línea de paquete:

sudo apt update
update repository

En la captura anterior, vemos que se han consultado los repositorios de Nginx.

Ahora podemos pasar a instalarlo desde Nginx.

Ingrese el siguiente comando para instalar Nginx

sudo apt install nginx nginx-extras
Install nginx and extra for reverse proxy

Cuando se complete la instalación, verifique que Nginx funcione correctamente:

sudo systemctl status nginx

También es posible desde un navegador ir a la dirección: http://server-ip. Debería aparecer la página Bienvenido Nginx.

Además, también es posible instalar certbot para Nginx para generar certificados Let’s Encrypt.

sudo apt install python3-certbot-nginx

Nuestro servidor ya está listo, podemos pasar a configurar nuestros diferentes hosts virtuales en el proxy inverso.

Configuración de Nginx como proxy inverso

Como probablemente ya haya entendido, el objetivo aquí no es usar las funciones de proxy inverso de Nginx para servir sitios que estarían alojados en el propio servidor usando un contenedor u otro servidor web (Apache, Tomcat…) sino para servir sitios (aplicaciones) que están alojados en otro servidor.

En algunos casos podemos tener un problema de registro de DNS, sobre todo cuando el servidor que está detrás del proxy usa virtualhosts y que existe un registro y que posteriormente apuntará al proxy inverso, nos encontramos con esta configuración principalmente cuando el proxy inverso debe resolver la url y que apunta a ella.

Para resolver este problema, vamos a codificar el servidor proxy en el archivo /etc/hosts con la resolución correcta, para lograr este resultado:

Para agregar una grabación, abra el archivo con nano (u otro).

sudo nano /etc/hosts

Luego agregue el registro en el formato:

ip_adr dns_record

Ahora que se soluciona este problema, veremos cómo configurar nuestro proxy inverso con Nginx.

Proxy inverso Nginx: configuración «estándar»

Para ilustrar este primer tutorial, enviaremos tráfico a un servidor IIS simple, usaremos el nombre DNS rproxy.rdr-it.io

Cree un archivo de configuración para el virtualhost

sudo touch /etc/nginx/sites-available/rproxy-rdr-it-io

Abre el archivo que acabas de crear:

sudo nano /etc/nginx/sites-available/rproxy-rdr-it-io

Pegue la configuración a continuación (cada línea está comentada):

Ahora necesitamos agregar un enlace simbólico para activar nuestra configuración:

sudo ln -s /etc/nginx/sites-available/rproxy-rdr-it-io /etc/nginx/sites-enabled

Pruebe la configuración de Nginx:

sudo nginx -t

Si todo está bien, vuelva a cargar la configuración:

sudo systemctl reload nginx

Es hora de probar, antes de asegurarse de que su registro de dns (url) esté apuntando al proxy inverso. 😉

Desde un navegador, se muestra la página IIS de mi servidor:

También puede ver el tráfico en los registros de Nginx (access.log).

Antes de pasar al siguiente paso, sugiero una pequeña mejora para nuestro host virtual, separaremos los registros de acceso en un archivo separado agregando el siguiente código:

access_log /var/log/nginx/rproxy-rdr-it-io_access.log;

Lo que da en el archivo virtualhost:

Luego vuelva a cargar la configuración de Nginx.

El archivo de registro está presente en el servidor, haga una solicitud para ver si todo funciona.

Ahora sabe cómo configurar virtualhost en modo de proxy inverso con Nginx.

Proxy inverso de Nginx: configuración de reescritura/anulación

Ahora pasaremos a una configuración donde reescribiremos el código HTML que se devuelve al navegador.

Esta modificación es posible con el módulo: Módulo HTTP Subs Filter.

Este tipo de configuración se utiliza habitualmente a la hora de publicar aplicaciones de forma interna y externa (en Internet) y la aplicación se configura con una URL interna y por tanto inaccesible desde Internet. También usamos este módulo para cambiar el puerto de publicación de una aplicación, por ejemplo, cierta aplicación (Tomcat) usa el puerto 8080, la reescritura permite que el servicio se publique en un puerto estándar 80/443.

Para verificar si el módulo está presente, vea el contenido de la carpeta /etc/nginx/modules-enabled/ y verifique que el enlace simbólico 50-mod-http-subs-filter.conf esté presente.

No voy a repasar la creación del host virtual, esto se ha discutido antes.

En esta parte, te mostraré dos ejemplos:

  • Un simple en código HTML
  • El segundo en WordPress

Ejemplo 1

Para este primer ejemplo, probaremos con una simple reescritura (sustitución) en un archivo HTML (index.html).

Como podemos ver en la captura de pantalla a continuación, trabajaremos en el dominio rdr-it.lan que solo está disponible desde una red privada y ahora queremos publicarlo en Internet en rdr-it.fr.

Aquí está el archivo index.html:

Podemos ver que la url rdr-it.lan está codificada dos veces.

A continuación se muestran los archivos (index.html e imagen):

Aquí está el resultado de un acceso interno.

Ahora le mostraré la configuración que le permitirá modificar rdr-it.lan a rdr-it.fr para poder publicar el sitio en Internet.

Aquí está el archivo de configuración de virtualhost:

Una vez que se agrega la configuración, cree el enlace simbólico, verifique la configuración y vuelva a cargar la configuración de Nginx.

Desde un navegador, vaya a la url accesible desde Internet, normalmente todo debería mostrarse correctamente.

Podemos ver a continuación que el código se ha reescrito con la URL correcta.

Ejemplo 2

En este segundo ejemplo de reescritura de contenido HTML, lo haré con un sitio de WordPress, como veremos más adelante, la configuración del virtualhost es un poco más complicada y usamos RegEx para modificar el contenido.

En las capturas de pantalla a continuación, una descripción general del sitio de WordPress:

Cree el archivo virtualhost y copie la configuración a continuación, adaptándose a su configuración.

Aquí algunas capturas:

  • Administración de WordPres donde podemos ver que la url (config) se cambia dinámicamente
  • Configuración en la base de datos con la url original: wp.rdr-it.lan
  • Captura de la solicitud HTTP donde podemos ver que estamos pasando por Nginx y no por LiteSpeed
  • Una visión general de los registros

Proxy inverso con equilibrio de carga

Para finalizar este tutorial, presentaré una configuración de proxy inverso Nginx con equilibrio de carga.

En la declaración de los servidores en el bloque upstream, es posible indicar un peso (preferencia),

upstream ServersWebPool{
    # Declare each server
    server srv-web-01 weight=3;
    server srv-web-02;
}

En el ejemplo anterior, para 4 solicitudes HTTP, 3 solicitudes irán a srv-web-01 y una solicitud a srv-web-02.

El último elemento que se puede configurar es la disponibilidad del servicio:

upstream ServersWebPool{
    # Declare each server
    server srv-web-01 max_fails=3 fail_timeout=60s;
    server srv-web-02;
}

En el ejemplo anterior, después de 3 fallas en el servidor srv-web-01, se considerará no disponible durante 60 segundos.

Por defecto, el valor max_fails es igual a 1 y fail_timeout a 10 segundos.


Ahora sabe cómo configurar Nginx como un proxy inverso y reescribir (sustituir) el contenido HTML para que coincida con la URL de solicitud en caso de que el código HTML no use enlaces absolutos.