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.

![[xml]](/images/xml.gif)
