Apache2 con PHP seguro en UserDir


Si eres un administrador de redes y utilizas Apache para servir las web de tus usuarios puede que te interese este artículo.

Habrás notado que los desarrolladores de PHP intentaron solucionar algunos problemas de seguridad que utilizar los directorios de usuario acarrea. Bueno, para eso se empleó el: safe_mode pero obviamente ese no es trabajo que debería hacer PHP. Entonces en la versión 6.x de PHP quitaron por completo el modo seguro. Por lo que ya no disponemos más del safe_mode.

¿Y ahora? ¿Cómo hacemos para proteger el acceso de usuarios malintencionados o no pero que de todos modos tendrían forma de modificar o leer los archivos del DocumentRoot que nuestro usuario del servidor web Apache tiene?

Ok, la solución era con suexec y haciendo que PHP se ejecute como CGI desde los propios usuarios. Entonces esto haría que PHP corriera como un proceso aparte a nombre del usuario de la web que le corresponde. Para que sepan, mod_userdir.c es un módulo de apache que interpreta los directorios de los usuarios (/home/usuario/UserDir) y en base a eso maneja sus correspondientes páginas. Que en conjunto con suexec se tiene un entorno seguro para la ejecución de scripts en el directorio del usuario. Pero ese método no me solucionaba el problema ya que sólo sirve para scripts (cgi-bin). Así que si abría una página interpretada (con PHP por ejemplo, lo cual no se considera un script) desde el directorio del usuario ésta lo haría a nombre del usuario del servidor web (en mi caso: apache). Eso presentaba un problema de seguridad ya que un lenguaje como PHP permite la ejecución de órdenes en el propio servidor.

Entonces la solución de utilizar suexec para que PHP se ejecutara como CGI a nombre de los usuarios parecía la ideal, pero me encontré conque no se podía llevar a cabo en la práctica.

La combinación válida era utilizar suexec en conjunto con ScriptAlias y un Action para hacer que cada petición a un archivo .php se hiciera a través de un script determinado. Script el cual podría hacer ejecutar a nombre de otro usuario con la directiva SuexecUserGroup. Pero no era lo que yo estaba buscando ya que lo que yo quería era que el script se ejecutara a nombre del usuario del cual se estaba pidiendo la página. Es decir, que si pedíamos una página de /~miguel el script debía ejecutarse a nombre de miguel para que solamente tuviera acceso a lo que miguel tiene acceso.

Esa solución no me servía entonces busqué alternativas haciendo cambios de directorio o usando host virtuales, cambios en la declaración del Action donde había puesto en lugar de /cgi-bin/script algo como ~user/cgi-bin/script pero ninguna de las pruebas me sirvieron.

Había encontrado un módulo llamado suPHP que me permitiría hacer lo que yo quería. Pero después de varios intentos, fracasos y pruebas decidí no usarlo por dos motivos:
1) Demasiadas cosas para configurar que no me parecían prácticas.
2) No estaba hecho con la seguridad en mente. El autor parece que no tomó en cuenta todo lo posible para mantenerlo seguro. Y además, sugiere usar el modo “paranoico” lo cual limita las cosas a algo parecido a lo que se puede hacer con suexec y SuexecUserGroup.

Después de haber estado casi 4 días escribiendo código y pensando hora tras hora donde inclusive había llegado a escribir bastante código para tratar de traducir el nombre de usuario de los archivos y eso me llevó a necesitar una cosa y eso a otra y así se me terminó haciendo una cadena de cosas necesarias donde para cada una debía escribir código.

Después de todo eso, se me encendió la lamparita y logré solucionarlo en un par de líneas. Increíblemente solamente conseguí hacer un parche que añade unas pocas líneas al archivo mod_actions.c y permite “mágicamente” hacer lo que yo quería, al mismo tiempo que mantiene la compatibilidad 100% con la actual configuración del servidor web Apache.

El asunto es que no creo que haya sido en vano haber escrito todo ese código y haber estudiado hasta ese punto como trabaja y programar módulos para el servidor web Apache ya que si no hubiera sido por ello creo que la lamparita no se me hubiera encendido en este momento.

Además, de que descubrí que algunas cosas no funcionan tan bien como deberían pero también descubrí que si uno configura bien apache hay casi 0% de posibilidad de un problema de seguridad. Porque si bien hay código que cuando uno configura las cosas de una manera no trabaja exactamente como uno espera que trabaje y puede ser inseguro, si uno lo configura cuidadosamente va a trabajar en forma muy segura.

Quiero que sepan que adentro de apache las cosas están bien hechas. Y la programación de suexec está muy bien cuidada, tanto que por eso aconsejo la utilización de este parche que permite trabajar las cosas a través de suexec en vez de suPHP porque suexec está muy bien pensado y programado lo que lo hace totalmente seguro.
Entonces aquí dejo el parche que les va a permitir utilizar suexec para interpretar PHP (o algún lenguaje que trabaje en forma similar) a través de un script que se colocará en cada cgi-bin de cada directorio web de usuario.

Descarga el parche desde aquí: ftp://cieloaragua.sytes.net/src/proyectos/mod_actions.c.diff

¿Como aplicar el parche?

  1. Primero que nada necesitas tener el código fuente de apache versión 2.2.9. El mismo se puede descargar desde: http://httpd.apache.org
  2. Luego lo descomprimes en un directorio (normalmente /usr/src).
  3. Te metes en el directorio de apache y del módulo: cd http-2.2.9/modules/mappers
  4. Y aplicas el parche: patch < donde/descargaste/el/parche/mod_actions.c.diff
  5. Ahora ya puedes configurar (./configure), compilar (make) e instalar apache como siempre (make install).

¿Como hacerlo funcionar?

Bien, no voy a pasar a explicar como instalar y configurar cada cosa que se necesita. Doy por entendido que eso ya lo tienes hecho.

Por lo tanto, para poder utilizar esta nueva característica que añade el parche solo tienes que agregar al comienzo del nombre del script de un Action los caracteres: ~*

Esos caracteres le estarán indicando que: ~ (empieza un usuario) y * (debe traducirse).

Ejemplo:

Action application/x-httpd-php ~*/cgi-bin/php

En el action anterior cada vez que venga una petición del tipo mime application/x-httpd-php ésta será atendida por un script llamado php que se encuentra en el directorio cgi-bin del usuario dueño de la página web de la que se hizo la petición.

Si sabes lo que son las Actions (sino puedes visitar: http://httpd.apache.org/docs/2.2/mod/mod_actions.html) habrás notado que normalmente se pone el script de esta forma: /cgi-bin/php. O sea que ahora puedes hacerlo de las dos formas ya que la forma anterior sigue funcionando como antes.

Esto significa que si quieres puedes aplicar el parche que no afectará en lo absoluto al funcionamiento de tu servidor web ya que lo único que hace es añadir una nueva forma para la parte del script en el Action pero tranquilamente puede seguir funcionando con la forma anterior.

  1. #1 por Consultaapache el abril 14, 2010 - 7:07 am

    Buenas,
    se que hace un par de años que escribiste esta entrada. pero googleando me he encontrado con que tuviste el mismo problema que yo tengo ahora y la solución que encontraste igual me sirve. Al intentar bajar el fichero adjunto con tu solución (de rapidshare) me indica que no está disponible.
    Podrías aunque sea decirme qué hiciste?
    Muchas gracias!

    • #2 por anyeos el mayo 18, 2010 - 10:53 am

      Disculpame no revisaba los comentarios de mi weblog desde hace un par de meses.
      Si yo sabía que no iba a poder bajarse más porque se vence el plazo del rapidshare. Pero ahora lo monté en mi ftp. Lo puedes descargar si quieres.
      Si no te funciona por favor avisame.

      Saludos

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: