Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I am trying to implement image hotlink protection problem in nginx and I need help. I have a huge issue of my site's images being submitted to social networks like StumbleUpon with a direct link like

http://example.com/xxxxx.jpg

Which sometimes gets huge traffic and increases CPU usage and bandwidth usage. I want to block direct access to my images from other referrers and protect them from being hotlinked.

Here is the code from my vhost.conf

 server {
  access_log off;

  error_log  logs/vhost-error_log warn;
  listen    80;
  server_name  mydomain.com www.mydomain.com;

  # uncomment location below to make nginx serve static files instead of Apache
  # NOTE this will cause issues with bandwidth accounting as files wont be logged
  location ~* \.(gif|jpg|jpeg|png|wmv|avi|mpg|mpeg|mp4|htm|html|js|css)$ {
   root   /home/username/public_html;
   expires 1d;
  }

   root   /home/mydomain/public_html;
}


  location / {
   client_max_body_size    10m;
   client_body_buffer_size 128k;

   proxy_send_timeout   90;
   proxy_read_timeout   90;

   proxy_buffer_size    4k;
   # you can increase proxy_buffers here to suppress "an upstream response
   #  is buffered to a temporary file" warning
   proxy_buffers     16 32k;
   proxy_busy_buffers_size 64k;
   proxy_temp_file_write_size 64k;

   proxy_connect_timeout 30s;

   proxy_redirect  http://www.mydomain.com:81   http://www.mydomain.com;
   proxy_redirect  http://mydomain.com:81   http://mydomain.com;

   proxy_pass   http://ip_address/;

   proxy_set_header   Host   $host;
   proxy_set_header   X-Real-IP  $remote_addr;
   proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;

   expires       24h;

  }
  }

For hotlink protection I added this code

location ~* (\.jpg|\.png|\.gif|\.jpeg)$ {
     valid_referers blocked www.mydomain.com mydomain.com;
     if ($invalid_referer) {
        return 403;
     }

This is the current nginx code for this domain, but it didn't work:

 server {
  access_log off;

  error_log  logs/vhost-error_log warn;
  listen    80;
  server_name  mydomain.com www.mydomain.com;

  # uncomment location below to make nginx serve static files instead of Apache
  # NOTE this will cause issues with bandwidth accounting as files wont be logged
  location ~* \.(gif|jpg|jpeg|png|wmv|avi|mpg|mpeg|mp4|htm|html|js|css)$ {
   root   /home/username/public_html;
   expires 1d;
  }

   root   /home/mydomain/public_html;
}
  location ~* (\.jpg|\.png|\.gif|\.jpeg)$ {
     valid_referers blocked www.mydomain.com mydomain.com;
     if ($invalid_referer) {
        return 403;
     }


  location / {
   client_max_body_size    10m;
   client_body_buffer_size 128k;

   proxy_send_timeout   90;
   proxy_read_timeout   90;

   proxy_buffer_size    4k;
   # you can increase proxy_buffers here to suppress "an upstream response
   #  is buffered to a temporary file" warning
   proxy_buffers     16 32k;
   proxy_busy_buffers_size 64k;
   proxy_temp_file_write_size 64k;

   proxy_connect_timeout 30s;

   proxy_redirect  http://www.mydomain.com:81   http://www.mydomain.com;
   proxy_redirect  http://mydomain.com:81   http://mydomain.com;

   proxy_pass   http://ip_address/;

   proxy_set_header   Host   $host;
   proxy_set_header   X-Real-IP  $remote_addr;
   proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;

   expires       24h;

  }
  }

How can I fix this?

share|improve this question

migrated from stackoverflow.com Sep 12 '11 at 11:29

This question came from our site for professional and enthusiast programmers.

2 Answers 2

up vote 2 down vote accepted

You should ask this question on: http://serverfault.com/

My current site uses this:



## Stop Image and Document Hijacking, alow Google, MSN PicSearch
location ~* \.(png|gif|jpg|jpeg)$ {
        set $testref "";
        if ($http_referer !~ ^(http://mydomain.com|http://www.google|http://images.search.yahoo|http://www.bing|http://pictures.ask)){
           set $testref I;
        }
        if ($http_user_agent !~* (Googlebot|psbot|msnbot|Yahoo|Ask)) {
           set $testref "${testref}G";
        }
        if ($testref = IG){
           return 444;
        }
}


You can use only the first "if" part, the second is not to block Google and other image spiders. First part looks for referers from mydomain (and google, etc) and returns 444 in other cases. It can be replaced to return blank.gif image.

share|improve this answer
    
using this made all the images from my site disappear instead –  Ayaz Malik Dec 10 '10 at 13:29
    
You should change it to you domain. Also to test this, use links from pages to see images not go directly to them, because you referer will be not set correctly. –  Ross Dec 10 '10 at 13:32
    
Yes i did chagned the domain to mine. maybe im putting your code in the wrong place. can u point out where should i put it. like i said i have no idea about nginx –  Ayaz Malik Dec 10 '10 at 14:02
1  
Have a look here for examples of config files with different options like blocking images and others: calomel.org/nginx.html –  Ross Dec 10 '10 at 14:57

You can use the valid_referers option in Nginx for this. See http://www.marceleichner.de/blog/prevent-hotlinking-but-enable-facebook-and-google-image-sea/

The relevant code is:

location ~* \.(gif|jpg|jpeg|png|wmv|avi|mpg|mpeg|mp4|htm|html|js|css)$ {
  valid_referers none blocked example.org www.exampleorg ~\.google\. ~\.yahoo\. ~\.bing\. ~\.facebook\. ~\.fbcdn\.;
  if ($invalid_referer) {
    return 403;
  }

  root   /home/username/public_html;
  expires 1d;
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.