Select Page

Nginx: Hotlink protection via rewrite

Or: how you can punish picture thieves!

Almost everyone who runs a website with editorial content on the Internet is familiar with this: image theft via hotlink.
And preferably with a completely copied text that you have painstakingly researched and spent hours writing down and proofreading.

This article was last updated on April, 14 2022.

info
Written by Saskia Teichmann
on January 31, 2016
Sending
User Review
0 (0 votes)
Comments Rating 0 (0 reviews)
Hotlink protection ∙ Protect media ∙ nginx
Nginx: Instructions - Configure hotlink protection

There is not even a backlink to your own website, unless the content thief has simply copied and pasted the entire content from the source code into his website. Then it can happen that you have linked to another of your own posts somewhere with the complete URL. And this link is then still contained in the text. But first take a deep breath and first things first:

What is a hotlink actually?

A hotlink is, for example, the integration of an image via a direct link to the existing URL. Without downloading the image beforehand, uploading it to your own web space or server and then linking it from there.

Hotlinks are not generally bad. At least not if the hotlinking has been agreed with each other or if you are an image upload service.
In most cases, however, you are not an image upload service, but simply someone who pays for their web hosting every month and has a certain traffic limit. And here we come to the crux of the matter.
If someone else displays media files on their homepage that are located on your web server, your server serves each of these third-party requests because that's what servers do. They serve (serve, provide, serve, serve).

Now the content thief has a free image on his website for which no traffic is generated/charged on his own server. This traffic (server load) is billed to the thief, i.e. you, and costs server resources every time a visitor surfs to the content thief's site and the image is displayed in their web browser.
Under certain circumstances, this can lead to incredible external traffic. Depending on how much visitor traffic the content thief has on his website.
That's really not funny.

Today I would like to show you how you can configure your own NGINX web server so that it does not serve these external requests as expected, but instead serves a different image to visitors to the content thief website.
This way, you can reverse the supposed damage and benefit from it, and if you are really angry, you can get one over on the thief: attract visitors to your own website!

How to turn NGINX into an invincible Hotlink boss!

This is the plan:

  • We want a comprehensive solution that works for all domains. So that you don't have to customize each individual vHost configuration (sites-available).
  • The request link should be rewritten (rewrite) and thus a specific, different image is served to the thief's side instead
  • It must work with Google Image Search and other search engines with an image search function instead of banning hotlinking altogether. Otherwise, Google Image Search will no longer display your actual images, but only the replacement image

Solution to the image theft

These few lines of code are ultimately the solution to the problem with image theft. You can find out how and where to place the code in the next section.

location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|swf)$ {
  add_header "Access-Control-Allow-Origin" "*";
  access_log off;
  log_not_found off;
  expires max;
  valid_referers none blocked ~.google. ~.bing. ~.yahoo. ~.yandex. server_names ~($host);
    if ($invalid_referer) {
      rewrite (.*) /hotlink/eight-content-and-image-stealing.png redirect;
      }
}
#hotlink end redirect loop
location = /hotlink/eye-content-and-image-stealing.png { }

What does the code do?

~ is used to take upper/lower case into account, while ~* Case-sensitive ignored.

NGINX checks the locations rule in the order in which the regular expressions are inserted. This means that the caching header instructions for media files and the instructions for our hotlink protection must be in the same block!

location = /hotlink/eighth-content-and-image-stealing.png { } is required so that the new request for the replacement image does not result in an infinite forwarding loop:
Image thief site sends request for imageA → our NGINX redirects the request for replacement image → image thief site sends request for replacement image → our NGINX redirects the request for replacement image, but does not serve → and so on...

Placeholder image for image theft

$host is a variable that makes this instruction globally usable and works under all vHost domains on the web server. The following URL is valid for every domain: http://$host/hotlink/achtung-inhalts-und-bilderklau.png

Only the directory /hotlink and an image file with the name: attention-content-and-image-stealing.png should be stored in this directory. You can also name the file and directory differently if you wish. Just adapt the code accordingly.

How to integrate the location rule

This is how you proceed to equip your NGINX web server with this special hotlink protection against image theft.

Total Time: 30 minutes

Preparations: Create and upload exchange graphic

First create a graphic that visitors to the Thief website should see and upload it to the desired directory on your web server. Make a note of the URL of the graphic.

NGINX Webserser locations Customize configuration

On your server, navigate to the directory /etc/nginx/common/ and find the locations configuration included in the server block of your vhost, which contains rules for the location defined in the code above. As a rule, there will already be an existing rule block for the specified location. If not, simply insert the above code as a new rule block in the correct file.
If the block already exists, insert only the above rules without the locations wrap.

Save and reload NGINX web server configuration

Then save the configuration file with the extended locations block on the server and test the new configuration first via the SSH terminal with nginx -t
If the test has gone through without any problems, restart your NGINX with the command service nginx restart.

Test your hotlink protection!

Here I have written a tool that you can use to test your hotlink protection configuration. Enter the direct URL for a graphic on your nginx server in the input field. Ideally, your replacement image should then be displayed in the output field below. If the image from the entered URL appears, you must check your hotlink protection again.

If you want to run the test several times in succession for the same image URL, you must clear your browser cache after each test and reload this page.

Check image URL

Do you still have questions? Then don't hesitate to use the comment function below this article!

Please share this article on your Facebook page, Twitter, Google+ or another social platform of your choice. Below you will find the share buttons. Sharing is quick and easy and I would really appreciate it.

<span class="castledown-font">Saskia Teichmann</span>

Saskia Teichmann

A WordPress full stack web developer from Germany who likes to create beautiful websites and sophisticated web projects.

In her free time, Saskia enjoys hiking with her family in the Tramuntana mountains on Mallorca, walking in the Herrenhausen Gardens in Hanover or swimming in the sea.

Submit a project requestServing coffee

9 Comments

  1. Kuwe

    Super ingenious post! The idea is really simple 🙂 I think it's great. Unfortunately, I've never thought that far before, as this has never been a problem for me (could be due to the content ;)).
    I am also very surprised to read something about Nginx configuration on a frontend / design page. WordPress is also more tuned to Apache, although some plugins now also support Nginx more and generate configs for it instead of just creating an Apache htaccess 😉

    Btw. I think your designs are great too! *both thumbs up* 🙂

    Reply
    • Saskia Lund

      Thank you for this great feedback!

      To be honest, I think nginx is the "better" and faster web server in combination with WordPress. Just do a little googling on the subject 🙂

      To the front-end comment:
      I'm a frontend developer, but since I specialize in WordPress, there's no way around php in my eyes, and at some point there's no way around server-related issues.

      Many thanks again!

      Reply
  2. Frank

    Great article! Where exactly should the code be placed? In the htaccess in the root of the website? Or in a separate htaccess in the image directory? Thank you very much!

    Reply
    • Saskia Lund

      Hello Frank!

      If you are using an nginx web server, the .htaccess will not be used; in other words, an nginx web server cannot do anything with .htaccess files.

      .htaccess files are used in conjunction with Apache web servers.

      The above code is usually used globally in the locations.conf file in the server directory /etc/nginx/common/ for an nginx web server.
      It is important to take a close look at your own server configuration in locations.conf. If there is already a locations rule for the above-mentioned location, you must then adapt it using the above code; otherwise, as mentioned, simply insert, save and then execute the new configuration of the nginx using the terminal command nginx -t briefly check. If the nginx in the terminal reports back that everything is tutti, you can use service nginx restart Restart the web server to load the new configuration.

      Good luck!

      Reply
  3. Frank

    Thanks and sorry...I had overlooked Nginx in the title. I am looking for a functioning hotlink protection for my Magento store on an Apache, preferably without Google penalties.

    Reply
    • Saskia Lund

      Hello Frank!

      For an Apache counterpart, try adding the following to your .htaccess file in the root directory of your website:

      1st variant (if you generally want to prohibit the hotlinking of image files, but want to allow hotlinking for certain domains (e.g. google.*, bing.*, yahoo.*, yandex.*, duckduckgo.*, etc.):

      RewriteEngine on
      # Remove the following line if you also want to block empty referrer URLs:
      RewriteCond %{HTTP_REFERER} !^$
      
      RewriteCond %{HTTP_REFERER} !^https?://(.+\.)?yourdomain.com [NC]
      RewriteRule \.(jpe?g|png|gif|bmp)$ - [NC,F,L]
      
      # If you now want to display a replacement image instead of the actually hotlinked image, replace the above rule as follows:
      # RewriteRule \.(jpe?g|png|gif|bmp) http://deinedomain.de/blocked.png [R,L]
      
      # Allow hotlinking from the following sites (domains)
       RewriteCond %{HTTP_REFERER} !^https?://(www\.)?google\.com/.*$ [NC]

      2. if you only want to block hotlinking for certain referrers (bad domains):

      RewriteEngine on
      RewriteCond %{HTTP_REFERER} ^https?://(.+\.)?schlingel1\.com [NC,OR]
      RewriteCond %{HTTP_REFERER} ^https?://(.+\.)?schlingel2\.com [NC,OR]
      RewriteRule \.(jpe?g|png|gif|bmp)$ - [NC,F,L]
      
      # If you would now like to display a replacement image instead of the actually hotlinked image, replace the above rule as follows:
      # RewriteRule \.(jpe?g|png|gif|bmp) http://deinedomain.de/blocked.png [R,L]

      I hope this helps you

      Best regards
      Saskia

      Reply
  4. Miller

    Who knows a hotlink protection for bmbfotos.com?
    nothing works for this page

    Reply
    • Saskia Lund

      Hello "Müller"!
      Which images on the above-mentioned website are hotlinked, for example?
      Perhaps they can help you further.

      Best regards
      Saskia Lund

      Reply
  5. Ralph

    Is it possible to block only one domain? By rewrite ?

    Reply

Submit a Comment

Your email address will not be published. Required fields are marked *

Sending