MINOR: http: implement the "http-request reject" rule

This one acts similarly to its tcp-request counterpart. It immediately
closes the request without emitting any response. It can be suitable in
certain DoS conditions, as well as to close an HTTP/2 connection.
This commit is contained in:
Willy Tarreau 2017-11-24 07:52:01 +01:00
parent f528fff46b
commit 53275e8b02
2 changed files with 47 additions and 1 deletions

View File

@ -3805,7 +3805,7 @@ http-check send-state
See also : "option httpchk", "http-check disable-on-404" See also : "option httpchk", "http-check disable-on-404"
http-request { allow | auth [realm <realm>] | redirect <rule> | http-request { allow | auth [realm <realm>] | redirect <rule> | reject |
tarpit [deny_status <status>] | deny [deny_status <status>] | tarpit [deny_status <status>] | deny [deny_status <status>] |
add-header <name> <fmt> | set-header <name> <fmt> | add-header <name> <fmt> | set-header <name> <fmt> |
capture <sample> [ len <length> | id <id> ] | capture <sample> [ len <length> | id <id> ] |
@ -3848,6 +3848,11 @@ http-request { allow | auth [realm <realm>] | redirect <rule> |
codes is limited to those that can be overridden by the "errorfile" codes is limited to those that can be overridden by the "errorfile"
directive. No further "http-request" rules are evaluated. directive. No further "http-request" rules are evaluated.
- "reject" : this stops the evaluation of the rules and immediately closes
the connection without sending any response. It acts similarly to the
"tcp-request content reject" rules. It can be useful to force an
immediate connection closure on HTTP/2 connections.
- "tarpit" : this stops the evaluation of the rules and immediately blocks - "tarpit" : this stops the evaluation of the rules and immediately blocks
the request without responding for a delay specified by "timeout tarpit" the request without responding for a delay specified by "timeout tarpit"
or "timeout connect" if the former is not set. After that delay, if the or "timeout connect" if the former is not set. After that delay, if the

View File

@ -11923,6 +11923,46 @@ enum act_parse_ret parse_http_set_status(const char **args, int *orig_arg, struc
return ACT_RET_PRS_OK; return ACT_RET_PRS_OK;
} }
/* This function executes the "reject" HTTP action. It clears the request and
* response buffer without sending any response. It can be useful as an HTTP
* alternative to the silent-drop action to defend against DoS attacks, and may
* also be used with HTTP/2 to close a connection instead of just a stream.
* The txn status is unchanged, indicating no response was sent. The termination
* flags will indicate "PR". It always returns ACT_RET_STOP.
*/
enum act_return http_action_reject(struct act_rule *rule, struct proxy *px,
struct session *sess, struct stream *s, int flags)
{
channel_abort(&s->req);
channel_abort(&s->res);
s->req.analysers = 0;
s->res.analysers = 0;
HA_ATOMIC_ADD(&s->be->be_counters.denied_req, 1);
HA_ATOMIC_ADD(&sess->fe->fe_counters.denied_req, 1);
if (sess->listener && sess->listener->counters)
HA_ATOMIC_ADD(&sess->listener->counters->denied_req, 1);
if (!(s->flags & SF_ERR_MASK))
s->flags |= SF_ERR_PRXCOND;
if (!(s->flags & SF_FINST_MASK))
s->flags |= SF_FINST_R;
return ACT_RET_CONT;
}
/* parse the "reject" action:
* This action takes no argument and returns ACT_RET_PRS_OK on success,
* ACT_RET_PRS_ERR on error.
*/
enum act_parse_ret parse_http_action_reject(const char **args, int *orig_arg, struct proxy *px,
struct act_rule *rule, char **err)
{
rule->action = ACT_CUSTOM;
rule->action_ptr = http_action_reject;
return ACT_RET_PRS_OK;
}
/* This function executes the "capture" action. It executes a fetch expression, /* This function executes the "capture" action. It executes a fetch expression,
* turns the result into a string and puts it in a capture slot. It always * turns the result into a string and puts it in a capture slot. It always
* returns 1. If an error occurs the action is cancelled, but the rule * returns 1. If an error occurs the action is cancelled, but the rule
@ -12734,6 +12774,7 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, {
struct action_kw_list http_req_actions = { struct action_kw_list http_req_actions = {
.kw = { .kw = {
{ "capture", parse_http_req_capture }, { "capture", parse_http_req_capture },
{ "reject", parse_http_action_reject },
{ "set-method", parse_set_req_line }, { "set-method", parse_set_req_line },
{ "set-path", parse_set_req_line }, { "set-path", parse_set_req_line },
{ "set-query", parse_set_req_line }, { "set-query", parse_set_req_line },