Zak
Zak

Reputation: 2058

NGINX enable rate limiting only on successful requests

Is there are a way to enable rate limiting only for successful requests (i.e. HTTP status code 200)?

For example, in the following snippet from my configuration...

http {
    limit_req_zone $binary_remote_addr zone=test:10m rate=2r/m;

    server {
        location / {
             limit_req zone=test;
             proxy_pass http://localhost:3000/;
             ...
        }

        ...
    }

    ...
}

...requests are successfully rate limited (up to two requests per minute).

However, as this is for a contact form which sends me emails, I do not care about rate limiting if http://localhost:3000/ returns an error as no email will have been sent.

Upvotes: 2

Views: 2140

Answers (2)

Dog
Dog

Reputation: 115

The currently accepted answer is not exactly correct. You can actually do (kinda) it.

Note, try_files is needed instead of return, due to return's short circuiting behavior.


proxy_intercept_errors on;

# repeat as needed
error_page <code> = @nein_<code>;
location @nein_<code> {
  internal  ;
  limit_req zone=<zone>;
  try_files /dev/null =<code>;
}


Note: this only takes effect AFTER failed auth, so you have to play around with burst limit to delay the next requests. Im not even sure if its possible to secure things this way against brute force attacks.

Upvotes: 0

Larry.He
Larry.He

Reputation: 634

No, there isn't.

Nginx processes HTTP request in 11 phases from reading request to sending reponse: post-read, server-rewrite, find-config, rewrite, post-rewrite, pre-access, access, post-access, try-files, content, log.

proxy_pass is in content phase while limit_req is in pre-access phase (refer ngx_http_limit_req_module.c), pre-access phase handlers is executed before content phase handlers, so limit_req handler can not check if the response code is OK.

Upvotes: 5

Related Questions