# rm-rf.es | Administración de sistemas

Bitácora personal de un SysAdmin Gnu/Linux, Windows, BSD...

Configurar Apache como Reverse Proxy (Proxy Inverso)


reverse proxy

Reverse Proxy / Proxy inverso

Un reverse proxy es un servidor proxy instalado en el domicilio de uno o más servidores web. Todo el tráfico entrante de Internet y con el destino de uno de esos servidores web pasa a través del servidor proxy. Hay varias razones para instalar un “reverse proxy”:

  • Seguridad: el servidor proxy es una capa adicional de defensa y por lo tanto protege 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 por el “reverse proxy”, el cual está equipado con un hardware de aceleración SSL (Security Sockets Layer).
  • Distribución de Carga: el “reverse proxy” puede distribuir la carga entre varios servidores web. En ese caso, el “reverse proxy” puede necesitar reescribir las 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 “reverse proxy” puede descargar los servidores web almacenando contenido estático como imágenes u otro contenido gráfico.

Definición Wikipedia

Configurando Apache como Reverse Proxy

Para poder utilizar el propio servidor web Apache como Proxy inverso, debemos tener compilados una serie de módulos. Los módulos básicos necesarios son los siguientes: mod_proxy, mod_proxy_http, mod_proxy_ftp, mod_proxy_connect, mod_proxy_html, mod_xml2enc y mod_headers.

Lo primero que deberíamos hacer es revisar cuales de estos módulos ya están compilados en nuestro servidor web apache, para ello al pasamos al binario httpd el parámetro

-l

:

# httpd -l

  mod_headers.c
  mod_proxy.c
  proxy_connect.c
  proxy_ftp.c
  proxy_http.c

En este caso vemos que varios de ellos ya están compilados, hay que decir que mod_proxy integra el resto que véis ( proxy_connect, proxy_ftp y proxy_http). En caso de no tener mod_proxy compilado, deberíais hacerlo a través de la línea de compilación, y en caso de haber instalado apache por gestor de paquetes (yum, apt, etc) deberíais instalar el módulo correspondiente.

Partiendo entonces de la base que tenemos mod_proxy compilado, ahora deberíamos preparar los módulos mod_proxy_html y mod_xml2enc, que permiten reescribes las URLs en formato HTML (tipo mod_rewrite) hacia la ruta del proxy y dar soporte internacional (i18n) respectivamente.

Ámbos módulos se pueden descargar desde http://apache.webthing.com/mod_proxy_html/, una vez descargados podemos añadirlos a apache de forma sencilla mediante apxs de forma dinámica (DSO). Nos ubicamos en la carpeta en la que se encuentren los ficheros mod_proxy_html.c y mod_xml2enc.c y ejecutamos el siguiente comando (puede variar según ruta de apxs):

# /usr/local/apache/bin/apxs -I . -cia mod_proxy_html.c  mod_xml2enc.c

Es posible que encontréis un problema relacionado con libxml, es debido a que para compilar el módulo se necesitan dichas librerías. Podéis hacer un include a dichas librerías con el parámetro -L o directamente hacer un enlace simbólico de forma temporal:

# /usr/local/apache/bin/apxs -L /usr/include/libxml2/libxml/ -I . -cia mod_proxy_html.c  mod_xml2enc.c

O el enlace simbólico:

# ln -s /usr/include/libxml2/libxml/ .

Tras realizar este paso de forma satisfactoria, en nuestro fichero de configuración de Apache httpd.conf deberían aparecer como cargados ámbos módulos:

LoadModule proxy_html_module  modules/mod_proxy_html.so
LoadModule xml2enc_module     modules/mod_xml2enc.so

Ahora añadimos también la carga del módulo xml:

LoadFile  /usr/lib/libxml2.so
LoadModule proxy_html_module  modules/mod_proxy_html.so
LoadModule xml2enc_module     modules/mod_xml2enc.so

Este paso finalizaría la parte de compilación/instalación. Para la configuración es recomendable revisar todas las directivas posibles en la documentación oficial de apache. Nosotros vamos a configurar un ejemplo sencillo. Vamos a hacer que al acceder a http://rm-rf.es/google se acceda a google.es mediante proxy inverso.

Vamos a desactivar lo primero el Forward Proxy porque no lo utilizamos, podemos añadir la siguiente directiva seguido de los LoadModule anteriores:

ProxyRequests Off

El virtualhost con el proxy inverso configurado quedaría de esta forma:

<VirtualHost *:80>
ServerName rm-rf.es
DocumentRoot /xxx/xxx/xxx
ServerAdmin xxx@xxxx
UseCanonicalName Off
CustomLog /xxxxx
ScriptAlias /xxxxx

<Location /google>
        SetOutputFilter proxy-html
        ProxyPass         http://google.es/
        ProxyHTMLURLMap         http://google.es /google
        ProxyPassReverse         http://google.es
        RequestHeader unset Accept-Encoding
</Location>

</VirtualHost>

Como veis, hemos añadido una nueva ubicación “Location” dentro del Virtualhost para especificar que ese es el punto desde el que se servirán las peticiones desde el proxy. Posteriormente mapeamos mediante ProxyPass la URL local contra la URL remota. La directiva ProxyPassReverse permite a apache ajustar la URL en las cabeceras HTTP Location, Content-Location y URI, mientras que ProxyHTMLURLMap es la directiva utilizada para hacer el rewrite de los enlaces HTML.

Finalmente hacemos un graceful o un syntax check (-t) a apache para recargar las configuraciones y verificar si el funcionamiento es correcto. Esta es una configuración básica de como utilizar mod_proxy para servir contenido, vuelvo a recomendar la revisión de la documentación para sacar el máximo partido a este servicio. Quizás en otro artículo explique como configurar este proxy reverso para servir contenido mediante SSL y otras curiosidades más.

Información sobre apache desde línea de comandos


Siguiendo el hilo de la Información sobre PHP desde línea de comandos hoy vamos a ver las posibilidades que nos ofrece el servidor web Apache en la línea de comandos:

En primera instancia revisamos si el binario httpd se encuentra en nuestro path o si debemos llamar a su ruta completa:

# whereis httpd
httpd: /usr/sbin/httpd /etc/httpd

En este caso podemos llamarlo directamente con “httpd”, vamos a ver algunas opciones que nos permiten sacar información sobre el servidor web:

Mostrar la versión de Apache:

# httpd -v
# httpd -v
Server version: Apache/X.X.XX
Server built:   Sep 21 2009 09:57:47

Mostrar información y ajustes de la compilación:

Como véis también muestra la información que sacábamos con httpd -v:

# httpd -V
Server version: Apache/X.X.XX
Server built:   Sep 21 2009 09:57:47
Server's Module Magic Number: ...
Server loaded: ...
Compiled using:  ...
Architecture:   32-bit
Server compiled with....
 -D APACHE_MPM_DIR="server/mpm/prefork"
 -D APR_HAS_SENDFILE
...
...

Mostrar módulos compilados:

# httpd -l
Compiled in modules:
  core.c
  mod_access.c
  mod_auth.c
  mod_include.c
  mod_log_config.c
  mod_logio.c
  mod_env.c
  mod_expires.c
...
...

Ejecutar una revisión de sintaxis para los ficheros de configuración:

# httpd -t
Syntax OK

Listar las directivas de configuración disponibles:

# httpd -L
Directory (core.c)
	Container for directives affecting resources located in the specified directories
	Allowed in *.conf only outside...
	Container for directives affecting resources accessed through the specified URL paths
	Allowed in *.conf only outside ...
VirtualHost (core.c)
	Container to map directives to a particular virtual host, takes one or more host addresses
	Allowed in *.conf only outside ..
Files (core.c)
...
...

Especificar un fichero de configuración alternativo:

# httpd -f fichero

Especificar un ServerRoot alternativo:

# httpd -d directorio

Listar las opciones en línea de comandos:

# httpd -h
Usage: /usr/local/apache/bin/httpd [-D name] [-d directory] [-f file]
                                   [-C "directive"] [-c "directive"]
                                   [-k start|restart|graceful|stop]
                                   [-v] [-V] [-h] [-l] [-L] [-G] [-t] [-S]
Options:
  -D name           : define a name for use in  directives
  -d directory      : specify an alternate initial ServerRoot
  -f file           : specify an alternate ServerConfigFile
  -C "directive"    : process directive before reading config files
  -c "directive"    : process directive after reading config files
  -e level          : show startup errors of level (see LogLevel)
  -E file           : log startup errors to file
  -v                : show version number
  -V                : show compile settings
  -h                : list available command line options (this page)
  -l                : list compiled in modules
  -L                : list available configuration directives
  -G                : list available configuration directives after loading conf file
  -t -D DUMP_VHOSTS : show parsed settings (currently only vhost settings)
  -S                : a synonym for -t -D DUMP_VHOSTS
  -t                : run syntax check for config files

Apache: Activar httpd fullstatus


Apache ofrece la posibilidad de mostrar un informe en el que indica si el servidor web está funcionando correctamente, la versión del mismo, estadísticas tiempo online, reinicios, cantidad de peticiones procesandose en el servidor, tipo de petición, su estado, usos de CPU etc.

En primera instancia existe la versión básica de “status“, que nos dice los PID de los procesos de apache y que está funcionando:

$ /etc/init.d/httpd status
httpd (pid 23922 23027 23015 22996 22984 22983 22982 22981 22980 22979 22978 22977 22975) is running...

Y la versión extendida que es de la que hablaba anteriormente, “fullstatus“:

$ /etc/init.d/httpd fullstatus
   Apache Server Status for localhost
   Server Version: Apache/2.2.0 (Debian)
   Server Built: Jul 14 2009 06:04:04
   --------------------------------------------------------------------------
   Current Time: Tuesday, 08-Sep-2009 22:51:45 CEST
   Restart Time: Tuesday, 08-Sep-2009 22:43:16 CEST
   Parent Server Generation: 0
   Server uptime: 8 minutes 29 seconds
   Total accesses: 2612 - Total Traffic: 23.4 MB
   CPU Usage: u120.23 s3.35 cu0 cs0 - 24.3% CPU load
   5.13 requests/sec - 47.1 kB/second - 9.2 kB/request
   1 requests currently being processed, 11 idle workers

 ___________W....................................................
 ................................................................
 ......................

   Scoreboard Key:
   "_" Waiting for Connection, "S" Starting up, "R" Reading Request,
   "W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup,
   "C" Closing connection, "L" Logging, "G" Gracefully finishing,
   "I" Idle cleanup of worker, "." Open slot with no current process

Srv   PID     Acc    M  CPU  SS Req  Conn Child Slot     Client                  VHost                                 Request
0-0  22977 0/234/234 _ 9.12  2  1143 0.0  1.65  1.65 xx.xx.xx.xx   xxxx.com                    GET Home/ HTTP/1.1
                                                                                                 GET
1-0  22978 0/242/242 _ 8.76  0  12   0.0  1.47  1.47 xx.xx.xx.xx    xxxxx.com                    /static/API/2/u5s8411hd3mjt2nemzdy.html
                                                                                                    HTTP/1.1
                                                                                                    GET
2-0  22979 0/246/246 _ 8.16  2  13   0.0  1.38  1.38 xx.xx.xx.xx   xxxxx.com                    /static/API/2/u5s8411hd3mjt2nemzdy.html
                                                                                                    HTTP/1.1
3-0  22980 0/224/224 _ 33.35 1  11   0.0  8.38  8.38 xx.xx.xx.xx   xxxxx.com                    GET /img/home_en-us.jpg HTTP/1.1
                                                                                                    GET
4-0  22981 0/245/245 _ 9.13  0  12   0.0  1.37  1.37 xx.xx.xx.xx   xxxxxx.com                    /static/API/2/b2250unz63ytqj3oz0fn.html
                                                                                                    HTTP/1.1
5-0  22982 0/244/244 _ 10.40 1  10   0.0  1.50  1.50 xx.xx.xx.xx   xxxxx.com                    GET /img/TEN_home_en-us.jpg HTTP/1.1
                                                                                                    GET
6-0  22983 0/247/247 _ 8.73  1  12   0.0  1.54  1.54 xx.xx.xx.xx  xxxxx.com                    /static/API/2/u5s8411hd3mjt2nemzdy.html
                                                                                                    HTTP/1.1
                                                                                                    GET
7-0  22984 0/230/230 _ 9.85  0  12   0.0  1.72  1.72 xx.xx.xx.xx    xxxxx.com                    /static/API/2/tq5x51nvb25gbp3tm22c.html

11-0 23922 0/54/54   W 2.03  0  0    0.0  0.30  0.30 127.0.0.1       xxxx.com GET /server-status HTTP/1.1

   --------------------------------------------------------------------------

    Srv  Child Server number - generation
    PID  OS process ID
    Acc  Number of accesses this connection / this child / this slot
     M   Mode of operation
    CPU  CPU usage, number of seconds
    SS   Seconds since beginning of most recent request
    Req  Milliseconds required to process most recent request
   Conn  Kilobytes transferred this connection
   Child Megabytes transferred this child
   Slot  Total megabytes transferred this slot

El “status” simple no es necesario activarlo, en cambio el “fullstatus” hay que permitirlo, tenéis que editar el fichero de configuración de apache httpd.conf y descomentar la siguiente línea:

ExtendedStatus On

Posteriormente, hay que indicar a quien vamos a dejar acceder a esta información, en este caso recomiendo siempre solo a localhost:
NOTA: Cambiar # por < y >, wordpress automáticamente elimina esa parte del código y no conseguía que se visualizara en la entrada…

#Location /server-status#
    SetHandler server-status
    Order deny,allow
    Deny from all
    Allow from localhost 127.0.0.1
#/Location#

Reiniciamos apache y listo. Otras formas de visualizar el estado:

service httpd fullstatus
apachectl fullstatus

apxs no se encuentra disponible para Apache


apxs es una utilidad de apache para instalar módulos y extensiones. Esto se consigue instalando un objeto DSO (dynamic shared object) desde el propio fichero fuente, es decir, desde las propias sources, de modo que puede añadirse un nuevo módulo sin tener que recomilar apache, mediante la adición del mismo con la directiva “LoadModule“.
Para poder utilizar esta utilidad, tenemos que tener soporte DSO en apache, o lo que es lo mismo, tener cargado el módulo “mod_so”, para averiguarlo ejecuta:

$ httpd -l
Compiled in modules:
  core.c
  prefork.c
  http_core.c
  mod_so.c

Si el módulo aparece puedes utilizar sin problemas apxs. Debes tener en cuenta, que has de tener instaladas también los “Apache development files”, que para Fedora/CentOS/RedHat es el siguiente paquete instalable vía yum:

yum install httpd-devel

Podéis ver ejemplos de instalación de módulos con esta herramienta en los dos siguientes enlaces:

Instalación mod_security
Instalación mod_evasive

Apache: rotar logs según fecha o tamaño


Hace unas semanas expliqué como usar logrotate para tener un buen sistema de rotado de logs. No obstante, no comenté la posibilidad de rotar los logs según su tamaño o fecha.

Pongamos el caso de que queremos rotar un determinado log de apache, en el momento que llegue a los 150Mb, para ello, iriamos a nuestro fichero de configuración para el logrotate de apache (/etc/logrotate.d/apache por ejemplo):

/usr/local/apache/logs/access_log {
    compress
    maxage 360
    size=+150M
    create 644 root root
    postrotate
     /etc/init.d/apache2 reload
    endscript
}

Como habréis comprobado, para asignarle un tamaño máximo de 150 Mb, añadimos size=tamaño_máximo, podemos indicar el tamaño en k o M sin problemas. Por otra parte, podemos especificar que se eliminen los ficheros de logs almacenados si superan un determinado tiempo de vida, en este caso 360 días, con el parámetro maxage.

Iremos desvelando más parámetros de logrotate