Exclude ip's from Nginx limit_req zone

Hi

I am using this code to limit connections from ip’s :

Main nginx config:

limit_conn_zone $binary_remote_addr zone=alpha:8m;
limit_req_zone $binary_remote_addr zone=delta:8m rate=40r/s;

Domain nginx conf:

limit_conn alpha 5;
limit_req zone=delta burst=80 nodelay;

So a user can create only 5 connections per ip and can have 40 requests
with
a burst up to 80 connections.

Now i want to exclude Cloudflare ip’s from this connection limits.

Any ideas how can i do it?

Thanks

Posted at Nginx Forum:

hi,

does this link helps?

cheers,

mex

Posted at Nginx Forum:

requests with a burst up to 80 connections.

Now i want to exclude Cloudflare ip’s from this connection limits.

If memory serves right you can use

 location / {
     if ($remote_addr != 1.2.3.4) {
         error_page 404 = @no_whitelist;
         return 404;
     }
     # whitelisted
 }
 location @no_whitelist {
     limit_conn  adalpha 5;
 }

@mex

Yes it seems that it will help me :slight_smile:

But on the code he is not using limit_conn_zone at all …

My code:
http{
limit_req_zone $binary_remote_addr zone=delta:8m rate=30r/s;
limit_conn_zone $binary_remote_addr zone=alpha:8m;

New code:
http{
limit_req_zone $binary_remote_addr zone=notabot:5m rate=200r/s;
limit_req zone=notabot burst=200 nodelay;

What is the difference?

Posted at Nginx Forum:

On Sat, Dec 20, 2014 at 06:18:03PM -0500, ASTRAPI wrote:

Hi there,

limit_conn_zone $binary_remote_addr zone=alpha:8m;
limit_req_zone $binary_remote_addr zone=delta:8m rate=40r/s;

limit_conn alpha 5;
limit_req zone=delta burst=80 nodelay;

Now i want to exclude Cloudflare ip’s from this connection limits.

Instead of using $binary_remote_addr, use a $new_variable which is empty
for Cloudflare IPs and equal to $binary_remote_addr for other IPs.

Ideally, something like

geo $new_variable {
default $binary_remote_addr;
# things that match cloudflare
10.0.0.0/8 “”;
}

except that “geo” does not expand $variables.

So instead, use “geo” to set a flag, and then use “map” to set the value
you want:

geo $use_new_variable {
default 1;
# things that match cloudflare
10.0.0.0/8 0;
}

map $use_new_variable $new_variable {
default $binary_remote_addr;
0 “”;
}

(Other possibilities exist.)

f

Francis D. [email protected]

I am highly suspicious about the content found at the address pointed by
the link provided by mex.
Unless I am mistaken, the variable filled by the geo module is not used
anywhere else… thus I guess the limiting works OK, but the
‘white-list’
feature probably does not work, as it was expected/advertised.
TL;DR: it probably does not work.

==========

Francis gave you an answer which is working. I will try to explain it
with
other words, hoping you will understand what to do.

The limit_* modules (req and conn) filter requests based on a variable,
which content is used as a key. If you use $binary_remote_addr there,
nginx
will keep counters per (non empty) each value of the key and limit each
of
them. In that case, each unique non-empty value is the binary IP address
of
a client.

Now, you want to exclude clients from that list, so you cannot use it
directly. The trick you can use to exclude requests from being limited
by
the limit_* module is ensuring that requests that should be unlimited
provide an empty value for the variable used by these modules.
Since you base your limit_* behavior on IP addresses, you thus need to
set
an “empty” IP address for whitelisted addresses, so they are unlimited.

How to get that filtered list? nginx’s map module allows you to fill a
variable depending on the value of another, used as a key.
That idea there is that if your key says “should not limit” (or, say,
0),
the new variable should be empty, while in all other cases the new
variable
should contain $binary_remote_addr.
That gives you the last map Francis provided:
map $should_limit $filter {
default $binary_remote_addr;
0 “”;
}
You wanna use the $filter variable on your limiter.

Now, for each request, you want to fill up this $should_limit variable
with
0 for unlimited requests and anything else (say, 1) to limit them.
That is where the geo module kicks in, where you set the default value
of
the variable it is working on with 1, and put rules matching the
white-listed IP addresses associated with the value 0.

Read the answer from Francis in the light of this attempt at explaining
it
step-by-step.
The goal of the first part of his message was to explain why this
2-steps
process is mandatory, due to limitations in the inner workings of the
geo
directive.

Hoping to have cleared things a little…

B. R.

Thanks for your replies but i am confused now :frowning:

Can anyone please try to post:

What i must add to main nginx config at:

http { ?

and what to add to the nginx domain config file at:

server { ?

Target is to have connections limit per ip 20 and requests limits per ip
to
40 and requests burst up to 80 !

Posted at Nginx Forum:

Thanks for your reply B.R

Not very clear yet as my english is not good at all :frowning:

Can you please try to post:

What i must add to main nginx config at:

http { ?

and what to add to the nginx domain config file at:

server { ?

Cloudflare ip’s that i want to exclude:

199.27.128.0/21
173.245.48.0/20
103.21.244.0/22
103.22.200.0/22
103.31.4.0/22
141.101.64.0/18
108.162.192.0/18
190.93.240.0/20
188.114.96.0/20
197.234.240.0/22
198.41.128.0/17
162.158.0.0/15
104.16.0.0/12

Posted at Nginx Forum:

Anyone please?

Posted at Nginx Forum:

Thanks for your reply Maxim D.

So something like this ? :

Main nginx conf:

http {

geo $limited {
    default           1;
    192.168.45.56/32  0;
    199.27.128.0/21  0;
    173.245.48.0/20  0;
    103.21.244.0/22  0;
    103.22.200.0/22  0;
    103.31.4.0/22  0;
    141.101.64.0/18  0;
    108.162.192.0/18  0;
    190.93.240.0/20  0;
    188.114.96.0/20  0;
    197.234.240.0/22  0;
    198.41.128.0/17  0;
    162.158.0.0/15  0;
    104.16.0.0/12  0;
}

map $limited $limit {
    1        $binary_remote_addr;
    0        "";
}

And this on the domain config? :

server {

limit_req_zone $limit zone=foo:1m rate=10r/m;
limit_req zone=foo burst=5;

Posted at Nginx Forum:

Hello!

On Wed, Dec 24, 2014 at 02:36:50PM -0500, ASTRAPI wrote:

    192.168.45.56/32  0;
    198.41.128.0/17  0;

And this on the domain config? :

server {

limit_req_zone $limit zone=foo:1m rate=10r/m;
limit_req zone=foo burst=5;

The limit_req_zone can be used only at http{} level, so you’ll
have to move it to http{} block, see here for docs:

http://nginx.org/r/limit_req_zone

The limit_req directive can be used at http, server, or location
level. It’s up to your specific setup requirements where to use
it. In many cases it’s good idea to protect only expensive
resources like proxying to backends.


Maxim D.
http://nginx.org/

My english is not so good and sometimes is hard for me sorry :frowning:

So as the goal is to limit globaly the maximum connections from one ip
to 15
and to have 40 requests per ip and burst up to 80 requests per second it
should be like this?

Main nginx conf:

http {
limit_req_zone $limit zone=foo:1m rate=40r/s;

geo $limited {
default 1;
192.168.45.56/32 0;
199.27.128.0/21 0;
173.245.48.0/20 0;
103.21.244.0/22 0;
103.22.200.0/22 0;
103.31.4.0/22 0;
141.101.64.0/18 0;
108.162.192.0/18 0;
190.93.240.0/20 0;
188.114.96.0/20 0;
197.234.240.0/22 0;
198.41.128.0/17 0;
162.158.0.0/15 0;
104.16.0.0/12 0;
}

map $limited $limit {
1 $binary_remote_addr;
0 “”;
}

And on domain conf:

server {
limit_req zone=foo burst=80;

If not can you please post a configuration that will do that?

Thanks

Posted at Nginx Forum:

Anyone please?

Posted at Nginx Forum:

Hello!

On Wed, Dec 24, 2014 at 09:01:09AM -0500, ASTRAPI wrote:

Anyone please?

An example of how to whitelist addresses from limit_req can be
found in the mailing list archives, for example here:

http://mailman.nginx.org/pipermail/nginx/2012-July/034790.html

Documentation on directives used can be found here:

http://nginx.org/en/docs/http/ngx_http_geo_module.html
http://nginx.org/en/docs/http/ngx_http_map_module.html
http://nginx.org/en/docs/http/ngx_http_limit_req_module.html


Maxim D.
http://nginx.org/

Ok all done fixed !

Thanks :slight_smile:

Posted at Nginx Forum: