Using http_limit_conn with a custom variable

Hi,
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.

Thanks,
Kevin


Kevin Burke | 415-723-4116 | www.twilio.com

Hello!

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 Module ngx_http_map_module, Module ngx_http_perl_module).

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 D.
http://nginx.org/en/donation.html

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
it
using map.

Thanks,
Kevin


Kevin Burke | 415-723-4116 | www.twilio.com