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

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

Pasos para activar WebDAV en Apache (mod_dav)

Apache

El objetivo de WebDAV es hacer de la World Wide Web un medio legible y editable, en línea con la visión original de Tim Berners-Lee. Este protocolo proporciona funcionalidades para crear, cambiar y mover documentos en un servidor remoto (típicamente un servidor web). Esto se utiliza sobre todo para permitir la edición de los documentos que sirve un servidor web, pero puede también aplicarse a sistemas de almacenamiento generales basados en web, que pueden ser accedidos desde cualquier lugar. La mayoría de los sistemas operativos modernos proporcionan soporte para WebDAV, haciendo que los ficheros de un servidor WebDAV aparezcan como almacenados en un directorio local.

Definición de WebDAV en Wikipedia

Preparación/instalación

Vamos a ver los pasos (sencillos) para activar WebDAV en Apache. Lo primero que hay que verificar es que el módulo mod_dav está cargado, ya sea de forma estática o dinámica. Normalmente cuando instalamos Apache por gestor de paquetes viene cargado de forma dinámica en el fichero httpd.conf:

Loadmodule dav_module modules/libdav.so

Si por contra compilamos Apache manualmente podemos decidir si compilarlo estáticamente o dinámicamente (como hemos visto antes). Para hacerlo estáticamente añadiremos la directiva correspondiente a la línea de compilación y podremos ver si está cargado con el comando:

# httpd -l

Otra opción es instalar el paquete por yum/apt/pkg si el paquete está disponible en un repositorio.

Configuración

Lo primero que tenemos que hacer es activar el soporte para WebDAV a nivel general de Apache, para ello añadiremos la siguiente línea en el fichero httpd.conf. Podemos restringirlo a nivel de <Directory> o <Location>:

Dav On

Además de esto, debemos especificar la base de datos de bloqueos (Lock Database) en la sección global de la configuración del httpd.conf:

DavLockDB /etc/apache/var/DavLock

Este directorio debe tener permisos de escritura para el usuario y grupo que ejecuta el servidor Apache.

El resultado final sería el siguiente, en este ejemplo activamos WebDAV en una ubicación (/webdav) únicamente para usuarios autenticados (admin) configurados con htpasswd

DavLockDB /usr/local/apache2/var/DavLock
<Location /webdav>
   Dav On

   AuthType Basic
   AuthName DAV
   AuthUserFile user.passwd

   <LimitExcept GET OPTIONS>
     require user admin
   </LimitExcept>
</Location>

Estas mismas directivas (a excepción del DavLockDB) podríamos añadirlas dentro de un virtualhost.

Conectar al WebDAV

Muchos sistemas soportan acceso a WebDAV de forma nativa. No obstante, en Linux podéis usar cadaver sobre línea de comandos:

$ cadaver http://dav.test.com/webdav/
...
...
dav:/webdav/>

mod_fcgid: HTTP request length 132147(so far) exceeds MaxRequestLen (131072)

Si utilizas Apache + FastCGI y no has modificado los parámetros por defecto de configuración de fasctcgi es probable que si intentas hacer upload de ciertos ficheros cuyo tamaño no sea muy pequeño recibas un error como este en el log:

[Tue Aug 30 12:05:13 2011] [warn] [client XX.XX.XXX.XX] mod_fcgid: HTTP request length 132147 (so far) exceeds MaxRequestLen (131072)

FastCGI está bloqueando la subida del fichero debido a su tamaño. Los límites iniciales de la directiva MaxRequestLen son muy bajos por defecto (131072), así que conviene ampliarlos para evitar este tipo de errores, por ejemplo a 15MB. Esta directiva la añadimos dentro del fichero php.conf (en la carpeta conf/ de apache) y sino dentro del IfModule correspondiente a fastcgi:

<IfModule mod_fcgid.c>
MaxRequestLen 15728640
...
...
</IfModule>

Reiniciamos apache y listo. Hay que tener en cuenta que esto mismo puede suceder también en servidores con Lighttpd y FastCGI.

Apache: servir PHP usando extensión HTML

ApacheExiste la posibilidad de que queramos introducir código PHP dentro de ficheros estáticos (.html, .htm…), de modo que al servir la página a través del navegador dicho código php se ejecute en lugar de mostrarse como texto plano. Este truco valdría tanto para cualquier otra extensión (cgi por ejemplo).

Para realizar esta configuración, debemos utilizar la directiva AddType en el fichero .htaccess del website o directamente a nivel general del servidor web en el fichero httpd.conf.

Lo primero que debemos verificar es que tenemos cargado en Apache el módulo mod_mime, que es el encargado de servir la directiva AddType.

# httpd -l | grep mime
  mod_mime.c

Una vez verificado, si quisieramos mapear las extensiones .html para servir contenido PHP, deberíamos añadir la siguiente directiva al fichero .htaccess:

AddType application/x-httpd-php .php .htm .html .shtml

Si tuvierais varias versiones de PHP instaladas en un mismo servidor, es posible que necesitéis especificar la versión del siguiente modo:

AddType application/x-httpd-php5 .php .htm .html .shtml

o

AddType application/x-httpd-php4 .php .htm .html .shtml

Esto lo podemos añadir también a nivel general en Apache, ya sea directamente en el httpd.conf o en el fichero php.conf junto con el resto de configuraciones de PHP. Si lo añadimos en httpd.conf reiniciamos el servicio tras hacerlo:

# /etc/init.d/httpd graceful

Ahora, si hacemos un fichero test.html con el siguiente contenido, al servirlo en el navegador web ejecutará el código PHP en lugar de mostrarlo como si fuera html puro y duro:

<h1>Prueba ejecutar PHP en fichero HTML</h1>
<? phpinfo ?>

Apache: diferencia entre reiniciar con ‘restart’ y ‘graceful’

ApacheVamos a ver las principales diferencias a la hora de reiniciar un servidor web Apache mediante

/etc/init.d/httpd restart

y

/etc/init.d/httpd graceful

.

Reinicio con restart

# apachectl -k restart
# /etc/init.d/httpd restart

Esta forma de reiniciar el servidor web es lo mismo que enviar una señal HUP a los procesos httpd (enviar señales a un proceso). Básicamente lo que hace es:

  1. Solicitar la finalización de los procesos con la señal TERM a los procesos child (hijos) y eliminar el proceso padre
  2. Se vuelven a leer los ficheros de configuración y se abren los ficheros de log. Las estadísticas de mod_status se reinician
  3. Se genera el proceso padre y a partir de él los nuevos procesos hijos

Como podéis ver, hay parada de servicio. Puede llegar a ser mínima pero hay un momento en el que no hay ningún proceso httpd para servir peticiones web.

Reinicio con graceful

# apachectl -k graceful
# /etc/init.d/httpd graceful

Esta forma de reiniciar Apache hace que se envíe una señal

USR1

, lo cual hace que en lugar de reiniciar todos los procesos hijos de vez, el proceso padre permite que cada uno de los child termine de servir la petición web antes de morir. El proceso sería el siguiente:

  1. Enviamos la señal USR1 o graceful
  2. El proceso padre indica a los hijos que mueran una vez finalizada la petición que estén sirviendo
  3. El proceso padre vuelve a leer los ficheros de configuración y abrir los logs
  4. Los procesos hijos van terminando de servir las peticiones y el padre los va sustituyendo por nuevos (que ya tienen cargada la nueva configuración)

Cara a mod_status, módulo que sirve para controlar el estado del servidor web, Apache no habrá sido reiniciado, mantendrá todas sus estadísticas y mostrará con una G los threads que están sirviendo previos al reinicio graceful.

 

Apache: cómo hacer debug de mod_rewrite

El módulo de Apache mod_rewrite tiene la opción de activar un modo debug o de registro de errores que puede ser de gran utilidad cuando tenemos algún problema con la creación de urls amigables o cualquier tipo uso que le demos a mod_rewrite.

La implantación es simple, únicamente tenemos que especificar en el fichero de configuración de Apache httpd.conf la ruta hacia el log y el nivel de debug que queremos aplicar, que va de 0 (sin debug) a 9 (máximo debug). Se recomienda configurarlo con el valor 3 ya que siendo superior puede provocar alto uso de recursos:

RewriteLog "/usr/local/apache/logs/rewrite.log"
RewriteLogLevel 3

Es recomendable también activarlo únicamente para el virtualhost que lo necesitemos (si tenemos varios sitios web en el mismo servidor) o incluso a nivel de directorio con la directiva Directory. Reiniciamos Apache y comenzará a volcarse la información sobre dicho log.

[error] (28)No space left on device: mod_python: Failed to create global mutex

Ayer en un servidor Apache con mod_python me encontré con este error:

[Thu Jun 02 21:43:19 2011] [error] (28)No space left on device: mod_python: Failed to create global mutex 1 of 4 (/tmp/mpmtx280211).
Configuration Failed

Lo primero que hice por lógica fue mirar lo siguiente:

  1. Mirar que el disco tuviera espacio libre (df -h).
  2. Mirar que el disco no estuviera al 100% en inodos (df -i).
  3. Mirar que ningún log de Apache hubiera llegado a los 2.0GB de tamaño.

Ninguna de las tres cosas era cierta y seguía teniendo el problema. Hace ya un par de años tuve un problema similar en Apache y estaba relacionado con los semáforos del Kernel: Apache: Semget: No space left on device. Esa vez la solución que ofrecía era vaciar el array de semáforos. En este caso vamos  solucionarlo de otro modo, ampliando los valores de Kernel para los semáforos. Actualmente tenía los siguientes:

# cat /proc/sys/kernel/sem
250	32000	32	128

Los ampliamos y reiniciamos Apache:

# echo "kernel.sem = 512 32000 100 512" >> /etc/sysctl.conf
# sysctl -p
# /etc/init.d/httpd restart

 

Cluster HTTP en alta disponibilidad con CentOS + Heartbeat

En esta entrada vamos a montar un cluster de alta disponibilidad con dos nodos CentOS, Heartbeat y servidor web Apache. A partir de esta configuración básica el cluster puede aumentar su número de nodos según requerimientos de forma gradual y sencilla.

La configuración del cluster es la siguiente:

nodo 1:

IP: 192.168.1.129
HOSTNAME: cluster01

nodo 2:

IP: 192.168.1.130
HOSTNAME: cluster02

IP virtual para el cluster:

IP: 192.168.1.131

Cluster Apache Heartbeat

Una vez configurado en los dos nodos el hostname e IPs (la IP virtual de momento no la tocamos), pasamos directamente a la instalación de Heartbeat y Apache, en ambos nodos deberíamos instalar:

 yum install httpd

Si preferís compilar apache en lugar de usar paquetes precompilados acudir a este post: compilar apache y php.

Nota: Tendréis que configurar Apache para que escuche por la IP virtual, no lo arranquéis todavía:

Listen 192.168.1.131:80

Evitamos que httpd arranque automáticamente, lo hará HeartBeat:

# chkconfig httpd off

Instalamos Heartbeat mediante yum:

# yum install heartbeat

Una vez instalado pasamos a la configuración de Heartbeat. Los ficheros básicos son authkeys, ha.cf y haresources. La ruta en la que debemos configurarlos es /etc/ha.d/. Si necesitamos ejemplos o los ficheros base los podemos encontrar en /usr/share/doc/heartbeat-2.1.2/.

ha.cf

ha.cf es el fichero en el que se especifica la configuración global del cluster. Nuestra configuración base es la siguiente. En el fichero de muestra tenéis información sobre todas las directivas disponibles:

logfile /var/log/cluster.log
logfacility local0
warntime 5
deadtime 30
initdead 120
keepalive 2
bcast eth0
udpport 694
auto_failback on
node cluster01
node cluster02

En primera instancia especificamos que el log donde se volcará toda la información será /var/log/cluster.log. Las directivas de detección de fallo de nodos son las siguientes:

  • warntime: Heartbeat avisará cuando un nodo falle tras 5 segundos.
  • deadtime: Hearbeat confirmará que un nodo ha caído, 30 segundos.
  • initdead: Tiempo máximo que Heartbeat esperará a que un nodo arranque, 60 segundos.
  • keepalive: Especifica cada cuanto tiempo Heartbeat enviará paquetes para comprobar la disponibilidad de los nodos, 2 segundos.

A través de “node” especificamos cada uno de los nodos que componen el cluster (sus hostname), uddport es el puerto UDP utilizado para la comunicación y bcast la interfaz broadcast.

authkeys

Este es el fichero en el que se configura el sistema de autenticación entre todos los nodos del cluster. El formato es el siguiente:

auth num
num algorithm secret

Los algoritmos disponibles son crc (1) sha1 (2) y md5 (3). Se recomienda utilizar sha1 así que lo utilizamos para nuestro cluster. “clu$ter-4uth” será la llave de autenticación (secret):

auth 2
2 sha1 clu$ter-4uth

Únicamente root debe poder leer el fichero, así que asignamos los permisos correspondientes:

# chmod 600 /etc/ha.d/authkeys

haresources

En este fichero se especifican los servicios que se moveran entre los distintos nodos del cluster cuando uno de ellos caiga. En este caso únicamente trabajaremos con httpd, en el propio fichero tenéis toda la información. Le especificamos también la IP virtual asignada al servicio:

cluster01 192.168.1.131 httpd

Propagar cambios de configuración entre nodos

Una vez finalizada la configuración inicial, podemos propagar los cambios entre todos los nodos mediante el comando ha_propagate. Hay que tener conectividad ssh/scp entre las máquinas, si no utilizáis llaves os pedirá la clave ssh de los nodos:

# /usr/lib/heartbeat/ha_propagate
Propagating HA configuration files to node cluster02.

ha.cf                                                                                                                    100%   11KB  10.7KB/s   00:00
authkeys                                                                                                                 100%  672     0.7KB/s   00:00
Setting HA startup configuration on node cluster02.
..
...

Arrancar y probar el cluster

Una vez finalizada la configuración ya podemos proceder a arrancar el cluster, para ello iniciamos HeartBeat en cada uno de los nodos:

# /etc/init.d/heartbeat start

El propio HeartBeat reiniciará Apache, no lo hagáis manualmente:

IPaddr[4618]:    2011/04/19_11:43:02 INFO:  Resource is stopped
ResourceManager[4591]:    2011/04/19_11:43:02 info: Running /etc/ha.d/resource.d/IPaddr 192.168.1.131 start
IPaddr[4694]:    2011/04/19_11:43:02 INFO: Using calculated nic for 192.168.1.131: eth0
IPaddr[4694]:    2011/04/19_11:43:02 INFO: Using calculated netmask for 192.168.1.131: 255.255.255.0
IPaddr[4694]:    2011/04/19_11:43:03 INFO: eval ifconfig eth0:0 192.168.1.131 netmask 255.255.255.0 broadcast 192.168.1.255
IPaddr[4677]:    2011/04/19_11:43:03 INFO:  Success
ResourceManager[4591]:    2011/04/19_11:43:03 info: Running /etc/init.d/httpd  start

En este caso no estamos montando a través de iSCSI, NFS o similar los datos que sirve Apache, de modo que para verificar contra qué nodo del cluster estamos conectando en cada momento podemos crear un index.html básico en cada uno de los nodos, ruta /var/www/html/index.html en el que indiquemos el nodo en el que nos encontramos.

En este momento, si accedermos a http://192.168.1.131 ya deberíamos poder acceder vía web al servicio, y nos indicará que es el cluster01 quien está sirviendo el contenido.

La primera prueba que vamos a hacer para probar el cluster es tirar el nodo cluster01, para ello tiramos la interfaz de red, en mi caso eth0:

# ifdown eth0

Una vez pasado el tiempo especificado en la configuración, en nodo cluster02 debería tomar el control de httpd y servir la web http://192.168.1.131, en el log veréis algo similar a:

heartbeat[2354]: 2011/04/19_11:31:24 WARN: node cluster01: is dead
heartbeat[2354]: 2011/04/19_11:31:24 WARN: No STONITH device configured.
heartbeat[2354]: 2011/04/19_11:31:24 WARN: Shared disks are not protected.
heartbeat[2354]: 2011/04/19_11:31:24 info: Resources being acquired from cluster01.
heartbeat[2354]: 2011/04/19_11:31:24 info: Link cluster01:eth0 dead.
harc[2417]:	2011/04/19_11:31:25 info: Running /etc/ha.d/rc.d/status status
heartbeat[2418]: 2011/04/19_11:31:25 info: No local resources [/usr/share/heartbeat/ResourceManager listkeys cluster02] to acquire.
mach_down[2447]:	2011/04/19_11:31:26 info: Taking over resource group 192.168.1.131
ResourceManager[2473]:	2011/04/19_11:31:27 info: Acquiring resource group: cluster01 192.168.1.131 httpd
IPaddr[2500]:	2011/04/19_11:31:28 INFO:  Resource is stopped
ResourceManager[2473]:	2011/04/19_11:31:28 info: Running /etc/ha.d/resource.d/IPaddr 192.168.1.131 start
IPaddr[2576]:	2011/04/19_11:31:30 INFO: Using calculated nic for 192.168.1.131: eth0
IPaddr[2576]:	2011/04/19_11:31:30 INFO: Using calculated netmask for 192.168.1.131: 255.255.255.0
IPaddr[2576]:	2011/04/19_11:31:31 INFO: eval ifconfig eth0:0 192.168.1.131 netmask 255.255.255.0 broadcast 192.168.1.255
IPaddr[2559]:	2011/04/19_11:31:32 INFO:  Success
ResourceManager[2473]:	2011/04/19_11:31:32 info: Running /etc/init.d/httpd  start
mach_down[2447]:	2011/04/19_11:31:33 info: /usr/share/heartbeat/mach_down: nice_failback: foreign resources acquired
mach_down[2447]:	2011/04/19_11:31:33 info: mach_down takeover complete for node cluster01.
heartbeat[2354]: 2011/04/19_11:31:33 info: mach_down takeover complete.

Y efectivamente, al entrar por navegador a http://192.168.1.131/ accedemos al cluster02.

Esta es la configuración más básica de un cluster HTTP con HeartBeat, a partir de aquí es cuestión de ir haciendo pruebas de failover y failback tirando nodos, levantandolos, y en definitiva, trastear con la configuración, etc ya que HeartBeat permite una gran cantidad de configuraciones.

Instalar mod_security para Apache en Linux 64 bits

A la hora de instalar mod_security en sistemas de 64 bits podemos encontrarnos con problemas al intentar hacerlo a través de apxs. Por ello, tenemos que recurrir a la instalación mediante compilación. En este caso bajo un centos 5 x86_64.
Lo primero que hacemos es descargar las fuentes:

$ wget http://www.modsecurity.org/download/modsecurity-apache_2.5.13.tar.gz

Descomprimimos y nos ubicamos en la carpeta apache2 (para versiones 2 de Apache):

$ tar -xzvf modsecurity-apache_2.5.13.tar.gz
$cd modsecurity-apache_2.5.13/apache2

Llega el momento de compilar, en este caso la configuración me ha obligado a especificar la ruta tanto de apxs como de apr-config y apu-config:

# ./configure --with-apxs=/usr/local/apache/bin/apxs \
 --with-apr=/usr/local/apache/bin/apr-1-config \
 --with-apu=/usr/local/apache/bin/apu-1-config

Si no recibimos ningún error compilamos:

# make

E instalamos:

# make install

Llega el momento de añadir a httpd.conf la carga de los módulos necesarios y la llamada al fichero de configuración:

LoadFile /usr/lib/libxml2.so
LoadModule security2_module modules/mod_security2.so

Y la llamada al fichero de configuración que podéis llamar como queráis:

Include conf/modsec2.conf

Ya quedará únicamente crear o copiar el fichero modsec2.conf y copiar las reglas que queramos a la ruta deseada.

 

modsec2.conf:

<IfModule mod_security2.c>
SecRuleEngine On
SecFilterCheckURLEncoding On
SecFilterForceByteRange 0 255
SecAuditEngine RelevantOnly
SecAuditLog logs/modsec_audit.log
SecDebugLog logs/modsec_debug_log
SecDebugLogLevel 0
SecDefaultAction "phase:2,deny,log,status:403"
#Redireccion a html de seguridad
ErrorDocument 403 http://rm-rf.es/fallo_seguyridad.html
SecRule REMOTE_ADDR "^127.0.0.1$" nolog,allow
#Includes de configuracion
Include "/usr/local/apache/conf/modsecurity_rules/*.conf"
</IfModule>

Finalmente comprobamos que la sintaxis de los ficheros de configuración es correcta y ya podemos arrancar Apache y hacer pruebas con mod_security:

# /etc/init.d/httpd configtest
Syntax OK