On 2017/6/28 17:40, Mark Staudinger wrote:
> Hi Patrick,
>
> Where are you using the stick table and lua script call?  Frontend or
> backend?
>
> Perhaps this would work:
>
> * In the frontend, check the connection count from the "real backend"
> stick table
> * if the count is > 6, set ACL for the source
> *Use this ACL to steer the conection to the "redirect backend" which
> will call the lua script to sleep/redirect
>
> In this way, redirected requests won't add to the backend count for
> the stick table counting such things, because they go to a different
> backend that doesn't actually talk to the resource you are protecting.
>
I think I found the solution. It's very similar to what you proposed.

frontend foofront
  http-request lua.delay_request if { src,table_conn_cur(fooback) ge 6 }
  http-request redirect prefix / code 302 if {
src,table_conn_cur(fooback) ge 6 }

backend fooback
  stick-table type ip size 10000 expire 10s peers cluster store conn_cur
  http-request track-sc1 src


I didn't see this solution at first as I didn't see the `table_conn_cur`
converter. I thought the only way to get a value from a stick table was
to track the connection.
The documentation is also a little confusing as it seems to imply it'll
use the string form of the IP address, when I expect the table stores
the binary form of the IP address. But it seems to work from my testing.


> Best,
> -Mark
>
> On Wed, 28 Jun 2017 16:56:03 -0400, Patrick Hemmer
> <hapr...@stormcloud9.net> wrote:
>
>     So as the subject indicates, I'm looking to limit concurrent
>     connections to a backend by the source IP. The behavior I'm trying
>     for is that if the client has more than 6 connections, we sit on
>     the request for a second, and then send back a 302 redirect to the
>     same resource that was just requested.
>
>     I was able to accomplish this using a stick table for tracking
>     connection count, and a Lua script for doing the sleep ("sit on
>     the request" part), but it has a significant flaw. Once the >6
>     connection limit is hit, and we start redirecting with 302, the
>     client can't leave this state. When they come back in after the
>     redirect, they'll still have >6 connections, and will hit the rate
>     limit rule again.
>
>     We instead need a way to differentiate (count) connections held
>     open and sitting in the Lua delay function, and connections being
>     processed by a server.
>
>     I'd be open to other ways of accomplishing the end goal as well.
>     We want to use the 302 redirect so the rate limit is transparent
>     to the client. And we want the delay so that the client just
>     doesn't hammer haproxy with request after request, and the browser
>     report it as a redirect loop (a brief delay will allow the
>     existing connections to finish processing so that after the 302,
>     it can be handled). And we're trying for a per-client limit (as
>     opposed to a simple "maxconn" setting and a FIFO queue) to prevent
>     a single client from monopolizing the backend resource.
>
>     -Patrick
>
>
>
>

Reply via email to