Cómo utilizar Apache como proxy inverso con mod_proxy en Ubuntu 20.04

Introducción
Un proxy inverso es un tipo de servidor proxy que recibe solicitudes HTTP(S) y las distribuye de forma transparente a uno o más servidores backend. Los proxies inversos son útiles porque muchas aplicaciones web modernas procesan las solicitudes HTTP entrantes mediante servidores de aplicaciones backend. Estos servidores no están pensados para que los usuarios accedan a ellos directamente y, a menudo, solo admiten funciones HTTP básicas.
Puede utilizar un proxy inverso para evitar que se acceda directamente a estos servidores de aplicaciones subyacentes. También se pueden utilizar para distribuir la carga de las solicitudes entrantes a varios servidores de aplicaciones diferentes, lo que aumenta el rendimiento a escala y proporciona seguridad ante fallos. Pueden completar los vacíos con funciones que los servidores de aplicaciones no ofrecen, como el almacenamiento en caché, la compresión o el cifrado SSL.
En este tutorial, configurará Apache como un proxy inverso básico utilizando la mod_proxy
extensión para redirigir las conexiones entrantes a uno o varios servidores backend que se ejecutan en la misma red. Este tutorial utiliza un backend escrito con el marco web Flask, pero puede utilizar cualquier servidor backend que prefiera.
Prerrequisitos
Para seguir este tutorial, necesitarás:
- Un servidor Ubuntu 20.04 configurado con este tutorial de configuración inicial del servidor, que incluye un usuario
sudo
no root y un firewall. - Apache 2 instalado en su servidor siguiendo los pasos 1 y 2 de Cómo instalar el servidor web Apache en Ubuntu 20.04.
Paso 1: Habilitar los módulos Apache necesarios
Apache incluye muchos módulos que están disponibles pero no se habilitan en una instalación nueva. Primero, deberá habilitar los que usará en este tutorial.
Los módulos que necesitas son mod_proxy
el propio servidor y varios de sus módulos complementarios, que amplían su funcionalidad para admitir distintos protocolos de red. En concreto, utilizarás los siguientes:
mod_proxy
: el módulo proxy principal para redirigir conexiones. Permite que Apache actúe como puerta de enlace a los servidores de aplicaciones subyacentes.mod_proxy_http
:Agrega soporte para proxy de conexiones HTTP.mod_proxy_balancer
ymod_lbmethod_byrequests
: agregan funciones de equilibrio de carga para múltiples servidores back-end.
Para habilitar estos cuatro módulos, ejecute el siguiente comando:
- sudo a2enmod proxy proxy_http proxy_balancer lbmethod_byrequests
Para que estos cambios surtan efecto, reinicie Apache:
- sudo systemctl restart apache2
Apache ya está listo para actuar como un proxy inverso para las aplicaciones HTTP. En el siguiente paso opcional, creará dos servidores backend básicos. Estos ayudarán a verificar si la configuración funciona correctamente, pero si ya tiene su propia aplicación backend, puede saltar al Paso 3.
Paso 2: creación de servidores de prueba backend (recomendado)
Ejecutar algunos servidores backend puede ayudar a probar si su configuración de Apache está funcionando correctamente. Aquí, creará dos servidores de prueba que respondan a las solicitudes HTTP imprimiendo una línea de texto. Un servidor dirá ¡Hola mundo! y el otro dirá ¡Hola mundo! Esto le permitirá probar el equilibrio de carga entre varios servicios.
Nota: En configuraciones del mundo real, los servidores backend generalmente devuelven el mismo tipo de contenido. Sin embargo, para los fines de esta prueba, hacer que los dos servidores devuelvan mensajes diferentes le permite verificar que el mecanismo de equilibrio de carga usa ambos.
Flask es un microframework de Python para crear aplicaciones web. Este paso describe cómo usar Flask para crear los servidores de prueba, ya que una aplicación mínima requiere solo unas pocas líneas de código. No es necesario que sepas Python para configurarlos, pero si quieres aprender, puedes consultar nuestra serie sobre Cómo codificar en Python.
Primero actualice la lista de índice de paquetes usando apt
:
- sudo apt update
A continuación, instale pip
el administrador de paquetes de Python recomendado:
- sudo apt install python3-pip
A continuación, utilice pip
para instalar Flask:
- sudo pip3 install Flask
Ahora que todos los componentes necesarios están instalados, crea un nuevo archivo que contendrá el código para el primer servidor backend en el directorio de inicio del usuario actual. Puedes hacerlo con tu editor de texto preferido. Aquí usaremos nano
:
- nano ~/backend1.py
Inserte el siguiente fragmento de código en el archivo:
~/backend1.py
from flask import Flaskapp = Flask(__name__)@app.route('/')def home(): return 'Hello world!'
Las dos primeras líneas de código inicializan el marco Flask. Hay una función home()
que devuelve una línea de texto ( Hello world!
). La @app.route('/')
línea sobre la home()
definición de la función le indica a Flask que usa home()
el valor de retorno de como respuesta a las solicitudes HTTP dirigidas a la /
URL raíz de la aplicación.
Una vez que hayas terminado, guarda y sal del archivo. Si estás usando nano
, puedes hacerlo presionando CTRL + X
, luego Y
y ENTER
.
El segundo servidor backend es exactamente igual que el primero, salvo que devuelve una línea de texto diferente. Por lo tanto, ejecute cp
para copiar el contenido del primer archivo backend1.py
al backend2.py
archivo:
- cp ~/backend1.py ~/backend2.py
Ahora abra el archivo recién copiado usando su editor de texto preferido:
- nano ~/backend2.py
Actualice el mensaje que devuelve el mensaje ¡Hola mundo! para que diga ¡Hola mundo! en su lugar:
~/backend2.py
from flask import Flaskapp = Flask(__name__)@app.route('/')def home(): return 'Howdy world!'
Una vez que haya terminado de realizar la actualización, guarde y cierre el archivo.
A continuación, utilice el siguiente comando para iniciar el primer servidor en el segundo plano en el puerto 8080
. Esto también redirige la salida de Flask a, /dev/null
ya que enturbiaría la salida de la consola en el futuro:
- FLASK_APP=~/backend1.py flask run --port=8080 /dev/null 21
Aquí, precede al flask
comando estableciendo la FLASK_APP
variable de entorno en la misma línea. Las variables de entorno son una forma conveniente de pasar información a los procesos que se generan desde el shell. Puedes obtener más información sobre las variables de entorno en nuestra guía sobre Cómo leer y configurar variables ambientales y de shell en un VPS Linux.
En este caso, el uso de una variable de entorno garantiza que la configuración se aplique únicamente al comando que se está ejecutando y no permanecerá disponible posteriormente. Esto es necesario para evitar confusiones, ya que pasará otro nombre de archivo de la misma manera para indicarle al flask
comando que inicie el segundo servidor.
De manera similar, desea ejecutar el siguiente comando para iniciar el segundo servidor en el puerto 8081
. Observe el valor diferente para la FLASK_APP
variable de entorno:
- FLASK_APP=~/backend2.py flask run --port=8081 /dev/null 21
Ahora puede probar si los dos servidores están en funcionamiento mediante el curl
comando. Comience probando el primer servidor. Este comando utiliza curl
para conectarse a 127.0.0.1
, una dirección IP especial que representa localhost . Esto significa que el siguiente comando le indica a su servidor que se conecta a sí mismo e imprime su propia respuesta:
- curl http://127.0.0.1:8080/
Esto imprimirá la siguiente respuesta del servidor:
OutputHello world!
A continuación, pruebe el segundo servidor:
- curl http://127.0.0.1:8081/
Como antes, esto imprimirá la respuesta esperada del servidor:
OutputHowdy world!
En el siguiente paso, modificará el archivo de configuración de Apache para habilitar su uso como proxy inverso.
Paso 3: Modificación de la configuración predeterminada para habilitar el proxy inverso
En esta sección, configurará el host virtual Apache predeterminado para que sirva como proxy inverso para un solo servidor back-end o una matriz de servidores back-end con equilibrio de carga.
Nota : En este tutorial, se aplica la configuración al nivel de host virtual. En una instalación predeterminada de Apache, solo hay un único host virtual predeterminado habilitado. Sin embargo, también puede usar todos esos fragmentos de configuración en otros hosts virtuales. Para obtener más información sobre los hosts virtuales en Apache, puede leer nuestro tutorial Cómo configurar hosts virtuales Apache en Ubuntu 20.04.
Si su servidor Apache actúa como servidor HTTP y HTTPS, su configuración de proxy inverso debe colocarse en los hosts virtuales HTTP y HTTPS. Para obtener más información sobre SSL con Apache, puede leer nuestro tutorial Cómo crear un certificado SSL autofirmado para Apache en Ubuntu 20.04.
Abra el archivo de configuración predeterminado de Apache utilizando su editor de texto preferido:
- sudo nano /etc/apache2/sites-available/000-default.conf
Dentro de ese archivo, encontrará el VirtualHost *:80
bloque que comienza en la primera línea. El primer ejemplo siguiente explica cómo configurar este bloque para que actúe como proxy inverso para un solo servidor backend, y el segundo ejemplo configura un proxy inverso con equilibrio de carga para varios servidores backend.
Ejemplo 1: Proxy inverso de un único servidor backend
En primer lugar, reemplace todo el contenido dentro del VirtualHost
bloque para que su archivo de configuración se lea como el siguiente. Si ha seguido los servidores de ejemplo en el Paso 2, utilice 127.0.0.1:8080
. Si tiene sus propios servidores de aplicaciones, utilice sus direcciones en su lugar:
/etc/apache2/sites-available/000-default.conf
VirtualHost *:80 ProxyPreserveHost On ProxyPass / http://127.0.0.1:8080/ ProxyPassReverse / http://127.0.0.1:8080//VirtualHost
Hay tres directivas representadas, aquí hay una breve descripción general de lo que están haciendo:
ProxyPreserveHost
: hace que Apache pase el encabezado originalHost
al servidor backend. Esto es útil, ya que hace que el servidor backend conozca la dirección utilizada para acceder a la aplicación.ProxyPass
: la directiva de configuración del proxy principal. En este caso, especifica que todo lo que se encuentre bajo la URL raíz (/
) debe asignarse al servidor backend en la dirección indicada. Por ejemplo, si Apache recibe una solicitud para/example
, se conectará y devolverá la respuesta al cliente original.http://your_backend_server/example
ProxyPassReverse
: debe tener la misma configuración queProxyPass
. Le indica a Apache que modifica los encabezados de respuesta del servidor backend. Esto garantiza que si el servidor backend devuelve un encabezado de redirección de ubicación, el navegador del cliente se redirija a la dirección del proxy y no a la dirección del servidor backend, lo que no funcionaría como se esperaba.
Una vez que haya terminado de agregar este contenido, guarde y salga del archivo.
Para que estos cambios surtan efecto, reinicie Apache:
- sudo systemctl restart apache2
Ahora, si accedes a través de un navegador web, verás la respuesta de tu servidor backend en lugar de la página de bienvenida estándar de Apache. Si sigues el paso 2, esto significa que verás ¡Hola mundo! en el navegador.http://your_server_ip
Ejemplo 2: equilibrio de carga entre varios servidores back-end
Si tiene varios servidores back-end, una buena forma de distribuir el tráfico entre ellos al utilizar proxy es utilizar las funciones de equilibrio de carga de mod_proxy
.
Primero abra el archivo de configuración predeterminado de Apache usando su editor de texto preferido:
- sudo nano /etc/apache2/sites-available/000-default.conf
Ahora reemplace todo el contenido dentro de VirtualHost
para que su archivo de configuración se lea como el siguiente. Si siguió los servidores de ejemplo en el Paso 2, utilice 127.0.0.1:8080
y 127.0.0.1:8081
para las BalancerMember
directivas. Si tiene sus propios servidores de aplicaciones, utilice sus direcciones en su lugar:
/etc/apache2/sites-available/000-default.conf
VirtualHost *:80Proxy balancer://mycluster BalancerMember http://127.0.0.1:8080 BalancerMember http://127.0.0.1:8081/Proxy ProxyPreserveHost On ProxyPass / balancer://mycluster/ ProxyPassReverse / balancer://mycluster//VirtualHost
La configuración es similar a la anterior, pero en lugar de especificar directamente un único servidor backend, estas directivas hacen lo siguiente:
Proxy
: esteProxy
bloque adicional se utiliza para definir varios servidores. El bloque tiene un nombre (el nombre se puede modificar libremente) y consta de uno o más s, que especifican las direcciones del servidor backend subyacente.balancer://mycluster
BalancerMember
ProxyPass
yProxyPassReverse: these directives use the load balancer pool named
mycluster` en lugar de un servidor específico.
Si siguió los servidores de ejemplo del paso 2, utilice 127.0.0.1:8080
y 127.0.0.1:8081
para las BalancerMember
directivas, como se indica en el bloque anterior. Si tiene sus propios servidores de aplicaciones, utilice sus direcciones en su lugar.
Una vez que haya terminado de agregar este contenido, guarde y salga del archivo.
Para que estos cambios surtan efecto, reinicie Apache:
- sudo systemctl restart apache2
Si accede a través de un navegador web, verá las respuestas de sus servidores backend en lugar de la página estándar de Apache. Si siguió el paso 2, al actualizar la página varias veces debería aparecer ¡Hola mundo! y ¡Hola mundo!, lo que significa que el proxy inverso funcionó y está equilibrando la carga entre ambos servidores.http://your_server_ip
Nota : Para cerrar ambos servidores de prueba cuando ya no los necesite, como cuando termine este tutorial, puede ejecutar el killall flask
comando.
Conclusión
Ahora ya sabes cómo configurar Apache como un proxy inverso para uno o varios servidores de aplicaciones subyacentes. mod_proxy
Se puede utilizar de forma eficaz para configurar un proxy inverso para servidores de aplicaciones escritas en una amplia gama de lenguajes y tecnologías, como Python y Django, o Ruby y Ruby on Rails. También se puede utilizar para equilibrar el tráfico entre varios servidores back-end para sitios con mucho tráfico, para proporcionar alta disponibilidad a través de varios servidores o para proporcionar compatibilidad con SSL segura a servidores back-end que no admiten SSL de forma nativa.
Si bien mod_proxy
con mod_proxy_http
es quizás la combinación de módulos más utilizados, existen otros que admiten distintos protocolos de red. No los usamos en este tutorial, pero algunos otros módulos populares incluyen:
mod_proxy_ftp
para FTP (Protocolo de transferencia de archivos).mod_proxy_connect
para tunelización SSL.mod_proxy_ajp
para AJP (Protocolo Apache JServ), como los backends basados en Tomcat.mod_proxy_wstunnel
para sockets web.
Para obtener más información sobre mod_proxy
, puedes leer la mod_proxy
documentación oficial de Apache .
Deja una respuesta