[MINOR] acl: add 2 new verbs: fe_sess_rate and be_sess_rate

These new ACLs match frontend session rate and backend session rate.
Examples are provided in the doc to explain how to use that in order
to limit abuse of service.
This commit is contained in:
Willy Tarreau 2009-03-05 21:34:28 +01:00
parent 3a8efeb46d
commit 079ff0a207
2 changed files with 78 additions and 0 deletions

View File

@ -4070,6 +4070,44 @@ connslots(backend) <integer>
dynamic connections. Also, if any of the server maxconn, or maxqueue is 0, then
this acl clearly does not make sense - in which case the value returned will be -1.
fe_sess_rate <integer>
fe_sess_rate(frontend) <integer>
Returns true when the session creation rate on the current or the named
frontend matches the specified values or ranges, expressed in new sessions
per second. This is used to limit the connection rate to acceptable ranges in
order to prevent abuse of service at the earliest moment. This can be
combined with layer 4 ACLs in order to force the clients to wait a bit for
the rate to go down below the limit.
Example :
# This frontend limits incoming mails to 10/s with a max of 100
# concurrent connections. We accept any connection below 10/s, and
# force excess clients to wait for 100 ms. Since clients are limited to
# 100 max, there cannot be more than 10 incoming mails per second.
frontend mail
bind :25
mode tcp
maxconn 100
acl too_fast fe_sess_rate ge 10
tcp-request inspect-delay 100ms
tcp-request content accept if ! too_fast
tcp-request content accept if WAIT_END
be_sess_rate <integer>
be_sess_rate(backend) <integer>
Returns true when the sessions creation rate on the backend matches the
specified values or ranges, in number of new sessions per second. This is
used to switch to an alternate backend when an expensive or fragile one
reaches too high a session rate, or to limite abuse of service (eg. prevent
sucking of an online dictionary).
Example :
# Redirect to an error page if the dictionary is requested too often
backend dynamic
mode http
acl being_scanned be_sess_rate gt 100
redirect location /denied.html if being_scanned
2.3.5.2) Matching contents at Layer 4
-------------------------------------

View File

@ -2096,11 +2096,51 @@ acl_fetch_connslots(struct proxy *px, struct session *l4, void *l7, int dir,
return 1;
}
/* set test->i to the number of connections per second reaching the frontend */
static int
acl_fetch_fe_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
test->flags = ACL_TEST_F_VOL_TEST;
if (expr->arg_len) {
/* another proxy was designated, we must look for it */
for (px = proxy; px; px = px->next)
if ((px->cap & PR_CAP_FE) && !strcmp(px->id, expr->arg.str))
break;
}
if (!px)
return 0;
test->i = read_freq_ctr(&px->fe_sess_per_sec);
return 1;
}
/* set test->i to the number of connections per second reaching the backend */
static int
acl_fetch_be_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
test->flags = ACL_TEST_F_VOL_TEST;
if (expr->arg_len) {
/* another proxy was designated, we must look for it */
for (px = proxy; px; px = px->next)
if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->arg.str))
break;
}
if (!px)
return 0;
test->i = read_freq_ctr(&px->be_sess_per_sec);
return 1;
}
/* Note: must not be declared <const> as its list will be overwritten */
static struct acl_kw_list acl_kws = {{ },{
{ "nbsrv", acl_parse_int, acl_fetch_nbsrv, acl_match_int, ACL_USE_NOTHING },
{ "connslots", acl_parse_int, acl_fetch_connslots, acl_match_int, ACL_USE_NOTHING },
{ "fe_sess_rate", acl_parse_int, acl_fetch_fe_sess_rate, acl_match_int, ACL_USE_NOTHING },
{ "be_sess_rate", acl_parse_int, acl_fetch_be_sess_rate, acl_match_int, ACL_USE_NOTHING },
{ NULL, NULL, NULL, NULL },
}};