0

I'm trying to implement download hotlinking protection.

I've this code

    location /download/ {
      valid_referers  blocked  server_names  *.example.com;

      if ($invalid_referer) {
        return   403;
      }

Working fine, this allow specify domain and block whatever is not in valid_referers, What is the problem? i want to implement a specify IP allowed to use not referer and rest block it.

This is what log shows.

1.2.3.4 - - - "GET file.doc HTTP/2.0" 200 13050 "-" "-"

I want only 1.2.3.4 accept none referer.

Tero Kilkanen
  • 36,796
  • 3
  • 41
  • 63
Kurogane
  • 3
  • 1
  • 4

2 Answers2

1

For hotlinking prevention, it is good enough to allow empty referrer strings (direct downloads). Therefore your config could look like this:

valid_referers none blocked server_names *.example.com;

Browsers always add the Referer header to the image requests when they load images embedded in the web pages.

If you really want to block direct downloads of images, then you need to use something like this in the http level of nginx configuration:

geo $blocked {
    default 1;
    1.2.3.4 0;
}

And then in server block:

location /download/ {
    valid_referers  blocked  server_names  *.example.com;

    set $refblocked $invalid_referer$blocked;

    if ($refblocked = "11") { # If value of both $invalid_referer and $blocked are 1, block access.
        return 403;
    }
}

Here, the geo module is used to map IP address to a variable value, and set is used to combine $invalid_referer and $blocked into a single variable, which is tested within if statement.

I haven't tested this exact configuration myself, but the principle should work.

Tero Kilkanen
  • 36,796
  • 3
  • 41
  • 63
  • Thanks, i not test it but before i not understand this part. $refblocked = "11" and $refblocked = "1", what is 11 and 1? i suppose 1 blocked by default if is 0 then allowed – Kurogane Jun 12 '20 at 06:50
  • `$refblocked` is set to combination of values of `$invalid_referer` and `$blocked`. Then, with `if` we test if the value of both variables is such that the connection should be blocked. According to nginx documentation, `$invalid_referer` is an empty string when request should be allowed and `1` when request should be blocked. Actually my example was wrong, I updated it. – Tero Kilkanen Jun 12 '20 at 07:12
0

This should also work:

geo $hotlink {
    default $invalid_referer;
    1.2.3.4 0;
}
location /download/ {
    valid_referers  blocked  server_names  *.example.com;
    if ($hotlink) {
       return 403;
    }
}