Hello,
On Fri, Jun 24, James Brown wrote:
> +1 I am also using a fake backend with no servers and a 503 errorfile, and
> it confuses everybody who looks at the config or the metrics. Being able to
> directly emit a 429 would be fantastic.
This is my first attempt in adding deny_status to:
http-request tarpit [deny_status <status>]
First patch updates parse_http_req_cond so config parser accepts
[deny_status <status>] for http-request tarpit (and sets
rule->deny_status).
The second patch updates http_process_req_common/http_process_tarpit to
use deny_status. http_process_tarpit has a switch statement for mapping
txn->status (200<->504) to HTTP_ERR_<num>(enum). Is this reasonable ?
Do tarpitted (http-request tarpit / req(i)tarpit) requests always
go thru http_process_req_common (so txn->status is always set to
txn->status = http_err_codes[deny_status]) ?
Or is there a possibility that int deny_status could be overwritten
in http_process_req_common (with multiple deny/block/tarpit rules) ?
Both patches are against 1.7.1, but if this looks otherwise ok then
I can modify the patches against 1.8dev and add missing documentation.
I've used this minimal config for testing:
(missing defaults/global):
frontend test
bind [email protected]:8080
http-request tarpit deny_status 429 if TRUE
default_backend test_be
frontend test2
bind [email protected]:8081
http-request tarpit if TRUE
default_backend test_be
frontend test3
bind [email protected]:8082
reqtarpit . if TRUE
default_backend test_be
backend test_be
server dummy 127.0.0.1:80 id 1
curl -v http://127.0.0.1:8080 should be tarpitted with status 429
and curl -v http://127.0.0.1:8081 (and :8082) with 500.
-Jarno
--
Jarno Huuskonen
>From 3f82309f1b96330ac75bc53a35b683cdc41ab61d Mon Sep 17 00:00:00 2001
From: Jarno Huuskonen <[email protected]>
Date: Mon, 26 Dec 2016 13:47:30 +0200
Subject: [PATCH] parse_http_req_cond: parse deny_status code for http-request
tarpit.
To: [email protected]
X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4
---
src/proto_http.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/proto_http.c b/src/proto_http.c
index aa8d997..dce1ac7 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -9007,11 +9007,15 @@ struct act_rule *parse_http_req_cond(const char **args,
const char *file, int li
if (!strcmp(args[0], "allow")) {
rule->action = ACT_ACTION_ALLOW;
cur_arg = 1;
- } else if (!strcmp(args[0], "deny") || !strcmp(args[0], "block")) {
+ } else if (!strcmp(args[0], "deny") || !strcmp(args[0], "block") ||
!strcmp(args[0], "tarpit")) {
int code;
int hc;
rule->action = ACT_ACTION_DENY;
+ if (!strcmp(args[0], "tarpit")) {
+ rule->action = ACT_HTTP_REQ_TARPIT;
+ rule->deny_status = HTTP_ERR_500;
+ }
cur_arg = 1;
if (strcmp(args[cur_arg], "deny_status") == 0) {
cur_arg++;
@@ -9031,13 +9035,10 @@ struct act_rule *parse_http_req_cond(const char **args,
const char *file, int li
}
if (hc >= HTTP_ERR_SIZE) {
- Warning("parsing [%s:%d] : status code %d not
handled, using default code 403.\n",
- file, linenum, code);
+ Warning("parsing [%s:%d] : status code %d not
handled, using default code %d.\n",
+ file, linenum, code, rule->action ==
ACT_ACTION_DENY ? 403: 500);
}
}
- } else if (!strcmp(args[0], "tarpit")) {
- rule->action = ACT_HTTP_REQ_TARPIT;
- cur_arg = 1;
} else if (!strcmp(args[0], "auth")) {
rule->action = ACT_HTTP_REQ_AUTH;
cur_arg = 1;
--
1.8.3.1
>From 25b5e0993e3be2af34b0c3c4957e7ddbae50b8f3 Mon Sep 17 00:00:00 2001
From: Jarno Huuskonen <[email protected]>
Date: Sun, 1 Jan 2017 12:16:44 +0200
Subject: [PATCH] http_process_tarpit: add deny_status code/message.
To: [email protected]
X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4
---
src/proto_http.c | 48 ++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 44 insertions(+), 4 deletions(-)
diff --git a/src/proto_http.c b/src/proto_http.c
index dce1ac7..63277e3 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -4347,8 +4347,10 @@ int http_process_req_common(struct stream *s, struct
channel *req, int an_bit, s
if (txn->flags & TX_CLDENY)
goto deny;
- if (txn->flags & TX_CLTARPIT)
+ if (txn->flags & TX_CLTARPIT) {
+ deny_status = HTTP_ERR_500;
goto tarpit;
+ }
}
/* add request headers from the rule sets in the same order */
@@ -4437,6 +4439,8 @@ int http_process_req_common(struct stream *s, struct
channel *req, int an_bit, s
if (s->be->cookie_name || sess->fe->capture_name)
manage_client_side_cookies(s, req);
+ txn->status = http_err_codes[deny_status];
+
req->analysers &= AN_FLT_END; /* remove switching rules etc... */
req->analysers |= AN_REQ_HTTP_TARPIT;
req->analyse_exp = tick_add_ifset(now_ms, s->be->timeout.tarpit);
@@ -4843,6 +4847,7 @@ int http_process_request(struct stream *s, struct channel
*req, int an_bit)
*/
int http_process_tarpit(struct stream *s, struct channel *req, int an_bit)
{
+ int http_err_code_idx;
struct http_txn *txn = s->txn;
/* This connection is being tarpitted. The CLIENT side has
@@ -4863,9 +4868,44 @@ int http_process_tarpit(struct stream *s, struct channel
*req, int an_bit)
*/
s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
- txn->status = 500;
- if (!(req->flags & CF_READ_ERROR))
- http_reply_and_close(s, txn->status, http_error_message(s,
HTTP_ERR_500));
+ if (!(req->flags & CF_READ_ERROR)) {
+ switch(txn->status) {
+ case 500:
+ http_err_code_idx = HTTP_ERR_500;
+ break;
+ case 403:
+ http_err_code_idx = HTTP_ERR_403;
+ break;
+ case 429:
+ http_err_code_idx = HTTP_ERR_429;
+ break;
+ case 504:
+ http_err_code_idx = HTTP_ERR_504;
+ break;
+ case 503:
+ http_err_code_idx = HTTP_ERR_503;
+ break;
+ case 502:
+ http_err_code_idx = HTTP_ERR_502;
+ break;
+ case 408:
+ http_err_code_idx = HTTP_ERR_408;
+ break;
+ case 405:
+ http_err_code_idx = HTTP_ERR_405;
+ break;
+ case 400:
+ http_err_code_idx = HTTP_ERR_400;
+ break;
+ case 200:
+ http_err_code_idx = HTTP_ERR_200;
+ break;
+ default:
+ http_err_code_idx = HTTP_ERR_500;
+ break;
+ }
+ http_reply_and_close(s, txn->status, http_error_message(s,
http_err_code_idx));
+ }
req->analysers &= AN_FLT_END;
req->analyse_exp = TICK_ETERNITY;
--
1.8.3.1