Deshabilitar mod_security por virtualhost, location, reglas, IP…

ModSecurity es un excelente módulo de Apache que actua a modo de firewall de aplicaciones Web y que provee protección contra ataques, permite monitorizar el tráfico HTTP y realizar análisis en tiempo real.

Hace ya 7 años que publiqué una guía de instalación que en principio todavía es válida así que podéis echarle un vistazo. En esta entrada lo que quería enseñaros es la forma de deshabilitar el módulo o algunas de sus funcionalidades no a nivel global, sino por virtualhost o ruta de aplicación, entre otras. Está claro que es un módulo muy útil pero siempre será necesario desactivarlo para determinadas aplicaciones, ubicaciones, IPs, etc.

Desactivar completamente mod_security

Para desactivar completamente el módulo debemos utilizar la directiva «SecRuleEngine«:

<IfModule mod_security2.c>
 SecRuleEngine Off
 </IfModule>

Ese bloque se puede colocar tanto a nivel de virtualhost como de «Location». El «IfModule» me gusta ponerlo siempre para que en el caso de que algún día desactivemos el módulo a nivel global de Apache no provoque un fallo de sintaxis en la configuración.

Por ejemplo, para desactivarlo dentro de un location:

<Location /foo>
 <IfModule mod_security2.c>
 SecRuleEngine Off
 </IfModule>
 </Location>

Si la configuración de Apache lo permite (Allowoverride…) lo podríamos configurar a nivel de .htaccess  por sitio en lugar de tener que hacerlo en los archivos de configuración de Apache.

Deshabilitar una o varias reglas

Los falsos positivos están a la orden del día cuando utilizamos mod_security. Si quisiéramos hacer que una o varias reglas no fueran utilizadas por un determinado virtualhost, aplicación o location se puede especificar del siguiente modo:

<Location /foo>
 <IfModule mod_security2.c>
 SecRuleRemoveById 10001
 </IfModule>
 </LocationMatch>
<LocationMatch /foo.php>
 <IfModule mod_security2.c>
 SecRuleRemoveById 10001 10002 10003
 </IfModule>
 </LocationMatch>

El ID de la regla siempre aparece tanto en el log de mod_security cuando bloquea una petición como en los propios archivos de reglas, ejemplo:

--062f3e55-H--
 Message: Access denied with code 406 (phase 2). 
[file "/etc/httpd/conf.d/modsecurity_rules/modsecurity_crs_41_sql_injection_attacks.conf"]
 [line "235"] [id "981245"] [msg "Detects basic SQL authentication bypass attempts 2/3"]
[data "\x22 :\x22folderRename\x22,\x22a"] [severity "CRITICAL"] [tag "WEB_ATTACK/SQLI"]

Whitelist de IPs o segmentos de red

Si queremos que los accesos a través de una IP no sean parseados por el módulo de mod_security, podemos habilitar a nivel global de configuración la «whitelist»:

SecRule REMOTE_ADDR "^127.0.0.1$" nolog,allow

Esto se podría hacer también para una determinada regla o personalizar aún más como gestionar las peticiones de una determinada IP:

<IfModule mod_security2.c>
 SecRule REMOTE_ADDR "^10.0.0.100$" "phase:1,t:none,nolog,allow,ctl:ruleEngine=Off,ctl:auditEngine=Off,id:9999"
 </IfModule>
<IfModule mod_security2.c>
 SecRule REMOTE_HOST "@ipmatch 10.0.0.0/24" \
 "id:12345,phase:2,t:none,pass,nolog,noauditlog,ctl:ruleRemovebyID=330039"
 </IfModule>

Si queréis profundizar más en el tema os recomiendo echar un vistazo a la documentación de mod_security de Atomic Corp.