Instalación y configuración básica de ModSecurity
Desde hace tiempo tengo ganas de instalar un Web Application Firewall (WAF) y siempre tuve ModSecurity en la mira. Hoy con un poco de tiempo, decidí darle una chance y jugar un rato.
ModSecurity es un módulo para Apache que permite analizar los pedidos en distintas fases del protocolo HTTP. De esta forma, es posible procesar los pedidos antes de ser entregados a la aplicación subyacente (por ejemplo, escrita en PHP), o luego de que se completó la ejecución. Con este sistema es posible prevenir ataques de SQL Injection, XSS, LDAP Injection, File Injection, Session Fixation, etc.
Como es un módulo para Apache, es muy fácil de instalar, aunque requiere algunos pasos para su configuración. En este artículo explicaré cómo instalar, configurar y poner en funcionamiento ModSecurity. La explicación culmina con una configuración básica de ModSecurity trabajando en modo monitoreo, es decir, sólo loggea los eventos, no actúa de forma activa. Por supuesto que la verdadera utilidad de un WAF es la prevención de los ataques, pero para evitar falsos positivos que afecten la funcionalidad de los sites que se encuentren activos, es preferible comenzar en un modo pasivo e ir habilitando reglas a medida que se va conociendo el tráfico.

Instalar ModSecurity en debian, una vez que ya está instalado Apache, es tan simple como ejecutar:
  apt-get install libapache2-modsecurity modsecurity-crs

El paquete modsecurity-crs contiene el conjunto de reglas core creado por OWASP. ModSecurity es simplemente el motor del firewall y todo firewall necesita reglas para funcionar. Las reglas creadas por OWASP abarcan todos los ataques más comunes de la web y por supuesto que son gratuitas de utilizar.

Una vez instalado el módulo, debe activarse ejecutando:
  a2enmod mod-security

En el paquete de debian encontré un error al intentar cargar el módulo, dado que las librerías estaban mal referenciadas en el archivo .load. Para arreglar el problema, debe modificarse la línea Load del archivo /etc/apache2/mods-enabled/modsecurity.load para que quede
  LoadFile /usr/lib/libxml2.so.2
en lugar de "LoadFile libxml2.so.2".

Para probar que el módulo está instalado correctamente, renombrar el archivo de configuración default:
  mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
reiniciar Apache:
  /etc/init.d/apache2 restart
y ejecutar nikto:
  nikto -host http://localhost
Puede utilizarse cualquier otra herramienta que genere tráfico malicioso, nikto es solamente un ejemplo.

Con esto ya debería existir el archivo de auditoría /var/log/apache2/modsec_audit.log, donde deberían estar las entradas generadas por nikto.

Como explicaba al principio, por si solo ModSecurity no hace nada, necesita ser alimentado con reglas, para ello el paquete modsecurity-crs. Si ya está instalado, las reglas se encontrarán en /usr/share/modsecurity-crs/. Este directorio está dividido en 5 subdirectorios:
  activated_rules
  base_rules
  experimental_rules
  optional_rules
  slr_rules
Los nombres explican por si mismos el contenido. La idea es colocar en activated_rules links simbólicos a las reglas que deseemos activar, como por ejemplo "/usr/share/modsecurity-crs/base_rules/modsecurity_crs_41_sql_injection_attacks.conf". Todo dependerá de qué deseen hacer, es una cuestión organizativa.
Para una configuración básica, simplemente incluiremos todo el directorio base_rules, en lugar de incluir activated_rules y agregar de a una las reglas. También debe incluirse el archivo de configuración modsecurity_crs_10_config.conf, que cuenta con seteos básicos. Esto se realiza editando el archivo "/etc/apache2/mods-enabled/mod-security.conf" y agregando las siguientes líneas:
  Include "/usr/share/modsecurity-crs/modsecurity_crs_10_config.conf"
  Include "/usr/share/modsecurity-crs/base_rules/*.conf"
es decir, el archivo debería quedar como a continuación:
<ifmodule security2_module="">
        SecDataDir /var/cache/modsecurity
        Include "/etc/modsecurity/*.conf"
        Include "/usr/share/modsecurity-crs/modsecurity_crs_10_config.conf"
        Include "/usr/share/modsecurity-crs/base_rules/*.conf"
</ifmodule>

Cada vez que realicen un cambio en la configuración deberán cargar nuevamente Apache. Claro que no es necesario reiniciarlo, también es posible hacer un reload más sutil y no matar las conexiones existentes:
  /etc/init.d/apache2 graceful

Un error bastante común al ejecutar las reglas de OWASP es el exceso en el límite de la librería PCRE que viene por defecto en el archivo modsecurity.conf. El error contiene el siguiente mensaje:
  Execution error - PCRE limits exceeded
Estos límites se configuran mediante las directivas SecPcreMatchLimit y SecPcreMatchLimitRecursion (modsecurity - Configuration Directives) y previenen que expresiones regulares mal formadas se salgan de control. Aumenten con cuidado este valor, tratando de que las reglas se ejecuten, pero sin asignar un número exorbitante. Por ejemplo, un valor que a mi me funcionó bien es 5000:
  SecPcreMatchLimit 5000
  SecPcreMatchLimitRecursion 5000

Con esto ya cuentan con ModSecurity habilitado y funcionando en modo "sniffer", dado que sólo revisa el contenido y loggea los ataques. A partir de aquí deberán analizarse dichos logs y decidir qué tipo de prevención aplicar. Hay que tener cuidado con los falsos positivos, dado que pueden influir en el correcto funcionamiento de los sites que intentamos proteger.

Una idea interesante es utilizar ModSecurity en conjunto con el módulo mod_proxy, es decir, utilizar Apache como un reverse Proxy y proteger con una sola instancia de ModSecurity varios web servers que se encuentren detrás.


Referencias

- ModSecurity Reference Manual
- Category: OWASP ModSecurity Core Rule Set Project
- mod_security on Apache