24x7 Linux Página personal y profesional HTML 4.01 válido CSS válido
Rechazar los enlaces desde determinados sitios web

Lo que se dice en el encabezado de este artículo puede no tener sentido a primera vista. ¿ Por qué razón iba yo a limitar la posibilidad de que la gente llegue a mi página pulsando un enlace en otras páginas distintas ?. ¿ No era esto de los hiperenlaces la idea principal detrás del lenguaje HTML y la web en general ?. En efecto, pero como casi todo en esta vida hay gente que se aprovecha de las posibilidades de una técnica para abusar de ella. Y los hiperenlaces entre páginas no escapan a estos abusos.

Imagínese que su sitio web contiene algún tipo de banner publicitario, que quizás le permite costear las facturas de su acceso a Internet, su hosting, o ni siquiera eso. Cuidado, que desde hace unos meses, si usted reside en España o sirve sus páginas desde una máquina dentro del territorio nacional le es de aplicación la LSSI (Ley de Servicios de la Sociedad de la Información y Comercio Electrónico), especialmente si obtiene ingresos de ella, por reducidos que sean.

Siga imaginando, y piense que el mayor reclamo que atrae visitantes a su web es, por ejemplo, un programa CGI al cual se le pasan como parámetros en un formulario las coordenadas geográficas de un punto del planeta, y el programa genera una página con una imagen del plano topográfico de esa zona, marcando el punto de coordenadas introducidas. Evidentemente hacer dicho programa le ha costado mucho tiempo y esfuerzo, quizá escanear decenas de mapas, y al menos desea que cada vez que alguien use dicho programa vea el banner publicitario, para a fin de mes al menos pagar el coste de su línea de acceso a Internet.

Suponga también que alguien visitó su página, le gustó y pensó que replicando en su propio servidor (con sus propios banners publicitarios) la página que da acceso a su aplicación podría sacarse unos euros a finales de mes (ingresos que evidentemente usted dejará de tener). Llevar a cabo este "robo" es tan sencillo como copiar el formulario HTML donde recabar los datos, y enlazar el CGI de nuestro servidor, que nos enviará la imagen.

Otra aplicación más común de la misma técnica consiste en disponer nosotros de una web con un amplio catálogo de imágenes, y que desde páginas externas a nuestro servidor enlacen a nuestros archivos. De esta manera los visitantes de aquel otro servidor verán las imágenes almacenadas en nuestro servidor, el consumo de ancho de banda lo sufrirá nuestro servidor, y todo ello de manera que el visitante del sitio remoto piensa que las imágenes realmente pertenecen a ese sitio, y no al nuestro. Estos abusos y otros similares se pueden evitar configurando adecuadamente nuestro servidor Apache, como se explicará a continuación.

Evidentemente no podemos evitar que alguien visite nuestra web, se descargue una a una las imágenes, y las copie tal cual en su sitio. Pero en este caso el ancho de banda que consuma la transferencia de las imágenes lo pagará él, de manera que posiblemente no le parezca tan buena idea.

Para entender lo que vamos a explicar a continuación resulta necesario tener claros los conceptos básicos de funcionamiento del protocolo HTTP: en caso necesario, lea acerca de los conceptos básicos. Las restricciones que vamos a llevar a cabo en la configuración de Apache se basan en la cabecera HTTP Referer, que para cada página que solicita nuestro navegador contiene la URL de la página donde se encuentra el enlace que hemos seguido (bien pulsando sobre él, bien con enlaces en la página HTML).

GET /images/imagen.png HTTP/1.1
Host: www.24x7linux.com
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3a) Gecko/20021212
Accept: text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png
Accept-Language: es,en;q=0.7,fr;q=0.3
Referer: http://www.24x7linux.com/index.shtml

Como puede ver, dentro de las cabeceras HTTP que el navegador del visitante envía al servidor web se encuentra una llamada Referer, que indica desde qué página hemos solicitado el recurso (en el ejemplo el recurso es el archivo /images/imagen.png). En el ejemplo se ve que la imagen solicitada forma parte de los contenidos de la página principal del sitio web www.24x7linux.com, luego parece bastante lógico que permitamos la descarga de esta imagen.

Si por el contrario tratamos de obtener el recurso /images/imagen.png tecleando directamente su URL en el navegador (http://www.24x7linux.com/images/imagen.png), el navegador no enviará al servidor cabecera Referer alguna. Si alguien enlaza a nuestro archivo gráfico /images/imagen.png desde una página de su propio sitio web, la cabecera Referer que llegará a nuestro servidor Apache será similar a la siguiente:

Referer: http://www.listillos.com/robos/descarados/index.shtml

Como se puede ver en este artículo sobre personalización de logs de Apache tenemos la posibilidad de definir variables de entorno en función de la existencia y contenido de cualquier cabecera HTTP para cada petición recibida en nuestro servidor, y responder de manera personalizada según estas variables de entorno. Por ejemplo, podemos denegar el acceso a estos contenidos o no en función de alguna de estas variables de entorno establecidas según el Referer de la petición.

Para que todo quede más claro vamos a ver un ejemplo práctico: evitar que ningún sitio web pueda enlazar a nuestro directorio de imágenes /images (supondremos que todas las imágenes que deseamos proteger se encuentran ahí, aunque Apache permite restringir el acceso por nombre de archivo, URL, directorio, etc.). Para llevar a la práctica esta limitación no vamos a modificar (a menos que sea necesario) el archivo de configuración principal de Apache, típicamente /etc/apache/httpd.conf. En su lugar vamos a usar un archivo .htaccess en el directorio cuyo acceso deseamos limitar.

Apache, para cada página solicitada, debe consultar dos conjuntos de reglas de acceso para determinar si el usuario remoto puede o no acceder al recurso solicitado, si requiere identificarse, etc. Por una parte, los mecanismos de identificación, autorización y control de acceso definidos en el archivo /etc/apache/httpd.conf (cuyos cambios sólo aplican al servidor en ejecución cuando lo reiniciamos o enviamos una señal). Y por otra, de estar activado en el archivo anterior, las reglas definidas en los archivos .htaccess de todos los directorios padre del que cuelga el recurso solicitado por el navegador. Es decir, si el navegador pide el recurso http://www.24x7linux.com/images/imagen.png, y el DocumentRoot del servidor es /home/http/, Apache evaluará las reglas de los siguientes archivos:

/etc/apache/httpd.conf
/.htaccess
/home/.htaccess
/home/http/.htaccess
/home/http/images/.htaccess

Parece claro que la activación de los archivos .htaccess supone una ralentización del servidor, puesto que han de evaluarse por cada petición de página. Pero esta característica es precisamente una de sus grandes ventajas frente al uso del control de acceso en el archivo /etc/apache/httpd.conf, y es que tan pronto guardamos a disco los cambios en el archivo .htaccess estos aplican a las siguientes peticiones de página. Además puede ser más sencillo de mantener un control de acceso homogéneo con este mecanismo, o simplemente resultarnos más sencillo de mantener. Un hecho donde ambos mecanismos de control de acceso coinciden es que el control de acceso especificado en un directorio aplica tanto al archivo y directorio indicado como a todos los subdirectorios.

Sin embargo por motivos de seguridad el uso de archivos .htaccess suele estar desactivado por omisión. Habitualmente en el archivo de configuración /etc/apache/httpd.conf hay un conjunto de reglas como las siguientes:

<Directory />
    AllowOverride None
</Directory>

La directiva AllowOverride None aplica al directorio raíz del sistema operativo (y a todos sus subdirectorios), e indica que aunque existan archivos .htaccess no haga caso de ninguna de las directivas presentes en ellos. En caso necesario deberíamos activar el soporte de archivos .htaccess para el directorio que deseamos proteger. Para ello deberíamos usar un conjunto de directivas como las siguientes en el archivo /etc/apache/httpd.conf. Consulte la documentación de AllowOverride para conocer todas las posibles opciones, puesto que a continuación sólo se usan las necesarias para el ejemplo.

<Directory /home/http/images/>
    AllowOverride Limit FileInfo
</Directory>

Volvamos al ejemplo. Debemos establecer una cierta variable de entorno cada vez que algún navegador nos pida un archivo dentro del directorio /images de nuestro servidor dependiendo de si el archivo se pide desde una página en nuestro propio servidor o desde cualquier otro de Internet. Entonces podremos permitir o no la descarga del archivo en función de si está definida o no dicha variable de entorno. La definición de la variable la llevaremos a cabo con la directiva SetEnvIfNoCase, ya explicada en este artículo, y la restricción del acceso con las directivas Order y Allow. El archivo /home/http/images/.htaccess contendrá las siguientes directivas:

SetEnvIfNoCase Referer "www\.24x7linux\.com" local
Order Allow,Deny
Allow from env=local

Definimos una variable de entorno llamada local para todas aquellas peticiones (no todas, sino sólo aquellas donde el archivo solicitado esté en el directorio /home/http/images/ del servidor) que provengan (cabecera Referer) de nuestras propias páginas. Y a continuación restringimos el acceso para sólo conceder permiso en caso de que la variable esté definida. La sintaxis más habitual de la directiva Allow (y de la directiva Deny) es usando nombres o direcciones IP de máquina, aunque en este caso necesitamos usar variables de entorno. El significado de la directiva Order Allow,Deny, así como de su versión alternativa Order Deny,Allow, puede encontrarla en la la documentación de Apache. Échele un vistazo, porque posiblemente las directivas Order no funcionen exactamente como usted piensa a priori que funcionan.

Antes de terminar quizás sea conveniente indicar que podríamos haber implementado la misma configuración que la indicada arriba de una manera alternativa:

SetEnvIfNoCase Referer "www\.24x7linux\.com" local
Order Deny,Allow
Deny from all
Allow from env=local

Ambos conjuntos de directivas representan exactamente el mismo comportamiento, pero quizás en este caso es más sencillo darse cuenta a primera vista del control de acceso implementado. Aunque existen más formas alternativas de hacer lo mismo, como por ejemplo negando la existencia de la variable de entorno cuya presencia indica un Referer local.

SetEnvIfNoCase Referer "www\.24x7linux\.com" local
Order Deny,Allow
Deny from env=!local

Última modificación: 01-March-2003 11:11:17 -0500

© 2002-2007 José Luis Domingo López. Todos los derechos reservados.
Contacte con el webmaster para informarle de fallos, incorrecciones o sugerencias.
Esta página cumple con los estándares HTML 4.01 y CSS2 del World Wide Web Consortium.