[nginx] allowing auth_request to proxy TOO_MANY_REQUESTS

Anders Nicolaisen alvn at alvn.dk
Fri Oct 21 12:12:48 UTC 2022


This works!

Although this still requires an extra line for each new location,
which might be forgotten by a collaborator, but this configuration
is definitely viable.

Thanks a lot!


On Wed, 12 Oct 2022 at 15:44, Maxim Dounin <mdounin at mdounin.ru> wrote:

> Hello!
>
> On Wed, Oct 12, 2022 at 11:04:50AM +0200, Anders Nicolaisen via
> nginx-devel wrote:
>
> > Thanks!
> > This does make sense, and one might be able to create a somewhat working
> > example using this.
> >
> > However, this seems to introduce a couple of drawbacks, and kind of
> > breaks the semantics of the 'auth_request'.
> >
> > Let me illustrate:
> >
> > First of all, having auth_request in the server context guards against
> > any newly added locations that might yet be missing rules handled
> > by the authentication server.
> > So, whenever a new location is added, the authentication server needs
> > to be updated as well before any requests can be redirected.
> > This will most often actually be a good thing in an environment with
> > a lot of rules and multiple developers.
> >
> > Second, if multiple developers are editing the configurations, they are
> > not required to remember the 'internal' in order to bar these from
> > outsiders,
> > as this would be automatically imposed via auth_request.
> >
> > It seems to be more in line with the current semantics of auth_request,
> > and also by far cleaner code/configurations, by having auth_request be
> > able to relay this one more status code.
>
> Sure, details of the X-Accel-Redirect semantics is different from
> the one provided by auth_request.
>
> If you prefer auth_request semantics, you can do the same with
> auth_request and appropriate handling of the 403 errors, for
> example (assuming the auth backend cannot be modified and returns
> 429):
>
> server {
>    listen 8080;
>
>    location / {
>        auth_request /auth;
>        error_page 403 = /error;
>        proxy_pass ...
>    }
>
>    location = /auth {
>        error_page 429 = /limit;
>        proxy_intercept_errors on;
>        proxy_pass http://127.0.0.1:8081;
>    }
>
>    location = /limit {
>        set $limit 1;
>        return 403;
>    }
>
>    location = /error {
>        if ($limit) {
>            return 429;
>        }
>        return 403;
>    }
> }
>
> server {
>    listen 8081;
>
>    # an example X-Accel-Redirect server
>    # which rejects requests with 'foo' header set to a true
>    # value
>
>    if ($http_foo) {
>        return 429;
>    }
>
>    return 204;
> }
>
> The general issue with "having auth_request be able to relay this
> one more status code" as I see it is that it's not just one status
> code.  For example, request limiting in nginx by default uses 503
> status code, and it is not clear why 429 handling should be
> different.  Further, there is the Retry-After header field, which
> is optional, though may appear in both 429 and 503 responses.
> Further, there are other temporary conditions which might be
> considered, such as 413 (with Retry-After) or 502/504 errors.
> Trying to extend auth_reqest to handle unrelated response codes is
> going to result in a lot of additional logic there, which is not
> needed in most configurations and will complicate things.  And
> this is something I would prefer to avoid, especially given that
> the desired handling can be easily implemented simply by writing
> an appropriate configuration.
>
> > P.S.:
> > I tried to test your suggestion with this simple conf:
> > -----
> > server {
> >
> >   location / {
> >     proxy_pass http://localhost:8888/auth;
> >   }
> >   location @content {
> >     proxy_pass http://localhost:8888/;
> >   }
> > }
> > ----
> >
> > And got this error:
> >
> > ===
> > 2022/10/12 08:51:09 [emerg] 1451#1451: "proxy_pass" cannot have URI part
> in
> > location given by regular expression, or inside named location, or inside
> > "if" statement, or inside "limit_except" block
> > ===
> >
> > I'm guessing I just did something wrong, but the error message seems to
> > tell me that it is
> > not possible to do it this way.
>
> In named locations there are no location prefix to replace with
> the URI part specified in proxy_pass, so you should use proxy_pass
> without URI part, that is, "proxy_pass http://localhost:8888;",
> note no "/" at the end.
>
> See here for details:
>
> http://nginx.org/r/proxy_pass
>
> Hope this helps.
>
> --
> Maxim Dounin
> http://mdounin.ru/
> _______________________________________________
> nginx-devel mailing list -- nginx-devel at nginx.org
> To unsubscribe send an email to nginx-devel-leave at nginx.org
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20221021/2cf3cc07/attachment.htm>


More information about the nginx-devel mailing list