Subir archivos a '_posts'

This commit is contained in:
Echedelle López Romero 2022-07-12 11:06:10 +00:00
parent 6bee21ff9e
commit 04d6717f7e

View file

@ -0,0 +1,263 @@
---
layout: post
lang: es
title: "Apache HTTP Server: servidor «proxy» inverso y balanceador de carga"
date: 2022-07-12 07:56:13 +0100
categories: tutorials
---
Esta es la primera publicación formal desde que se fundó el sitio web, y he pensado inaugurarla con un tutorial para marcar el enfoque del sitio blog.
En este tutorial se explicará como usar Apache HTTP Server como servidor «proxy» inverso y balanceador de carga.
## Base inicial
Se empieza partiendo de un «VirtualHost» (Huesped Virtual) con un nombre de servidor, dirección de correo de administración, raíz de documentos y registros.
```
<VirtualHost *:80>
ServerName masfloss.net
ServerAdmin masfloss@riseup.net
Protocols h2c http/1.1
DocumentRoot /var/www/web
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
```
En este caso se usa de ejemplo el fichero por defecto de sitio `000-default`, que es usado para el puerto `80` con conexión «HTTP» sin cifrar.
Ya inicialmente, por razones de rendimiento, se habilita el protocolo «HTTP/2», específicamente la versión para conexiones no cifradas definida como «HTTP/2 Clearnet», y abreviada como «h2c», a diferencia del usado por defecto «h2» que sí es para conexiones cifradas.
Esto está declarado en la línea que incluye la directiva `Protocols` y se indican en orden los protocolos soportados por el sitio web que queremos hospedar.
Para poder hacer uso de ello, hay que habilitar el módulo `http2` con la orden `a2enmod <NOMBREDELMODULO>` con permisos de administración.
## Servidor «proxy» inverso
Para poder hacer que Apache HTTP Server como servidor «proxy» inverso, debemos habilitar algunos módulos aprovechando la orden visualizada previamente para ello.
Específicamente, los que habría que habilitar mínimo serían:
* `proxy_http`: permite la posiblidad de conexión a servidores de fondo por «HTTP».
* `proxy_html`: permite reemplazar los enlaces del sitio web que estamos «proxyficando» por los de la dirección por la que nos conectamos a nuestro servidor proxy inverso.
Adicionalmente, los siguientes módulos serían necesarios para ciertos casos o recomendados:
* `proxy_http2`: permite la posibilidad de conexión a servidores de fondo por «HTTP/2».
* `ssl`: usado en conjunto con el módulo `proxy_http` y/o `proxy_http2`, habilita la posibilidad de conexión a servidores de fondo por «HTTPS».
* `headers`: permite el establecimiento o modificación de cabeceras por parte del servidor web tanto a los clientes que se conectan como a los servidores de fondo.
Ahora, tocaría ver como quedaría reflejado en la configuración:
```
<VirtualHost *:80>
ServerName masfloss.net
ServerAdmin masfloss@riseup.net
Protocols h2c http/1.1
SSLProxyEngine On
ProxyPreserveHost On
ProxyRequests Off
ProxyPass /server-status !
ProxyPass / https://cualquierotroservidorweb.net
ProxyPassReverse / https://cualquierotroservidorweb.net
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
```
Como se puede apreciar, se suprime la directiva `DocumentRoot` dado que el servidor va a pasar todas las peticiones de la raíz a los servidores de fondo y se añaden algunas otras explicadas a continuación:
* `SSLProxyEngine`: al activarla, permite la conexión a servidores de fondo que usen "HTTPS", pero solo recomendado cuando nuestro servidor web no actúe como servidor «proxy» de redirección de peticiones, que no es el caso.
* `ProxyPreserveHost`: al activarla, envía la cabecera a los servidores de fondo con el nombre de dominio desde el que se está realizando la conexión, de forma que permite a los servidores de fondo actuar como si estos estuviesen actuando sobre ese dominio directamente sin una conexión «proxyficada».
* `ProxyRequests`: al desactivarla, se asegura que el servidor web no actúa como servidor «proxy» de resguardo de peticiones.
* `ProxyPass`: en este caso se usa de dos formas:
* La primera forma declara la directiva, establece una ruta de acceso alterna y hace uso del signo de exclamación. La idea es que esa ruta no sea traspasada a los servidores de fondo, sino que sea el propio servidor web el que la interprete.
* La segunda forma declara la directiva, establece una ruta de acceso a la raíz e indica una dirección web. Esto «proxyfica» la conexión a la raíz de nuestro sitio web hacia los servidores de fondo de la dirección web indicada.
* `ProxyPassReverse`: se declara de la misma manera que `ProxyPass` y simplemente se asegura de que nuestro servidor web actuando como servidor «proxy» inverso no es traspasado debido a redirecciones «HTTP» en los servidores de fondo de la dirección web indicada.
## Balanceador de carga
Partiendo de la configuración realizada para convertir Apache HTTP Server en un servidor «proxy» inverso, se puede transicionar hacia un balanceador de carga.
Para ello, se necesita activar, al menos, el módulo `proxy_balancer` que permite que Apache HTTP Server actúe como balanceador de carga.
Opcionalmente, se recomienda habilitar `proxy_hcheck` que permite evaluar la disponibilidad de los servidores de fondo y marcarlos como caídos en caso de no estar disponibles, y, al menos, uno de los módulos para las estrategias de distribución de carga de los dispuestos a continuación:
* `lbmethod_byrequests`: distribuye la carga teniendo entre los servidores de fondo basándose en una configuración de peticiones compartidas calculada según la demanda de trabajo esperada a realizar por cada servidor de fondo y la prioridad de cada servidor de fondo para suplir dicha demanda de trabajo.
* `lbmethod_bytraffic`: distribuye la carga teniendo en cuenta la cantidad de tráfico, en bytes, que se quiere que cada servidor de fondo maneje.
* `lbmethod_bybusyness`: distribuye la carga teniendo en cuenta la cantidad de peticiones que cada servidor de fondo tiene asignadas actualmente. Cada nueva petición es asignada automáticamente a aquel servidor de fondo con el número más bajo de peticiones activas.
Existe otro módulo experimental de distribución de carga llamado `lbmethod_hearbeat` que requiere el módulo `heartmonitor` para escuchar las peticiones de los servidores de fondo, que deben tener, a su vez, el módulo `heartbeat`. Con ello, se puede repartir la carga en base a la preparación de cada servidor de fondo, a diferencia de las otras estrategias.
Una configuración de base teniendo en cuenta esto, quedaría reflejada de la siguiente manera:
```
<VirtualHost *:80>
ServerName masfloss.net
ServerAdmin masfloss@riseup.net
Protocols h2c http/1.1
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
ProxyHCTemplate get5 hcmethod=GET hcinterval=5 hcpasses=1 hcfails=2 hcuri=/
<Proxy balancer://masfloss>
BalancerMember https://cualquierotroservidor.net route=masfloss1 hctemplate=get5
BalancerMember https://cualquierotroservidor2.net route=masfloss2 hctemplate=get5
ProxySet lbmethod=bybusyness stickysession=ROUTEID
</Proxy>
SSLProxyEngine On
ProxyPreserveHost On
ProxyRequests Off
ProxyPass / balancer://masfloss/
ProxyPassReverse / balancer://masfloss/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
```
En esta nueva configuración se añaden nuevas directivas y se modifican otras explicadas a continuación:
* `Header`: permite establecer cabeceras «HTTP» y, en este caso, es usada para crear una «cookie» llamada «ROUTEID» cuyo valor es establecido teniendo en cuenta el nombre de la ruta del servidor de fondo escogido para el balanceo, y que es modificada usando la variable de entorno que detecta el cambio de ruta del balanceador.
* `ProxyHCTemplate`: es específica del módulo `proxy_hcheck`, y simplemente, tras llamarla, asignamos un nombre y seguidamente establecemos la configuración de comprobación que queremos evitar repetir manualmente en cada servidor de fondo que sea miembro del balanceador. Las variables internas de la misma están definidas a continuación:
* `hcmethod`: permite definir el método para realizar la comprobación que puede ser uno de «HTTP» como `GET` o, directamente, `TCP`.
* `hcinterval`: permite definir el intervalo de tiempo entre comprobaciones en segundos.
* `hcpasses`: permite definir el número de comprobaciones correctas para que el servidor de fondo sea marcado como disponible para enviar peticiones.
* `hcfails`: permite definir el número de comprobaciones erróneas para que el servidor de fondo sea marcado como no disponible para enviar peticiones.
* `hcuri`: define la ruta a la que realizar las peticiones de la URL de cada servidor de fondo.
* `Proxy`: se declara como una etiqueta, y, en este caso, especifica una ruta con protocolo de balanceador. Esta ruta es auto-definida y puede tener el nombre que se considere. Dentro se usan otras dos directivas:
* `BalancerMember`: establece cada servidor de fondo que es miembro del balanceador y sus parámetros adicionales. En este caso definimos el nombre de la ruta para la «cookie» y la plantilla de comprobación a usar definida previamente.
* `ProxySet`: permite establecer configuraciones específicas de la directiva `Proxy`. Se hace uso de variables para ello:
* `lbmethod`: define el método de distribución de carga, siendo en este caso `bybussyness` que requiere el módulo `lbmethod_bybussyness`.
* `stickysession`: define el nombre de la «cookie» para el mantenimiento de la ruta por cada sesión de conexión, evitando saltos entre cada petición realizada en una misma sesión de un cliente.
* `ProxyPass` y `ProxyPassReverse`: se modifican apuntando a la raíz de la ruta del balanceador definido previamente y se suprime aquella referente a la ruta `/server-status` que sólo fue referenciada de ejemplo previamente.
## Gestor del balanceador de carga
Para finalizar, quedaría habilitar el gestor del balanceador, que permite visualizar el estado de los servidores de fondo de los miembros del mismo y, a su vez, realizar cambios no persistentes, revertidos al reiniciar el servidor web o recargar la configuración, en tiempo de ejecución de los parámetros de cada uno de los miembros del balanceador así como este mismo.
Adicionalmente, para evitar la exposición del balanceador de carga, se añade una autentificación básica.
```
<VirtualHost *:80>
ServerName masfloss.net
ServerAdmin masfloss@riseup.net
Protocols h2c http/1.1
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
ProxyHCTemplate get5 hcmethod=GET hcinterval=5 hcpasses=1 hcfails=2 hcuri=/
<Proxy balancer://masfloss>
BalancerMember https://cualquierotroservidor.net route=masfloss1 hctemplate=get5
BalancerMember https://cualquierotroservidor2.net route=masfloss2 hctemplate=get5
ProxySet lbmethod=bybusyness stickysession=ROUTEID
</Proxy>
<Location /balancer-manager>
SetHandler balancer-manager
AuthType Basic
AuthName "+FLOSS ID"
AuthBasicProvider file
AuthUserFile /var/www/.auth
<RequireAll>
Require all granted
Require valid-user
</RequireAll>
</Location>
SSLProxyEngine On
ProxyPreserveHost On
ProxyRequests Off
ProxyPass /balancer-manager !
ProxyPass / balancer://masfloss/
ProxyPassReverse / balancer://masfloss/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
````
En esta nueva versión de la configuración, se añaden unas pocas directivas adicionales, mayoritariamente por necesidad del sistema de autentificación básica, y se vuelve a añadir otra:
* `Location`: es una directiva en forma de etiqueta que establece una ruta declarada en el propio nombre partiendo de la raíz del sitio web hospedado, siendo en este caso la nueva ruta para el gestor del balanceador de carga. Internamente definimos otra serie de directivas para ello:
* `SetHandler`: permite establecer el aplicativo que se va a gestionar dicha ruta. En este caso debe ser el gestor del balanceador de carga definido como `balancer-manager`.
* `AuthType`: define el tipo de autentificación para acceder a la ruta, siendo en este caso `Basic` por el sistema de autentificación básica.
* `AuthName`: en el sistema de autentificación básica permite definir un nombre identificativo para el mensaje de solicitud de autentificación.
* `AuthBasicProvider`: es específica del sistema de autentificación básica, y permite definir la forma en la que se gestionan las credenciales de acceso, siendo en este caso `file` por ser un fichero.
* `AuthUserFile`: es específica al seleccionar un proveedor de autentificación básica basado en fichero, y define simplemente la ruta del fichero.
* `RequireAll`: es una directiva en forma de etiqueta que establece reglas de acceso a aplicar a todo cliente que acceda a dicha ruta. Internamente se definen las reglas siguientes:
* `Require all granted`: indica que todo cliente tiene acceso a la ruta.
* `Require valid-user`: indica que las credenciales de acceso deben ser válidas.
* `ProxyPass`: siendo específica la que define que la ruta `/balancer-manager` no será proxyficada a los servidores de fondo.
Finalmente, el fichero definido por la directiva `AuthUserFile` es creado con la orden `htpasswd -c /var/www/.auth <NOMBREDEACCESO>` definiendo con posterioridad al ejecutar dicha orden con un nombre de acceso correspondiente la contraseña del mismo.
Para credenciales de acceso adicionales, se ejecutaría la misma orden sin la opción `-c` que crearía el fichero de nuevo reemplazando el anterior si existiese en dicha ruta.
---
**Redacción:** [EchedeyLR](/redaction.html#EchedeyLR)