Limit_req with IP whitelisting

Hi folks,

I want to use limit_req with whitelisting some subnet, I have seen this
post: limit_req white list and
done some test but it’s not working.

I have added to server context:

geo $rate {
default 5; # 5r/s
10.0.0.0/24 -;
192.168.0.0/24 -;
10.1.0.0 -;
}

limit_req_zone $binary_remote_addr zone=ratezone:10m rate=$rate;
limit_req zone=ratezone burst=10 nodelay;

And I receive as error: nginx: [emerg] invalid rate “rate=$rate”

Any idea how to fix this issue?

  1. Is it possible to use limit_req for a single domaine “$host”?

Thanks in advance.


Matt

Posted at Nginx Forum:

Hello!

On Wed, Jul 06, 2011 at 12:27:57PM -0400, LeMaitre wrote:

Hi folks,

I want to use limit_req with whitelisting some subnet, I have seen this
post: limit_req white list and
done some test but it’s not working.

And not expected to: it’s only design idea. It wasn’t (yet?)
implemented.

limit_req zone=ratezone burst=10 nodelay;

And I receive as error: nginx: [emerg] invalid rate “rate=$rate”

Any idea how to fix this issue?

Right now you may try something like this:

geo $nolimit {
    default 0;
    10.0.0.0/24 1;
    192.168.0.0/24 1;
}

limit_req_zone $binary_remote_addr zone=ratezone:10m rate=5r/s;

server {
    ...

    location / {
        error_page 418 = @nolimit;

        if ($nolimit) {
            return 418;
        }

        limit_req zone=ratezone burst=10 nodelay;

        # ...
    }

    location @nolimit {
        # ... no limit_req here
    }
}

This will process requests in “location /” by default with
limit_req set, though users with ip addresses you specify will go
to “location @nolimit” where there are no limit_req.

  1. Is it possible to use limit_req for a single domaine “$host”?

Just define it in an appropriate server{} block.

Maxim D.

Hello Maxim,

I have tried and I got error 403.

http {

geo $nolimit {
default 0;
10.0.0.0/24 1; # my network
192.168.0/24 1; #my network
}
limit_req_zone $binary_remote_addr zone=ratezone:10m rate=5r/s;

server {
location / {
error_page 418 = @nolimit;
if ($nolimit) {
return 418;
}
limit_req zone=ratezone burst=10 nodelay;
index.html index.php;
if (!-f $request_filename) {
rewrite ^/(.*)$ /index.php last;
}
}

location @nolimit {
}

}

Is it right?

My goal is to block/reduce some DDoS without disturbing the internal
subnet network.

P.S: I’m using geoip to redirect some country to a static file but from
time to time there’s some botnet on the allowed county.

Thanks in advance

Posted at Nginx Forum:

On 6 Jul 2011 19h43 WEST, [email protected] wrote:

It seems that’s got nothing to do with Maxim’s suggestion but with
your (apparent) lack of configuration for serving PHP files. What type
of upstream are you using:

  1. Apache with mod_php?

  2. php-fpm or php-cgi?

Also your block:

if (!-f $request_filename) {
rewrite ^/(.*)$ /index.php last;
}

Is a deprecated way of routing the request. Use try_files. Also since
you’re not using the captured pattern why the capture?

See: http://wiki.nginx.org/HttpCoreModule#try_files

— appa

Thanks for your help Maxim and António. It works now.

I’ll correct the ifevil tomorrow.

Just another question, can you please tell me which value should I use
for the rate and burst?

Actually, I use:
limit_req_zone $binary_remote_addr zone=ratezone:20m
rate=30r/s;
limit_req zone=ratezone burst=100 nodelay;

There’s almost more then 20k domains behind it and a lot of connections

Thanks

Posted at Nginx Forum:

Hello!

On Wed, Jul 06, 2011 at 02:43:52PM -0400, LeMaitre wrote:

}
index.html index.php;
Just a side note: this doesn’t looks like correct config, probably
“index” directive was missed somewhere.

if (!-f $request_filename) {
rewrite ^/(.*)$ /index.php last;
}
}

location @nolimit {
}

You have to replicate your normal config in the “location
@nolimit”. Most likely you’ve got 403 due to no index defined
here.


}

Note well that if you have other locations, you may want to limit
them too (in a similar fashion).

Maxim D.