En uno de los últimos portales web que he tenido que desarrollar una de las principales premisas era que tenía que ser muy seguro. El nuevo portal tenía que suplir a una versión hecha en html puro, sin código en el servidor. ¿Para qué cambiar si la versión anterior ya era segura? Tampoco entraré en más detalles pero, ¿os acordáis de esas “bonitas” webs con montones de gifs animados y colores espartanos? Esas páginas eran bonitas al lado de esta. Al grano. Para el desarrollo del nuevo portal se estuvieron haciendo pruebas con varios CMS (Gestores de contenidos) en PHP. ¿Por qué en PHP? Pues porque los recursos del servidor eran limitados, y porque me gusta. Al final nos decantamos por Drupal, ya que ofrecía a priori una robustez y seguridad que otros no. ¡Ah!, y porque me gusta.
Una vez tenía el portal ya bastante terminado, me puse a indagar como podía añadirle más seguridad. Al final, en todos los gestores terminas instalando una infinidad de “plugins” (módulos) hechos por terceros que, aunque sea una comunidad muy rápida en resolver los problemas de seguridad, siempre existe cierto riesgo. Fue entonces cuando di con un módulo de Drupal llamado PHPIDS. El módulo actúa de “envoltorio” del programa PHPIDS.
Encontré también un enlace a howforge dónde se documenta la instalación de éste. Voy a resumir dicha instalación, ya que las bondades de este programa están bien resumidas en este post de Security By Default, y luego voy os explicaré como lo hice en Drupal.
Instalación Básica de PHPIDS
Esta instalación sirve para cualquier aplicación PHP, incluyendo todos sus CMS (Drupal, Joomla, WordPress, Moodle etc…). El ejemplo está realizado en una máquina Debian Squeeze.
1) Descargamos el programa de la web. En estos momentos en su versión 0.7. y descomprimimos el paquete.
$ wget http://phpids.org/files/phpids-0.7.tar.gz $ tar zxvf phpids-0.7.tar.gz
2) Creamos un directorio en la ruta dónde vayamos a ubicar la web y copiamos la el subdirectorio ‘lib’.
$ mkdir /var/www/phpids $ mv lib/ /var/www/phpids/
3) En el directorio de la aplicación IDS, creamos ‘tmp’ y le damos permisos de escritura (en este caso hacemos propietario del directorio) al usuario del servidor web (en apache a www-data).
$ mkdir /var/www/phpids/lib/IDS/tmp $ chown -R www-data:www-data /var/www/phpids/lib/IDS/tmp
4) Copiamos el archivo IDS/Config/Config.ini.php en Config.ini y modificamos las rutas por defecto.
; PHPIDS Config.ini ... [General] filter_type = xml filter_path = /var/www/phpids/lib/IDS/default_filter.xml tmp_path = /var/www/phpids/lib/IDS/tmp scan_keys = false ... [Logging] ; file logging path = /var/www/phpids/lib/IDS/tmp/phpids_log.txt ... [Caching] ; caching: session|file|database|memcached|none caching = file expiration_time = 600 ; file cache path = /var/www/phpids/lib/IDS/tmp/default_filter.cache ... ; memcached ;host = localhost ;port = 11211 ;key_prefix = PHPIDS ;tmp_path = /var/www/phpids/lib/IDS/tmp/memcache.timestamp
Como prueba de concepto, creamos un pequeño script php que nos muestra un mensaje de OK, si la petición es correcta, o nos muestra una traza del error en caso de un intento de ataque.
<?php set_include_path( get_include_path().PATH_SEPARATOR.'/var/www/phpids/lib'); require_once 'IDS/Init.php'; $request = array( 'REQUEST' => $_REQUEST, 'GET' => $_GET, 'POST' => $_POST, 'COOKIE' => $_COOKIE ); $init = IDS_Init::init('/var/www/phpids/lib/IDS/Config/Config.ini'); $ids = new IDS_Monitor($request, $init); $result = $ids->run(); if (!$result->isEmpty()) { echo $result; require_once 'IDS/Log/File.php'; require_once 'IDS/Log/Composite.php'; $cLog = new IDS_Log_Composite(); $cLog->addLogger(IDS_Log_File::getInstance($init)); $cLog->execute($result); }else print(“<h1>Todo OK!</h1>”); ?>
En la web de howforge encontraréis este ejemplo y otros un poco más desarrollados, así como la explicación para poder usar PHPIDA en todas las páginas PHP sin tener que modificar una a una usando la propiedad de PHP auto_prepend_file.
Si no tienes ni idea de este gestor y no quieres tenerla, puedes dejar de leer, ya que a partir de aquí puede que no te interese mucho.
PHPIDS en Drupal
Otra manera de usar PHPIDS es mediante el módulo de Drupal (ver la página de PHPIDS en la web de Drupal). Este módulo permite configurar el programa desde la consola de Drupal y registra los eventos en la base de datos de este, para poder acceder a ellos de una forma más visual. La instalación es bastante sencilla.
1) Descargar el último paquete de PHPIDS si no lo teniamos.
2) Se descomprime el tar en el directorio para las bibliotecas externas de Drupal (/sites/all/libraries/phpids-0.7).
3) Se crea un directorio de archivos temporales de escritura para PHPIDS para almacenar en caché los filtros y se le añade permisos como en el apartado anterior (phpids-0.7/lib/IDS/tmp)
4) Se copia, instala el módulo de Drupal PHPIDS.
En la configuración (http://miweb/es/admin/settings/logging) se establece:
General PHP-IDS Path: /opt/drupal/sites/all/libraries/phpids-0.7/lib PHP-IDS Temp Path: /opt/drupal/sites/all/libraries/phpids-0.7/lib/IDS/tmp Mail impact: 9 Filter settings. Anonymous users: "Log Anonymous users without actions" Authenticated users: "Log Authenticated users users without actions"
El resto se quedan en blanco por el momento.
Con esto ya se tiene instalado y registrando los “accesos indebidos”. No se han tomado medidas, lo único que hacemos es registrar, de manera que si vamos a http://miweb/es/admin/reports/dblog podemos filtrar los eventos de PHPIDS como muestra la figura:
Y si hacemos clic sobre el enlace del mensaje, se puede ver todo el detalle:
En ambos casos se PHPIDS se puede configurar de varias maneras: que registre, que bloquee, distintos grados de seguridad etc. Espero que este post al menos haya servido para mostrar que no es difícil poner un +1 a la seguridad de una web PHP.
Magnífico post. Muchas gracias por el enlace