Forum: NGINX Using http_limit_conn with a custom variable

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
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 |
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
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 |
This topic is locked and can not be replied to.