Re: Updating a stick table from the HTTP response

2015-06-30 Thread bjun...@gmail.com
Hi Holger,


"tcp-response content track- / http-response track-" would be a nice
feature, don't know if this is on the roadmap.


For the moment i can only imagine the following (needs HAProxy 1.6):


http-response lua script.lua


Within this Lua function, you check the http response code and
update/set a stick-table entry per haproxy socket ("set table ...").

(I don't know if there is a native lua function for this case (without
using the socket))


I didn't say it's an elegant solution ...  :)


---
Best Regards / Mit freundlichen Grüßen

Bjoern

2015-06-30 12:37 GMT+02:00 Holger Just :
> Hello all,
>
> Unfortunately, I have not received any feedback on my earlier email so
> I'll try again.
>
> I am still struggling trying to implement a throttling mechanism based
> on prior HTTP responses of the same client.
>
> Basically, I have some requests (using Basic Auth or other mechanisms)
> that might result in HTTP 401 responses from the backend server. I want
> to throttle further requests by the same client if the number of such
> responses reaches a certain threshold (responses / second). In that
> case, I want to first delay and finally block new requests completely
> until the error rate goes down.
>
> In order to implement this, it would be great if we would have the
> possibility to update stick entries based on the response and not only
> the request, e.g.
>
> tcp-response content track-sc2 src if { status 401 }
>
> Is something like this feasible, maybe under the restriction that the
> user has to make sure on their own that the data required to update the
> stick table entry is still available?
>
> Thank you for your feedback.
>
> --Holger
>
>
> Holger Just wrote:
>> Hello all,
>>
>> with HAProxy 1.5.11, we have implemented rate limiting based on some
>> aspects of the request (Host header, path, ...). In our implementation,
>> we delay limited requests by forcing a WAIT_END in order to prevent
>> brute-force attacks against e.g. passwords or login tokens:
>>
>>
>> acl bruteforce_slowdown sc2_http_req_rate gt 20
>> acl limited_path path_beg /sensitive/stuff
>>
>> stick-table type ip size 100k expire 30m store http_req_rate(300s)
>> tcp-request content track-sc2 src if METH_POST limited_path
>>
>> # Delay the request for 10 seconds if we have too many requests
>> tcp-request inspect-delay 10s
>> tcp-request content accept unless bruteforce_slowdown limited_path
>> tcp-request content accept if WAIT_END
>>
>>
>> As you can see above, we track only certain requests to sensitive
>> resources and delay further requests after 20 req / 300 s without taking
>> the actual response into account. This is good enough for e.g. a web
>> form to login or change a password.
>>
>> Now, unfortunately we have some endpoints which are protected with Basic
>> Auth which is validated by the application. If the password is
>> incorrect, we return an HTTP 401.
>>
>> In order to prevent brute-forcing of passwords against these endpoints,
>> we would like to employ a similar delay mechanism. Unfortunately, we
>> can't detect from the request headers alone if we have a bad request but
>> have to inspect the response and increase the sc2 counter only of we
>> have seen a 401.
>>
>> In the end, I would like to use a fetch similar to sc1_http_err_rate but
>> reduced to only specific cases, i.e. 401 responses on certain paths or
>> Host names.
>>
>> Now the problem is that we apparently can't manipulate the stick table
>> from a HTTP response, or more precisely: I have not found a way to do it.
>>
>> We would like to do something like
>>
>>
>> tcp-response content track-sc2 src if { status 401 }
>>
>>
>> which would allow us to track these error-responses similar to the first
>> approach and handle the next requests the same way as above.
>>
>> Now my questions are:
>>
>> * Is something like this possible/feasible right now?
>> * Is there some other way to implement rate limiting based on certain
>>   server responses?
>> * If this is not possible right now, would it be feasible to implement
>>   the possibility to track responses similar to what is possible with
>>   requests right now?
>>
>> Thank you for your feedback,
>> Holger Just
>>
>



Re: Updating a stick table from the HTTP response

2015-06-30 Thread Holger Just
Hello all,

Unfortunately, I have not received any feedback on my earlier email so
I'll try again.

I am still struggling trying to implement a throttling mechanism based
on prior HTTP responses of the same client.

Basically, I have some requests (using Basic Auth or other mechanisms)
that might result in HTTP 401 responses from the backend server. I want
to throttle further requests by the same client if the number of such
responses reaches a certain threshold (responses / second). In that
case, I want to first delay and finally block new requests completely
until the error rate goes down.

In order to implement this, it would be great if we would have the
possibility to update stick entries based on the response and not only
the request, e.g.

tcp-response content track-sc2 src if { status 401 }

Is something like this feasible, maybe under the restriction that the
user has to make sure on their own that the data required to update the
stick table entry is still available?

Thank you for your feedback.

--Holger


Holger Just wrote:
> Hello all,
> 
> with HAProxy 1.5.11, we have implemented rate limiting based on some
> aspects of the request (Host header, path, ...). In our implementation,
> we delay limited requests by forcing a WAIT_END in order to prevent
> brute-force attacks against e.g. passwords or login tokens:
> 
> 
> acl bruteforce_slowdown sc2_http_req_rate gt 20
> acl limited_path path_beg /sensitive/stuff
> 
> stick-table type ip size 100k expire 30m store http_req_rate(300s)
> tcp-request content track-sc2 src if METH_POST limited_path
> 
> # Delay the request for 10 seconds if we have too many requests
> tcp-request inspect-delay 10s
> tcp-request content accept unless bruteforce_slowdown limited_path
> tcp-request content accept if WAIT_END
> 
> 
> As you can see above, we track only certain requests to sensitive
> resources and delay further requests after 20 req / 300 s without taking
> the actual response into account. This is good enough for e.g. a web
> form to login or change a password.
> 
> Now, unfortunately we have some endpoints which are protected with Basic
> Auth which is validated by the application. If the password is
> incorrect, we return an HTTP 401.
> 
> In order to prevent brute-forcing of passwords against these endpoints,
> we would like to employ a similar delay mechanism. Unfortunately, we
> can't detect from the request headers alone if we have a bad request but
> have to inspect the response and increase the sc2 counter only of we
> have seen a 401.
> 
> In the end, I would like to use a fetch similar to sc1_http_err_rate but
> reduced to only specific cases, i.e. 401 responses on certain paths or
> Host names.
> 
> Now the problem is that we apparently can't manipulate the stick table
> from a HTTP response, or more precisely: I have not found a way to do it.
> 
> We would like to do something like
> 
> 
> tcp-response content track-sc2 src if { status 401 }
> 
> 
> which would allow us to track these error-responses similar to the first
> approach and handle the next requests the same way as above.
> 
> Now my questions are:
> 
> * Is something like this possible/feasible right now?
> * Is there some other way to implement rate limiting based on certain
>   server responses?
> * If this is not possible right now, would it be feasible to implement
>   the possibility to track responses similar to what is possible with
>   requests right now?
> 
> Thank you for your feedback,
> Holger Just
> 



Updating a stick table from the HTTP response

2015-04-29 Thread Holger Just
Hello all,

with HAProxy 1.5.11, we have implemented rate limiting based on some
aspects of the request (Host header, path, ...). In our implementation,
we delay limited requests by forcing a WAIT_END in order to prevent
brute-force attacks against e.g. passwords or login tokens:


acl bruteforce_slowdown sc2_http_req_rate gt 20
acl limited_path path_beg /sensitive/stuff

stick-table type ip size 100k expire 30m store http_req_rate(300s)
tcp-request content track-sc2 src if METH_POST limited_path

# Delay the request for 10 seconds if we have too many requests
tcp-request inspect-delay 10s
tcp-request content accept unless bruteforce_slowdown limited_path
tcp-request content accept if WAIT_END


As you can see above, we track only certain requests to sensitive
resources and delay further requests after 20 req / 300 s without taking
the actual response into account. This is good enough for e.g. a web
form to login or change a password.

Now, unfortunately we have some endpoints which are protected with Basic
Auth which is validated by the application. If the password is
incorrect, we return an HTTP 401.

In order to prevent brute-forcing of passwords against these endpoints,
we would like to employ a similar delay mechanism. Unfortunately, we
can't detect from the request headers alone if we have a bad request but
have to inspect the response and increase the sc2 counter only of we
have seen a 401.

In the end, I would like to use a fetch similar to sc1_http_err_rate but
reduced to only specific cases, i.e. 401 responses on certain paths or
Host names.

Now the problem is that we apparently can't manipulate the stick table
from a HTTP response, or more precisely: I have not found a way to do it.

We would like to do something like


tcp-request content track-sc2 src if { status 401 }


which would allow us to track these error-responses similar to the first
approach and handle the next requests the same way as above.

Now my questions are:

* Is something like this possible/feasible right now?
* Is there some other way to implement rate limiting based on certain
  server responses?
* If this is not possible right now, would it be feasible to implement
  the possibility to track responses similar to what is possible with
  requests right now?

Thank you for your feedback,
Holger Just