34

I run quite a big image gallery and there are 5 visitors that create an enormous amount of traffic by downloading the whole site every day using webcopiers. Those visitors have static IPs as it seems. What I would like to achieve is that those 5 IPs get redirected to a certain page (which explains why their behavior is problematic) as soon as they visit the site. All other visitors should be able to browse the site normally.

The server is running CentOS (5.8) and nginx (1.0.15) as webserver. Is there any way to achieve this by an entry in nginx.conf that you are aware of?

Thank you very much in advance for your hints and support!

Kind regards -Alex

Alex
  • 341
  • 1
  • 3
  • 6

3 Answers3

51

The Geo module is made to match client addresses. You can use it to define a variable to test like so:

geo $bad_user {
  default 0;
  1.2.3.4/32 1;
  4.3.2.1/32 1;
}

server {
  if ($bad_user) {
    rewrite ^ http://www.example.com/noscrape.html;
  }
}

This is more efficient than running a regex against $remote_addr, and easier to maintain.

kolbyjack
  • 7,854
  • 2
  • 34
  • 29
  • Thank you very much - it works great using geo! Just one thing: It only redirects requests to domain.com and not direct requests like domain.com/file.ext or domain.com/subdirectory/file.ext. How do I achieve this? Unfortunately, I am quite a RegEx Noob. :( – Alex Apr 18 '12 at 21:33
  • Where did you put the if? Can you provide the entire server block? After some more thought, putting the if directly in the server isn't the best idea, since it will be evaluated even for a request to /noscrape.html – kolbyjack Apr 18 '12 at 23:44
24

Using HttpAccessModule you will make this happen quickly.

server {
    if ($remote_addr = 1.2.3.4) {
        rewrite ^ http://www.website.com/noscrape.htm;
    }
   ...
}
Khaled
  • 35,688
  • 8
  • 69
  • 98
  • Thank you very much, Khaled! Is there a way to include several IPs into that directive? – Alex Apr 18 '12 at 12:58
  • Sorry, I am a bit confused (new here) - Did Matt answer the question or Khaled? However, thanks to both of you! ;) – Alex Apr 18 '12 at 13:17
  • 2
    This actually uses the [Rewrite module](http://wiki.nginx.org/HttpRewriteModule). You can use a regular expression match like this: `if ($remote_addr ~ "^(1.2.3.4|4.3.2.1)$")`. – mgorven Apr 18 '12 at 17:32
  • My `nginx -V` says that there is no such a module, but it works. Maybe it is builtin for now. – user3132194 Nov 13 '15 at 06:16
4

If you redirected to a different page in the same domain, and if you followed above examples it will cause to a redirect loop. so in your nginx configuration file, use as following ( I assume you use wordpress as it's widely used)

geo $bad_user {
  default 0;
  1.2.3.4/32 1;
  4.3.2.1/32 1;
}

server {
 location /
 {
  if ($bad_user) {
    rewrite ^ http://www.example.com/warning-page/ break;
  }

try_files $uri $uri/ /index.php$is_args$args;
 }

location /warning-page/
{
try_files $uri $uri/ /index.php$is_args$args;
}
  
}

Now if someone from the blacklisted ip visited any page except warning-page which is unlisted in the site, they will be redirected to the warning page. since the rewrite is in the location / block, it won't cause a redirect loop. However, if it's inside of the server block, then it will cause a redirect loop.

Don Dilanga
  • 232
  • 2
  • 8