Tuesday, September 10, 2013

Apache Traffic Server en Debian Wheezy

Este post es solo un ejemplo simple de configuración de Apache Traffic Server como proxy inverso (reverse proxy).

Wikipedia tiene esta definición para proxy inverso:

Un proxy inverso (reverse proxy en inglés) es un servidor proxy situado en el alojamiento de uno o más servidores web. Todo el tráfico procedente de Internet y con destino en alguno de esos servidores web es recibido por el servidor proxy. Hay varias razones para ello:

  • Seguridad: el servidor proxy es una capa adicional de defensa y por lo tanto protege a los servidores web.
  • Cifrado / Aceleración SSL: cuando se crea un sitio web seguro, habitualmente el cifrado SSL no lo hace el mismo servidor web, sino que es realizado en un equipo ajeno equipado incluso con hardware de aceleración SSL/TLS.
  • Distribución de Carga: el proxy puede distribuir la carga entre varios servidores web. En ese caso puede ser necesario reescribir la URL de cada página web (traducción de la URL externa a la URL interna correspondiente, según en qué servidor se encuentre la información solicitada).
  • Caché de contenido estático: Un proxy inverso puede descargar de trabajo a los servidores web almacenando contenido estático como imágenes u otro contenido gráfico. También puede almacenar contenido generado dinámicamente pero que pueda ser en alguna medida reutilizable.
No tengo nada que agregar a la definición :)

En este post voy a poner un ejemplo de configuración de Apache Traffic Server (ATS) como proxy inverso para caché de contenido estático.

Entorno de prueba

El entorno de prueba que utilicé es una máquina virtual con Debian Wheezy donde correrán los dos bloques funcionales que utilizaré, el ATS y apache como servidor web. Lo siguiente es un resúmen del entorno de pruebas para que quede claro:
  • ATS escuchando en el puerto 8080
  • Apache escuchando en el puerto 80
ATS necesita al menos un servidor DNS así que tuve que montar uno sencillo en la máquina de prueba. No voy a describir el proceso porque no es el objetivo de este post, lo que describiré es la configuración básica.
  • Zona "int" con un registro A (ats.int) apuntado a 127.0.0.1
  • La zona inversa ya viene configurada con el paquete bind9
Con el servidor DNS funcionando (hay que asegurarse de que funciona) proseguimos con la instalación.

Instlación

Instalamos ATS con el siguiente comando:
# aptitude install trafficserver

ATS es un producto un poco "raro", no se maneja ni se configura como cualquier otro producto de software libre. Tiene varios archivos de configuración con un formato muy poco usual. Para esta demostración de concepto necesitamos "tocar" los siguientes archivos (o saber que existen):
  • records.config: Es el archivo principal de configuración y contiene las directivas principales que gobiernan el comportamiento de ATS.
  • remap.config: En este archivo están las redirecciones a los servidores "reales".
  • splitdns.config: Aquí es donde le indicamos los servidores DNS que vamos a utilizar además de configurar el comportamiento en lo que a resolución de nombres se refiere para cada dominio.

Para esta prueba vamos a dejar muchas configuraciones por defecto y solo modificaremos las que nos interesan, insisto, _para esta prueba_. En cristiano, que hay que leerse el manual, esto no es " la guía definitiva de ATS".

Con el ATS instalado, el siguiente paso es arrancarlo. Editamos el archivo /etc/default/trafficserver y colocamos la variable TC_START en "yes"
TC_START=yes

Ahora arrancamos ATS
# /etc/init.d/trafficserver start

En /var/log/syslog debería aparecer algo como esto:
traffic_cop[10778]: --- Cop Starting [Version: Apache Traffic Server - traffic_cop - 3.0.5 - (build # 5918 on Jun  9 2012 at 18:37:39)] ---
traffic_cop[10778]: can't get passwd entry for the admin user
traffic_cop[10778]: can't get passwd entry for the admin user
traffic_cop[10778]: traffic_manager not running, making sure traffic_server is dead
traffic_cop[10778]: spawning traffic_manager
traffic_manager[10779]: NOTE: --- Manager Starting ---
traffic_manager[10779]: NOTE: Manager Version: Apache Traffic Server - traffic_manager - 3.0.5 - (build # 5918 on Jun  9 2012 at 18:33:34)
traffic_server[10789]: NOTE: --- Server Starting ---
traffic_server[10789]: NOTE: Server Version: Apache Traffic Server - traffic_server - 3.0.5 - (build # 5918 on Jun  9 2012 at 18:36:30)
traffic_server[10789]: {1081143632} STATUS: opened /var/log/trafficserver/diags.log

Ok, ahora toca configurarlo, para eso utilizaremos el comando traffic_line (ya dije que ATS era muy raro).

Configuración

Cambiamos el propietario del estos archivos de manera temporal.
# cd /etc/trafficserver
# chown trafficserver records.config remap.config splitdns.config

Le diremos a ATS es que no guarde copias de los archivos de configuración (esto es una prueba)
#traffic_line -s proxy.config.admin.number_config_bak -v 0

Cache status en los encabezados HTTP (para debugging)
# traffic_line -s proxy.config.http.insert_response_via_str -v 1

Cuando hacer caché de cada objeto (mirar documentación)
# traffic_line -s proxy.config.http.cache.when_to_revalidate -v 4

No necesita encabezados especiales para hacer caché de un objeto.
# traffic_line -s proxy.config.http.cache.required_headers -v 0

Server mappings 

Ahora es cuando le indicamos a ATS lo que va a hacer con las peticiones, es decir, las reglas que debe seguir para manejar las peticiones que vienen desde "afuera". Para esto editamos el archivo /etc/trafficserver/remap.config y colocamos lo siguiente al final del archivo:

map http://ats.int:8080 http://ats.int

Resolución DNS

ATS usa los servidores DNS del /etc/resolv.conf, en este caso, para que use nuestro servidor DNS que es donde tenemos la zona de pruebas "int", debemos editar el archivo /etc/trafficserver/splitdns.config y colocar lo siguiente:
dest_domain=int named=127.0.0.1

y le decimos que lo use
# traffic_line -sproxy.config.dns.splitDNS.enabled -v 1

Hemos finalizado, falta recargar la configuración
# traffic_line -x

Devolvemos el cambio de propietario de los archivos de configuración
# chown root.root records.config remap.config splitdns.config


Pruebas

Ahora toca probar lo que hicimos, para esto, creamos un archivo html de prueba en /var/www con el siguiente contenido:
<html>
<head>Prueba</head>
<body>
hola, esto es una prueba
</body>
</html>

Editamos el /etc/hosts y añadimos el alias ats.int a 127.0.0.1. Esto es para poder utilizar el nombre ats.int con la herramienta GET.

Probamos con el siguiente comando:
$ GET -Ue http://ats.int:8080/prueba.html

Deberíamos obtener algo parecido a esto:
GET http://ats.int:8080/prueba.html
User-Agent: lwp-request/6.03 libwww-perl/6.04
200 OK
Connection: close
Date: Tue, 10 Sep 2013 13:22:28 GMT
Via: http/1.1 murphy (ApacheTrafficServer/3.0.5 [cMsSfW])
Accept-Ranges: bytes
Age: 0
ETag: "4e-4b-4e6073106eb8b"
Server: ATS/3.0.5
Vary: Accept-Encoding
Content-Length: 75
Content-Type: text/html
Last-Modified: Tue, 10 Sep 2013 13:07:48 GMT
Client-Date: Tue, 10 Sep 2013 13:22:28 GMT
Client-Peer: 127.0.0.1:8080
Client-Response-Num: 1

<html>
<head>Prueba</head>
<body>
hola, esto es una prueba
</body>
</html>


Es importante verificar la cadena "[cMsSfW]" del encabezado Via que nos está diciendo:
cM: cache miss (el objeto no está en el caché)
sS: served (el objeto lo proporcionó el "servidor original")
fW: writen (el objeto fue escrito en el caché)

En cristiano, que el archivo prueba.html no estaba en el caché, que lo fue a buscar en el servidor, lo encontró, lo mandó al cliente http y lo guardó en caché. Es lo que se esperaba, no?

Ahora volvemos a ejecutar el mismo comando:
$ GET -Ue http://ats.int:8080/prueba.html
GET http://ats.int:8080/prueba.html
User-Agent: lwp-request/6.03 libwww-perl/6.04
200 OK
Connection: close
Date: Tue, 10 Sep 2013 13:22:28 GMT
Via: http/1.1 murphy (ApacheTrafficServer/3.0.5 [cHs f ])
Accept-Ranges: bytes
Age: 317
ETag: "4e-4b-4e6073106eb8b"
Server: ATS/3.0.5
Vary: Accept-Encoding
Content-Length: 75
Content-Type: text/html
Last-Modified: Tue, 10 Sep 2013 13:07:48 GMT
Client-Date: Tue, 10 Sep 2013 13:27:45 GMT
Client-Peer: 127.0.0.1:8080
Client-Response-Num: 1


<html>
<head>Prueba</head>
<body>
hola, esto es una prueba
</body>
</html>

Observemos de nuevo el encabezado Via, tiene la siguiente cadena "[cHs f ]"  y vemos que tiene un cH, es decir un cache Hit, que quiere decir que el objeto pedido está en el caché y de ahí lo envió al cliente http sin irlo a buscar al servidor original. Es lo que se esperaba de un proxy caché, no?

Se puede seguir haciendo pruebas, por ejemplo, limpiar el caché (ver documentación), hacer un tail -f al access.log de apache y verificar que el apache registra la primera petición del objeto (normal, no está en el caché) y que en posteriores peticiones, no se registra nada en el access.log de apache.

Eso es todo, ya tenemos a ATS funcionando.

No comments:

Post a Comment