diff --git a/doc/configuration.txt b/doc/configuration.txt index 8e5f707e73..e0e6d7e440 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -3771,6 +3771,29 @@ req_ssl_ver that TLSv1 is announced as SSL version 3.1. This test was designed to be used with TCP request content inspection. +wait_end + Waits for the end of the analysis period to return true. This may be used in + conjunction with content analysis to avoid returning a wrong verdict early. + It may also be used to delay some actions, such as a delayed reject for some + special addresses. Since it either stops the rules evaluation or immediately + returns true, it is recommended to use this acl as the last one in a rule. + Please note that the default ACL "WAIT_END" is always usable without prior + declaration. This test was designed to be used with TCP request content + inspection. + + Examples : + # delay every incoming request by 2 seconds + tcp-request inspect-delay 2s + tcp-request content accept if WAIT_END + + # don't immediately tell bad guys they are rejected + tcp-request inspect-delay 10s + acl goodguys src 10.0.0.0/24 + acl badguys src 10.0.1.0/24 + tcp-request content accept if goodguys + tcp-request content reject if badguys WAIT_END + tcp-request content reject + 2.3.5.3) Matching at Layer 7 ---------------------------- @@ -3957,6 +3980,7 @@ HTTP_URL_SLASH url_beg / match URL begining with "/" HTTP_URL_STAR url * match URL equal to "*" HTTP_CONTENT hdr_val(content-length) gt 0 match an existing content-length REQ_CONTENT req_len gt 0 match data in the request buffer +WAIT_END wait_end wait for end of content analysis ---------------+-----------------------------+--------------------------------- diff --git a/src/acl.c b/src/acl.c index e66d502f62..c02ad70daf 100644 --- a/src/acl.c +++ b/src/acl.c @@ -39,6 +39,21 @@ acl_fetch_true(struct proxy *px, struct session *l4, void *l7, int dir, return 1; } +/* wait for more data as long as possible, then return TRUE. This should be + * used with content inspection. + */ +static int +acl_fetch_wait_end(struct proxy *px, struct session *l4, void *l7, int dir, + struct acl_expr *expr, struct acl_test *test) +{ + if (dir & ACL_PARTIAL) { + test->flags |= ACL_TEST_F_MAY_CHANGE; + return 0; + } + test->flags |= ACL_TEST_F_SET_RES_PASS; + return 1; +} + /* force FALSE to be returned at the fetch level */ static int acl_fetch_false(struct proxy *px, struct session *l4, void *l7, int dir, @@ -772,6 +787,7 @@ const struct { { .name = "HTTP_URL_STAR", .expr = {"url","*",""}}, { .name = "HTTP_CONTENT", .expr = {"hdr_val(content-length)","gt","0",""}}, { .name = "REQ_CONTENT", .expr = {"req_len","gt","0",""}}, + { .name = "WAIT_END", .expr = {"wait_end",""}}, { .name = NULL, .expr = {""}} }; @@ -1064,6 +1080,7 @@ int acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *l4, v static struct acl_kw_list acl_kws = {{ },{ { "always_true", acl_parse_nothing, acl_fetch_true, acl_match_nothing }, { "always_false", acl_parse_nothing, acl_fetch_false, acl_match_nothing }, + { "wait_end", acl_parse_nothing, acl_fetch_wait_end, acl_match_nothing }, #if 0 { "time", acl_parse_time, acl_fetch_time, acl_match_time }, #endif diff --git a/tests/test-inspect-smtp.cfg b/tests/test-inspect-smtp.cfg index 1c0d46dddc..5cfc8649f8 100644 --- a/tests/test-inspect-smtp.cfg +++ b/tests/test-inspect-smtp.cfg @@ -3,7 +3,7 @@ # - if the address is in the white list, then accept it and forward the # connection to the server (local port 25) # - if the address is in the black list, then immediately drop it -# - otherwise, wait up to 3 seconds. If the client talks during this time, +# - otherwise, wait up to 35 seconds. If the client talks during this time, # drop the connection. # - then accept the connection if it passes all the tests. # @@ -17,19 +17,28 @@ listen block-fake-mailers mode tcp bind :8025 - timeout client 6s - timeout server 6s - timeout connect 6s + timeout client 60s + timeout server 60s + timeout queue 60s + timeout connect 5s - tcp-request inspect-delay 4s + tcp-request inspect-delay 35s acl white_list src 127.0.0.2 - acl black_list src 127.0.0.3 - acl talkative req_len gt 0 + acl black_fast src 127.0.0.3 # those ones are immediately rejected + acl black_slow src 127.0.0.4 # those ones are rejected after a delay tcp-request content accept if white_list - tcp-request content reject if black_list - tcp-request content reject if talkative + tcp-request content reject if black_fast + tcp-request content reject if black_slow WAIT_END + tcp-request content reject if REQ_CONTENT + # note that it is possible to wait for the end of the analysis period + # before rejecting undesired contents + # tcp-request content reject if REQ_CONTENT WAIT_END + + # on Linux+transparent proxy patch, it's useful to reuse the client'IP + # source 0.0.0.0 usesrc clientip balance roundrobin server mail 127.0.0.1:25 +