0

I want to prevent hotlingking in my site.

However I also have cloudflare to serve my site. I don't want to use cloudflare hotlinking protection feature as it cannot exclude external domain that I allowed image linking (as well as redirect images to a hotlink-denied image). Thus I want to prevent hotlinking in my server level.

The problem is when I enabled it in my server, the cloudflare will redirect to the hotlink-denied images, regardless what is the domain, which including my own domain. Here is the codes I used:

location ~* \.(gif|png|jpe?g)$ {

  # prevent hotlink
  valid_referers none blocked ~.google. ~.bing. ~.yahoo. allowed-domain.com, server_names ~($host);
  if ($invalid_referer) {
    rewrite (.*) /static/images/hotlink-denied.jpg redirect;
    # drop the 'redirect' flag for redirect without URL change (internal rewrite)
  }
}

location = /static/images/hotlink-denied.jpg { }

Is there anyway to bypass cloudflare on the images?

dev-jim
  • 283
  • 1
  • 2
  • 8
  • I've significantly changed my answer. Short version: with CloudFlare enabled hotlink protection in Nginx doesn't seem to work. I've given you two options below in my answer to make it work. – Tim Aug 31 '17 at 20:28

3 Answers3

0

TL;DR

You can create a page rule for your should-not-be-hotlinked images in cloudflare:

Url matches: https://example.com/images/*
The setting: Cache Level: Bypass

Now all requests goes to your server without being cached, and hotlinking is being blocked by your server.

Long answer:

If you don't disable caching, then cloudflare will add your successfully linked images to their CDN and any additional hotlink request would succeed since the request never goes to your server, so it cannot be blocked.

Note: The cloudflare hotlink protection (Scrape Shield) currently only works for gif, ico, jpg, jpeg, and png. not svg.

Fredrik
  • 528
  • 2
  • 10
0

Images are a key static resource you want to deliver via a CDN. That reduces your server load and makes your website load faster for your visitors. That might not suit some use cases though.

I use CloudFlare for hotlink protection. Like you, when I turn it off, Nginx hotlink protection doesn't work. My configuration looks very similar to yours.

The best way to enable hotlinking is to follow the CloudFlare instructions if you want to enable hotlinking.

You can currently specify certain URLs where hotlinking is ok by using the "hotlink-ok" parameter in the URL. So, for example, you could setup a directory called "hotlink-ok" and put the images you want hotlinkable in it. Something like:

http://www.yoursite.com/images/hotlink-ok/someimage.jpg

Option Two

The next option would be to create a subdomain, host it under CloudFlare, but turn Hotlink protection off. Currently this is done in the "content protection" tab, far right of the control panel.

You have two sub options here

  • Use the CloudFlare CDN to host and serve the images (orange cloud on). This reduces your server load and bandwidth, but makes the images available to anyone.
  • Turn caching off (gray cloud), so CloudFlare is just acting as a DNS server. Use Nginx for hotlink protection as you're currently doing.

My Nginx Config

Here's my Nginx config, which like yours, doesn't work through CloudFlare.

# Cache images on the client. Don't log errors or access. Block hotlinking.
location ~*  \.(jpg|jpeg|png|gif|css|js|ico|woff|woff2)$ {
  valid_referers none blocked server_names ~($host) ~(googleusercontent|google|bing|yahoo);
  if ($invalid_referer) {
    rewrite (.*) /stop-stealing-images.png redirect;
    # drop the 'redirect' flag for redirect without URL change (internal rewrite)
  }

  # Set up caching - 8 days for static resources. Remove the old unnecessary Pragma and hide the server version
  add_header Cache-Control "public, max-age=691200, s-maxage=691200";
  more_clear_headers Server; more_clear_headers "Pragma"; more_clear_headers "Expires";
}

# This allows the "stop stealing images" image to be hotlinked
location = /stop-stealing-images.png { }
Tim
  • 30,383
  • 6
  • 47
  • 77
-1

Check cloudflare's referer string in your logs vs what you're including there. If it's not present, you will just need to include that in your valid referers line and it should work fine. :)

Tim
  • 30,383
  • 6
  • 47
  • 77
Reverend Tim
  • 799
  • 7
  • 14