HotLinking: Prevenir el uso de tus imágenes desde fuera de tu Web

Trucos y Utilidades 1 de mar. de 2025

Qué es el HotLinking

El "hotlinking" es cuando alguién en vez de alojar sus propias imágenes en su servidor utiliza las imágenes de tu servidor para usarlas en su web.

Uno de los problemas de esto es que ese uso consume datos y ancho de banda de tu servidor.

En mi caso he visto que no solamente plagian el contenido de la web, sinó que encima usan mis propias imágenes como si fuesen propias en la web aumentando el consumo de datos de mi servidor.

Prevenir el HotLinking

Una de las maneras más sencillas de prevenir el hotlinking es usar un fichero .htaccess en la raíz de tu servidor para evitar que se puedan usar esas imágenes salvo en tu propio dominio.

Usando .htaccess

Un ejemplo de como usar un fichero .htaccess para prevenirlo sería algo así:

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?soloconlinux.org.es/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^https://(www\.)?soloconlinux.org.es/.*$ [NC]
RewriteRule \.(gif|png|webp|jpg|jpeg)$ - [F]

Si además quisieramos devolverles una imagen genérica por cada imagen nuestra que quieren usar podríamos incluir una línea extra al final como la siguiente:

RewriteRule \.(gif|png|webp|jpg|jpeg)$ http://soloconlinux.org.es/soloconlinux-img-protegida.png [R,L]

Con lo el aprovechado simplemente obtendría la siguiente imagen:

Usando Nginx

Sin embargo algunas aplicaciones web debido al lenguaje en que estén programadas no permiten hacer uso de  .htaccess para prevenir esto, es el caso del blog basado en Ghost, que uso para las publicaciones de SoloConLinux.

En este caso y dado que por delante del blog utilizo Nginx para servir las páginas web simplemente he modificado el fichero .conf en el que tengo la configuración de la publicación de mi blog.

Os muestro como era mi fichero antiguo de soloconlinux.conf para Nginx:

# soloconlinux
server {
    if ($host = soloconlinux.org.es) {
        return 301 https://$host$request_uri;
    } # Con certificado gestionado por Certbot

  server_name soloconlinux.org.es;
  listen      80;
  listen [::]:80;
  return 301 https://$host$request_uri;   
}

server {
  server_name soloconlinux.org.es;
  access_log /etc/nginx/conf.d/logs/soloconlinux-access.log;
  listen      443 ssl;
  listen [::]:443 ssl;

  location / {
    include /etc/nginx/conf.d/includes/proxy.conf;
    proxy_pass http://soloconlinux:2369;
  }
# INI - Certificados de LetsEncrytp gestionados por Certbot
ssl_certificate /etc/letsencrypt/live/soloconlinux.org.es/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/soloconlinux.org.es/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# FIN - Certificados de LetsEncrytp gestionados por Certbot
}

Algunos detalles sobre el fichero de configuracion:

  • Todas las peticiones http son redigiridas a https mediante return 301
  • El servidor solo responde por un puerto seguro (443) y mediante SSL
  • El blog está publicado en un contenedor en el puerto 2369 al que el Nginx redirige las peticiones (proxy_pass)
  • El servidor usa certificados de LetsEncrypt para autenticar el dominio

Para proteger ciertos ficheros y evitar que se puedan usar de manera externa desde otros servidores, simplemente deberemos incluir algunas líneas en el fichero de configuración.

El fichero final quedará así:

# soloconlinux
server {
    if ($host = soloconlinux.org.es) {
        return 301 https://$host$request_uri;
    } # Con certificado gestionado por Certbot

  server_name soloconlinux.org.es;
  listen      80;
  listen [::]:80;
  return 301 https://$host$request_uri;   
}

server {
  server_name soloconlinux.org.es;
  access_log /etc/nginx/conf.d/logs/soloconlinux-access.log;
  listen      443 ssl;
  listen [::]:443 ssl;
  
  # Incluimos parametros proxy para determinar host
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header Host $http_host;

  location / {
    include /etc/nginx/conf.d/includes/proxy.conf;
    proxy_pass http://soloconlinux:2369;
  }

  # Filtro para imagenes gif, png, webp y jpg/jpeg
  location ~* \.(gif|png|webp|jpe?g)$ {
    valid_referers none blocked soloconlinux.org.es;
    if ($invalid_referer) {
        return 403;
    }
    proxy_pass http://soloconlinux:2369;
  }

# INI - Certificados de LetsEncrytp gestionados por Certbot
ssl_certificate /etc/letsencrypt/live/soloconlinux.org.es/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/soloconlinux.org.es/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# FIN - Certificados de LetsEncrytp gestionados por Certbot
}

Los cambios realizados son:

  • Incluir opciones de proxy_set_header para determinar el host del que se realizan las peticiones
  • Incluir un filtro con un OR (mediante el |) para los ficheros de tipo gif, png, webp y jpeg.
  • Se bloquea la petición externa para todos los dominios excepto el que sea soloconlinux.org.es: valid_referes none blocked dominio
  • Si no es uno de nuestros dominios permitidos, en el if le enviamos un error 403 indicando que recibimos la petición pero tiene prohibido el usar ese recurso

Con estos sencillos cambios los que se aprovechan de nuestros ficheros indicados y los ponen en su web, directamente obtendrán un precioso hueco en vez de nuestra imagen y no consumirán nuestro ancho de banda.

Eso si, por ahora podrán seguir copiando nuestras imágenes, pero al menos no nos consumirán ancho de banda.

Etiquetas

Luis GuLo

🐧 SysAdmin GNU/Linux - 🐳 Docker - 🖥️ Bash Scripting - 🐪 Perl - 🐬 MySQL - 👥 Formador de TI - 👥 Formador de SysAdmin's - 💢 Ansible - ☁️ Cloud Computing - ❤️ Debian GNU/Linux