7 de Enero, 2007

Controlando el acceso a las imágenes

Llevaba ya un tiempo con la mosca detrás de la oreja, porque me iban aumentando las visitas y el consumo de ancho de banda, y últimamente no escribo demasiado por aquí, así que algo debía ir mal.

En efecto, parece que en alguna anotación he puesto una foto atractiva :D, y la estaban enlazando en diferentes foros. Después de posponer una solución más o menos definitiva, no he tenido más remedio que ponerme manos a la obra.

La cuestión es que normalmente en los foros vía web no hay posibilidad de subir imágenes de una forma sencilla, y como los usuarios no tienen demasiados conocimientos, por ignorancia (quiero pensar :P) suelen poner la imagen sin más... y cuando se visita esa página, la imagen se descarga desde este servidor.

Claro, cuando tienes algunos servicios funcionando en una conexión doméstica, el ancho de banda de subida es bastante preciado porque es un recurso escaso, así que estas cosas al final pueden llegar a perjudicar, sobretodo si te enlazan desde un par de foros con un tráfico considerable :(.

He optado por atender a los referer, que es un dato que proporcionan los navegadores al pedir un recurso alojado en un servidor web, indicando una referencia a la petición.

Veamos un ejemplo: cuando se carga una imagen desde este artículo, su referencia es la página del artículo. Así que es fácil identificar las peticiones que no parten de una página en este servidor, porque sabemos que la referencia tiene que seguir un patrón.

He ojeado un poco de documentación y he dado con una solución, aunque posteriormente he buscado y hay muchas formas más de conseguir lo mismo probablemente de una forma más sencilla ;).

Mi propuesta consiste en añadir a httpd.conf lo siquiente:

# OJO: esto requiere mod_setenvif activado
# los nombres desde los que serviré imágenes
SetEnvIfNoCase Referer "^http://(.*)?\.usebox\.net(/.*)?" ok_img
SetEnvIfNoCase Referer "^http://(.*\.)?\reidrac\.dyndns\.org(/.*)?" ok_img
SetEnvIfNoCase Referer "^http://(.*\.)?jornadas\.kleenux\.org(/.*)?" ok_img

# cuando no hay referencia, también
SetEnvIf Referer "^$" ok_img

# imágenes que se pueden descargar desde cualquier servidor
SetEnvIf Request_URI "^/images/online.png$" ok_img
SetEnvIf Request_URI "^/images/blackshell-rss.gif$" ok_img

# filtramos el acceso a las imágenes, negando el acceso
# a toda petición si no se ha activado la variable ok_img
<LocationMatch "/.*\.(gif|jpe?g|png)$">
        Order deny,allow
        Deny from all
        Allow from env=ok_img
</LocationMatch>

Básicamente comprobamos algunas variables que están presentes en las peticiones y, si se dan los valores adecuados, activamos una variable para permitir el acceso a esos casos.

Para los patrones que buscamos se emplean expresiones regulares, y he tenido en cuenta dos casos:

  • Referer: aquí pongo una regla para cada referencia válida para descargar una imagen. He emleado una por nombre de dominio con el que se puede acceder a los contenidos. Hay que tener cuidado con un caso especial: cuando no hay referencia (algunos navegadores puede que no nos den este dato).
  • Request_URI: hay algunas excepciones, como las imágenes que se cargan desde el RSS, que no tienen porqué tener como referencia una página conocida. En estos casos permitimos siempre la descarga.

En la última parte aplicamos un filtro para acceder a ficheros acabados en .gif, .jpg, .jpeg o .png, en el que denegamos su acceso si no está la variable ok_img, que se encargarán de activar las reglas SetEnvIfNoCase y SetEnvIf si los casos que he descrito se cumplen.

No es una medida que me apasione, por eso he pospuesto durante mucho tiempo el aplicarla, porque me parece bien que se enlacen imágenes directamente. Lástima que el problema estaba ya tomando una dimensión importante para mi modesta conexión :(.

Actualización: he cambiado los patrones para los referer que indican algunos proxy (como SQUID). He visto que usan http://nombre.dom en lugar de http://nombre.dom/, así que indico la barra final como opcional.

Anotación por Juan J. Martínez, clasificada en: blog.

Hay 8 comentarios

Gravatar

Eres demasiado bueno, podrias haber reemplazado la imagen por otra algo mas "comprometida" y echarte unas risas ante el asombro de los propietarios de la otra web :)

por Moises, en 2007-01-07 02:36:45

Gravatar

Moisés pero eso no reduciría el consumo de ancho de banda... o ¿si?
Depende con que imágen lo hagas. Si pones una chiquitina... ;)

por corsaria, en 2007-01-07 20:39:17

Gravatar

Me quedé con la curiosidad de qué imagenes posteaban en otros foros...

por Des, en 2007-01-09 19:56:26

Gravatar

Pues la más demandada resulta ser una de don't feed the troll:
http://blackshell.usebox.net/images/novedades905.jpg

Curioso que busquen y vayan a parar a mi anotación, y los efectos... bueno, digamos que hay muchos foros, y además muchos trolls :S

por Juanjo, en 2007-01-10 09:13:45

Gravatar

Ponle esta...
http://www.jonco48.com/blog/Aviator.jpg

por Javi, en 2007-01-11 12:11:08

Gravatar

Estoy con corsaria en que enviar otra imagen sería contraproducente.

No permito el enlace de las imágenes porque me supone un perjuicio, no porque sienta algún tipo de satisfacción al hacerlo :P

por Juanjo, en 2007-01-11 12:26:24

Gravatar

hablando de imagenes ...
Hay un web de la "AENA" de un pais Americano que usa imagenes de cabodesantapola.org en su pagina principal.
Imaginaros lo bien que me lo pasé el día que me di cuenta...jijijijiji

por Ruben, en 2007-01-17 20:29:52

Gravatar

Rubén, no se te ocurrió hacer alguna captura de pantalla del antes y el después?

por Felipe, en 2007-01-18 10:00:47

Los comentarios están cerrados: los comentarios se cierran automáticamente una vez pasados 30 días. Si quieres comentar algo acerca de la anotación, puedes hacerlo por e-mail.

Algunas anotaciones relacionadas: