Return a static page for specific users/IPs

Why do I want to do that?
Different reasons. One time, because I wanted a certain user not to access the dynamic WordPress site. Another time, I wanted to provide a bot that has been crawling the site with a “legitimate” page, without actually allowing it to go through the site. The main thing I was looking for is a way to do an internal redirect, so no 3xx code returned. I know there are probably better ways to achieve these goals (are there?). But hey, I learned some stuff about Nginx while doing this.

So here it goes, the first attempt:

  location ~* /some/path/with_numbers/\d+ {
    if ($remote_addr = 11.11.111.1) {
       return 200 "sample reply - should be empty";
    }
    # the next line is reached only when the above is not executed
    try_files $uri $uri/ /index.php$is_args$args;
  }

One problem with the above is that replacing the IP or adding more IPs is a bit problematic. So, we replace it with the following that relies on the Geo module:

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

server {
[...]
 location ~* /some/path/with_numbers/\d+ {
    if ($bad_ip) {
       return 200 "sample reply - should be empty";
    }
    # the next line is reached only when the above is not executed
    try_files $uri $uri/ /index.php$is_args$args;
  }

The other problem is that the text returned with the 200 code is a bit simplistic and I really wanted to send an HTML static page, not a stupid line. The fix uses error_page


[...]
 location ~* /some/path/with_numbers/\d+ {
    if ($bad_ip) { return 410; }
    error_page 410 =200 /my_static_page.html;
    # the next line is reached only when the above is not executed
    try_files $uri $uri/ /index.php$is_args$args;
  }

The result is a 200 (OK) code sent to the browser with a static HTML page that should load much faster than a PHP/RoR/etc alternative.

Of course, more can be done to identify the blocked entity, for example using UserAgent string, etc.
Leaving that for another day.

Similar Posts:




No Comments


You can leave the first : )



Leave a Reply

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