nginx (2)


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:




Django uWSGI and Nginx on Ubuntu 11.10

I’m working my way through installing my simple django app on a new Ubuntu machine using the components mentioned above.

So far, here’s what I’ve done:

  • apt-get install nginx-full
  • apt-get install uwsgi uwsgi-plugin-python
  • installed django from svn described in the docs

The nginx configuration can be found in /etc/nginx/sites-available/default. Of course, it’s best to make a copy of that file and edit it for the site/app I’m working on. Here’s what I put in it:

server {
    listen   80;
    server_name sss.grat.in;
    access_log /var/log/nginx/sss.grat.in-access.log;
    location /media {
        alias /home/sss/app/media/;
    }
    location /static {
        alias /home/sss/app/static/;
    }
    location / {
        uwsgi_pass unix:///var/run/sss.grat.in.sock;
        include uwsgi_params;
    }
}

Now for the uWSGI configuration file. I created the file /etc/uwsgi/apps-available/sss.ini and added the following lines:

[uwsgi]
chdir = /home/sss/app
pythonpath = /home/sss
env = DJANGO_SETTINGS_MODULE=app.settings
# load django
module = django.core.handlers.wsgi:WSGIHandler()

it’s really just that. What took me so long was to figure out that in Debian/Ubuntu you have to install uwsgi-plugin-python, otherwise you’ll keep on getting weird error messages. Also, the default ini file has most of the settings (in /etc/default/uwsgi) so you should either read or edit that to make sure you’re getting all the right values.

Similar Posts: