how to prevent image hotlinking in nginx?

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/da.jpg

now i want to block access to them but I cannot implement hotlink prevention in my nginx.conf file. Below is my nginx.conf file where should I place the code?

Hotlink code to be implemented:

  location ~ \.(jpe?g|png|gif)$ {
    valid_referers none blocked example.com *.example.com;
    if ($invalid_referer) {
        return 403;
    }
}  

My current code is below

{

#user  nobody;
worker_processes  10;
worker_rlimit_nofile 81918;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  81918;
    multi_accept on;
}


http {


    client_body_buffer_size 10K;
    client_header_buffer_size 1k;
    client_max_body_size 8m;
    large_client_header_buffers 2 1k;

    client_body_timeout   32;
    client_header_timeout 32;
    sendfile_max_chunk 512k;
    keepalive_timeout 5; # default 65
    send_timeout 20;     # default 60

    reset_timedout_connection on;

    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  5;
    #keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }


        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    server {
        listen       *:80;
            server_name  dl.rahim-soft.org;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
        location / {
            root   E:/WWW;
            index  index.html index.htm;

        }
    }
    server {
        listen       *:80;
        server_name  dl1.rahim-soft.org;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   E:/dl1;
            index  index.html index.htm;
        }
    }
    server {
        listen       *:80;
        server_name  dl2.rahim-soft.org;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   F:/dl2.rahim-soft.org;
            index  index.html index.htm;
        }

    }

}

Solution 1:

Perhaps your images need a root location too.

server {
  listen       *:80;
  server_name  dl2.rahim-soft.org;

  location / {
    location ~* \.(jpe?g|png|gif)$ {
      valid_referers none blocked rahim-soft.org *.rahim-soft.org;
      if ($invalid_referer) {
        return 403;
      }
    }  

    root   F:/dl2.rahim-soft.org;
    index  index.html index.htm;
  }
} 

Solution 2:

You need to cut & paste that snippet of config inside every server { } stanza, e.g. for dl2.rahim-soft.org:

server {
    listen       *:80;
    server_name  dl2.rahim-soft.org;

    location ~ \.(jpe?g|png|gif)$ {
        root   F:/dl2.rahim-soft.org;
        valid_referers none blocked rahim-soft.org *.rahim-soft.org;
        if ($invalid_referer) {
            return 403;
        }
    }  
    location / {
        root   F:/dl2.rahim-soft.org;
        index  index.html index.htm;
    }
} 

Nginx will serve regular expression matches in preference to prefix matches. However, it evaluates prefix locations first, allowing for the admin to override this by specifying locations using the = and ^~ modifiers.

While prefix locations generally select based on the longest, most specific match, regular expression evaluation is stopped when the first matching location is found.

To better understand how nginx prioritizes location matching, you might want to read this excellent article by digitalocean:

https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms#matching-location-blocks