Emezeta.com

htaccess: Bloqueando a la fuerza


El último día hablaba sobre las recomendaciones para robots y crawlers mediante el robots.txt. Este sistema es un conjunto de indicaciones para que los crawlers no se «pierdan» y sepan en todo momento por donde pueden y deben ir.

¿Qué es lo que ocurre? Que cualquier persona me puede indicar que debo y que no debo tocar en su casa, pero en todo momento yo tengo la opción de hacerlo, aunque no deba. De eso vamos a tratar en este artículo, ¿Que ocurre si llega un crawler «listillo» que pasa olímpicamente de las recomendaciones que le hemos hecho? Pues que lo echamos a patadas de nuestra casa... ;)

Existe un fichero en los servidores web Apache (la mayoría de los servidores), llamado .htaccess, en el que puedes incluir información de control para dictar al servidor que hacer con tus visitantes y otro tipo de acciones.

htaccess crawlers block

Lo primero que necesitamos es un sistema de estadísticas o mejor aún, acceso a nuestro fichero access.log, registro donde se guardan todos los accesos a nuestro servidor. En Dreamhost, el servidor donde tengo alojado mi blog (y uno de los más famosos), tiene acceso SSH/FTP y puedes ver sin ningún problema a estos registros.

Bien con un sistema de estadísticas, o con nuestro fichero access.log, nos interesa observar los accesos por petición (request), navegador o agente (user agent) o por ip. Desde una consola SSH podemos conseguir un listado de las IPs que más peticiones realizan:

tail -10000 access.log | awk '{print $1}' | sort | uniq -c |sort -n

Esta secuencia de comandos nos muestra las últimas 10.000 llamadas a nuestro servidor, agrupándolas por IPs y mostrando el número de peticiones realizado.

Esto nos servirá para tener una idea de que crawlers, robots o usuarios pueden estar sobrecargando nuestro servidor con demasiadas peticiones. Existe un programa bastante útil que yo utilizo para analizar los access.log, llamado Apache Log Viewer. La única y «minúscula» pega es que está en japonés.

  84 63.161.169.137
  85 crawl-66-249-67-236.googlebot.com
  91 81.177.8.166

Este no es un ejemplo real, pero imaginemos que esos son los resultados obtenidos. Tendríamos 84 peticiones de la IP que figura a su derecha. Si vamos a Inicio / Ejecutar / cmd y escribir nslookup IP podremos obtener el DNS inverso y saber a que compañía pertenece, o investigar un poco más con un analizador de logs o estadísticas y ver que accesos ha hecho.

¡Ojo! Que haga muchas peticiones no significa que sea un robot malvado. Puede que se trate de nuestro más fiel visitante o nuestro querido buscador de Google. Mucho cuidado con bloquear IPs sin pensarselo.

En mi caso resultó que la IP 81.177.8.166 realizaba bastantes peticiones, e investigando un poco más pude ver que eran a antiguos ficheros de un formulario que ya no existían. Probablemente un robot spam que sigue torpemente intentando enviar comentarios de SPAM, generando peticiones inútiles.

Si tenemos dudas la mejor opción es hacer un Whois y si nos parece que está realizando un ataque, enviar una queja al email de abuse del ISP que muestra en el whois.

block crawler robots

Bloqueando por IPs


Si estamos completamente seguros de que la IP que hemos encontrado en nuestros logs nos está realizando ataques DoS o algún tipo de sobrecarga de peticiones, vamos a bloquearla. Para ello tenemos que editar el fichero .htaccess en la carpeta raíz de nuestro sitio vía SSH o FTP y escribir o modificar su contenido añadiendo:

Order allow, deny
Deny from 81.177.8.166
Allow from all

Y no solo bloquear IPs, sino también rangos de IPs mediante sus clases: Deny from 81.0.0.0/8. Esto también es aplicable a crawlers que hemos añadido en el robots.txt y vemos días o semanas después (ojo, a veces no leen el robots.txt instantáneamente) que no hacen caso. Ahora toca que hagan caso a la fuerza mostrando un código de error 403 (prohibido) en lugar de lo que esperaban.

Bloqueando con SetEnvIfNoCase


Se nos plantea otra dificultad. Los robots que acceden ahora nunca tienen la misma IP, siempre son totalmente diferentes y sin relación:

  • Bot 1: Su agente de usuario no varía, es Malvadobot/2.0.
  • Bot 2: No tiene nunca el mismo agente de usuario, ni IP, pero accede siempre al fichero /sendemail.php, que no existe.
  • Bot 3: Ninguno de los anteriores criterios es fijo, salvo que viene siempre (Referer) de la página http://www.spammers.com/.

¿Cómo los bloqueamos?

SetEnvIfNoCase User-Agent "Malvadobot/" spambot
SetEnvIfNoCase Request_URI "/sendemail.php$" spambot
SetEnvIfNoCase Referer "^http://www.spammers.com/" spambot
deny from env=spambot

Con este código estamos identificando los criterios de los tres bots anteriores para asignarles una variable llamada spambot si casa con los criterios, y que si es así, bloqueará.

Bloqueando con ModRewrite


Existe otra alternativa para bloquear, que necesita el módulo mod_rewrite, y aunque se utiliza para reescribir direcciones, nos puede venir bastante bien para bloquear. Lo he dejado para el final, puesto que creo que es la alternativa más costoso en términos de computación, con respecto a los métodos anteriores.

RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} ^Malvadobot/.* [NC]
RewriteCond %{REQUEST_FILENAME} ^/sendemail.php$ [NC]
RewriteCond %{HTTP_REFERER} ^http://www.spammers.com/.* [NC]
RewriteRule .* - [F]

En primer lugar activamos el motor del ModRewrite, y usamos los tres casos anteriores como condiciones con el RewriteCond. En caso de ser afirmativa, reescribimos mostrando un error 403, o también podemos usar un error 410 (Eliminado permanentemente) escribiendo [G] en lugar de [F]. En la página de documentación de ModRewrite hay mucha información para profundizar.

Ahora ya sabemos como bloquear. Hay que usarlo con mucho cuidado para no bloquear a usuarios legítimos y perder visitas.