Manual sobre el uso de .htaccess como herramienta de seguridad en Apache, la configuración del WAF Mod_Security y el módulo anti-DoS Mod_Evasive.
.htaccess es un contenedor de directivas y reglas que, almacenado a nivel de directorio, complementa la configuración principal de Apache. Para que sea funcional, el VirtualHost debe tener:
AllowOverride All
Options FollowSymLinks
La mayoría de reglas de seguridad usan mod_rewrite, que debe estar activo en el servidor.
RewriteCond %{QUERY_STRING} (;|<|>|'|"|%0A|%0D|%22|%27|%3C|%3E|%00).*(/\*|union|select|insert|cast|set|declare|drop|update|md5|benchmark) [NC,OR]
RewriteCond %{QUERY_STRING} \.\.\/\.\. [OR]
RewriteCond %{QUERY_STRING} (localhost|loopback|127\.0\.0\.1) [NC,OR]
RewriteCond %{QUERY_STRING} \.[a-z0-9] [NC,OR]
RewriteCond %{QUERY_STRING} (<|>|'|%0A|%0D|%27|%3C|%3E|%00) [NC]
RewriteRule .* - [F]
RewriteCond %{HTTP_USER_AGENT} ^$ [OR]
RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} (winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} (libwww-perl|curl|wget|python|nikto|scan) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} (<|>|'|%0A|%0D|%27|%3C|%3E|%00) [NC]
RewriteRule .* - [F]
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http:// [OR]
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=(\.\.//?)+ [OR]
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=/([a-z0-9_.]//?)+ [NC]
RewriteRule .* - [F]
RewriteRule ^(cache|includes|logs|tmp)/ - [F]
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_URI} \.php|\.ini|\.xml [NC]
RewriteCond %{REQUEST_URI} \/library\/ [OR]
RewriteCond %{REQUEST_URI} \/images\/ [OR]
RewriteCond %{REQUEST_URI} \/cache\/
RewriteRule ^(.*)$ index.php [R=404]
AuthName "Introduce tus datos:"
AuthType Basic
AuthUserFile /www/miweb/.htpasswd
AuthGroupFile /dev/null
Require valid-user
El archivo .htpasswd debe situarse fuera del directorio público y, si es posible, fuera del open_basedir de PHP.
Deny from all
Allow from 83.165.114.0
Satisfy any
Con Satisfy any basta cumplir una de las dos condiciones (IP o contraseña). Con Satisfy All se deben cumplir ambas.
ErrorDocument 404 /errores/errorgenerico.php
ErrorDocument 403 /errores/errorgenerico.php
ErrorDocument 500 /errores/errorgenerico.php
Redirigir a una página genérica evita dar información sobre la estructura del servidor.
Options -Indexes
<Files *.php>
Deny from all
</Files>
<!-- También bloquear nombres del tipo xxx.php.gif -->
<FilesMatch "\.(php|php\.)(.+)(\w|\d)$">
Order Allow,Deny
Deny from all
</FilesMatch>
<Files ~ "\.old$">
Order allow,deny
Deny from all
Satisfy all
</Files>
<FilesMatch "(^|/)_">
Order allow,deny
Deny from all
Satisfy all
</FilesMatch>
Mod_Security actúa como Web Application Firewall (WAF) para Apache. Filtra y bloquea peticiones HTTP sospechosas: fuerza bruta, XSS, SQLi, etc.
apt-get install libapache2-mod-security2
sudo a2enmod security2
apachectl -M | grep security
El archivo de configuración está en /etc/modsecurity/modsecurity.conf.
| Directiva | Descripción |
|---|---|
SecRequestBodyAccess | Activa el análisis del cuerpo de las peticiones (On/Off). Necesario para inspeccionar parámetros POST. |
SecRequestBodyInMemoryLimit | Bytes reservados en RAM para los cuerpos de petición. Si se supera, se vuelcan a disco. |
SecRequestBodyLimit | Tamaño máximo del cuerpo. Si se supera, devuelve HTTP 413. |
SecRequestBodyNoFilesLimit | Límite para peticiones que no sean uploads. Por defecto 1 MB. |
SecRequestBodyLimitAction | Acción al superar el límite: Reject (bloquea) o ProcessPartial. |
| Directiva | Descripción |
|---|---|
SecResponseBodyAccess | Activa el análisis del cuerpo de las respuestas (Off por defecto). |
SecResponseBodyLimit | Límite en bytes de las respuestas. Si se supera, devuelve HTTP 500. |
SecResponseBodyLimitAction | Reject o ProcessPartial al superar el límite. |
SecResponseMimeType | Tipos MIME que se almacenan en buffers para análisis. |
Mod_Evasive mantiene una tabla dinámica con las URLs solicitadas por cada IP. Cuando una IP supera el número de peticiones por segundo configurado, la bloquea devolviendo un HTTP 403.
apt-get install libapache2-mod-evasive
Archivo de configuración: /etc/apache2/mods-available/evasive.conf
| Directiva | Descripción | Recomendado |
|---|---|---|
DOSHashTableSize | Tamaño de la tabla de hash. Valor alto = mejor rendimiento, más RAM. En servidores con alta carga: 2048+. | 2048 |
DOSPageCount | Máximo de peticiones por página concreta antes de bloquear la IP. | 2 |
DOSSiteCount | Máximo de peticiones a cualquier recurso del servidor. | 50 |
DOSPageInterval | Intervalo de tiempo (segundos) para el conteo de DOSPageCount. | 1 |
DOSSiteInterval | Intervalo de tiempo para el conteo de DOSSiteCount. | 1 |
DOSBlockingPeriod | Segundos que permanece bloqueada una IP. Cada nueva petición durante el bloqueo reinicia el contador y suma 10 segundos. | 10 |
DOSSystemCommand | Comando de sistema a ejecutar cuando se bloquea una IP (ej. regla de iptables). | - |
DOSWhitelist | IPs excluidas del control (ej. 192.168.17.*). | IPs propias |
DOSLogDir | Ruta del directorio de logs del módulo. | /var/log/apache2/ |
Ejemplo de configuración completa:
<IfModule mod_evasive20.c>
DOSHashTableSize 2048
DOSPageCount 2
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
DOSLogDir /var/log/apache2/evasive
DOSWhitelist 127.0.0.1
</IfModule>