Forum: NGINX Using http_limit_conn with a custom variable

Da41894a3b7f4d5bb5e25aad4944b4be?d=identicon&s=25 Kevin Burke (Guest)
on 2013-05-21 21:32
(Received via mailing list)
We're trying to use the limit_conn_zone directive to throttle incoming
HTTP requests.

We'd like to throttle based on the http basic auth variable
($remote_user), however, we must do processing on this value so the
zone does not overflow with illegitimate values. Ideally we'd want to
do something like

set $safe_remote_user "";
content_by_lua '
-- Some code to filter $remote_user values, simplified to one line here
ngx.var.safe_remote_user = $remote_user
limit_conn_zone $safe_remote_user zone:user 10m;

However this runs into a problem that we can only set variables inside
of the location context, but limit_conn_zone must be defined in the
http context. So, as we understand it we cannot use a variable defined
by lua in the limit_conn_zone directive. We were curious if anyone has
run into this problem, and if there are workarounds that could help us
solve this problem.


Kevin Burke | 415-723-4116 |
A8108a0961c6087c43cda32c8616dcba?d=identicon&s=25 Maxim Dounin (Guest)
on 2013-05-22 15:59
(Received via mailing list)

On Tue, May 21, 2013 at 12:31:05PM -0700, Kevin Burke wrote:

> content_by_lua '
> solve this problem.
For variables processing independant on a particular request
handling point there is the map{} and perl_set directives in
nginx (see,

Not sure if there is something similar in lua module, but map
should be enough for a particula task.

With map you may do something like this:

    map $remote_user $limit {
        default      invalid;
        ~^[a-z0-9]+$ $remote_user;

This way only valid (according to a regex) user names are mapped
to their own limits, while everything else maps to predefined
value "invalid".

Maxim Dounin
Da41894a3b7f4d5bb5e25aad4944b4be?d=identicon&s=25 Kevin Burke (Guest)
on 2013-05-22 16:36
(Received via mailing list)
Ah, thanks, map{} is probably the best solution. We got it "working" by
using rewrite_by_lua_file, which let us set new headers:

    # Set an HTTP header that is read by conn_zone
    rewrite_by_lua_file user.lua;

    limit_conn_zone $http_user_binary ...;

Then in the lua file, add something like:

    ngx.set_header('User-Binary', ngx.md5_bin($remote_user));

This is almost certainly not an ideal thing to do, we'll look to rewrite
using map.


Kevin Burke | 415-723-4116 |
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.