From 3ba924a4da0e5cfdca695b3f3dd5a0ff9f32e736 Mon Sep 17 00:00:00 2001 From: Aurelien DARRAGON Date: Fri, 20 Sep 2024 09:34:13 +0200 Subject: [PATCH] MINOR: action: add do-log action Thanks to the two previous commits, we can now expose the do-log action on all available action contexts, including the new quic-init context. Each context is responsible for exposing the do-log action by registering the relevant log steps, saving the idendifier, and then store it in the rule's context so that do_log_action() automatically uses it to produce the log during runtime. To use the feature, it is simply needed to use "do-log" (without argument) on an action directive, example: tcp-request connection do-log As mentioned before, each context where the action is exposed has its own log step identifier. Currently known identifiers are: quic-initial: quic-init tcp-request connection: tcp-req-conn tcp-request session: tcp-req-sess tcp-request content: tcp-req-cont tcp-response content: tcp-res-cont http-request: http-req http-response: http-res http-after-response: http-after-res Thus, these "additional" logging steps can be used as-is under log-profile section (after "on" keyword). However, although the parser will accept them, it makes no sense to use them with the "log-steps" proxy keyword, since the only path for these origins to trigger a log generation is through the explicit use of "do-log" action. This need was described in GH #401, it should help to conditionally trigger logs using ACL at specific key points.. and may either be used alone or combined with "log-steps" to add additional log "trackers" during transaction handling. Documentation was updated and some examples were added. --- doc/configuration.txt | 30 +++++++++++++++++++++++++++ src/http_act.c | 37 ++++++++++++++++++++++++++++++++++ src/quic_rules.c | 19 +++++++++++++++++ src/tcp_act.c | 47 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+) diff --git a/doc/configuration.txt b/doc/configuration.txt index 4a194e775..f76b65b1b 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -14585,6 +14585,7 @@ del-map - - - - - X X deny - - - - - X X - dgram-drop X - - - - - - - disable-l7-retry - - - - - X - - +do-log X X X X X X X X do-resolve - - - X - X - - early-hint - - - - - X - - expect-netscaler-cip - X - - - - - - @@ -14885,6 +14886,33 @@ disable-l7-retry reason than a connection failure. This can be useful for example to make sure POST requests aren't retried on failure. +do-log + Usable in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft + X | X | X | X | X | X | X | X + + This action manually triggers a log emission on the proxy. This means + log options on the proxy will be considered (including formatting options + such as "log-format"), but it will not interfere with the logs automatically + generated by the proxy during transaction handling. It currently doesn't + support any argument, though extensions may appear in future versions. + + Using "log-profile", it is possible to precisely describe how the log should + be emitted for each of the available contexts where the action may be used. + That is, 'on' keyword followed by of the following values: 'quic-init', + 'tcp-req-conn', 'tcp-req-sess', 'tcp-req-cont', 'tcp-res-cont', 'http-req', + 'http-res', 'http-after-res'. + + Also, they will be properly reported when using "%OG" logformat alias. + + Example: + log-profile myprof + on tcp-req-conn format "Connect: %ci" + + frontend myfront + log stdout format rfc5424 profile myprof local0 + log-format "log generated using proxy logformat, from '%OG'" + tcp-request connection do-log #uses special log-profile format + tcp-request content do-log #uses proxy logformat do-resolve(,,[ipv4,ipv6]) Usable in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft @@ -26882,6 +26910,8 @@ on [drop] [format ] [sd ] - "any" : override both log-format and error-log-format for all logging steps, unless a more precise step override is declared. + See "do-log" action for relevant additional values. + This setting is only relevant for "log" directives used from contexts where using "log-format" directive makes sense (e.g.: http and tcp proxies). Else it will simply be ignored. diff --git a/src/http_act.c b/src/http_act.c index 3a902ab35..f0a19f362 100644 --- a/src/http_act.c +++ b/src/http_act.c @@ -2371,6 +2371,40 @@ static enum act_parse_ret parse_http_wait_for_body(const char **args, int *orig_ return ACT_RET_PRS_OK; } +static enum log_orig_id do_log_http_req; +static enum log_orig_id do_log_http_res; +static enum log_orig_id do_log_http_after_res; + +static void init_do_log(void) +{ + do_log_http_req = log_orig_register("http-req"); + BUG_ON(do_log_http_req == LOG_ORIG_UNSPEC); + do_log_http_res = log_orig_register("http-res"); + BUG_ON(do_log_http_res == LOG_ORIG_UNSPEC); + do_log_http_after_res = log_orig_register("http-after-res"); + BUG_ON(do_log_http_after_res == LOG_ORIG_UNSPEC); +} + +INITCALL0(STG_PREPARE, init_do_log); + +static enum act_parse_ret parse_http_req_do_log(const char **args, int *orig_arg, struct proxy *px, + struct act_rule *rule, char **err) +{ + return do_log_parse_act(do_log_http_req, args, orig_arg, px, rule, err); +} + +static enum act_parse_ret parse_http_res_do_log(const char **args, int *orig_arg, struct proxy *px, + struct act_rule *rule, char **err) +{ + return do_log_parse_act(do_log_http_res, args, orig_arg, px, rule, err); +} + +static enum act_parse_ret parse_http_after_res_do_log(const char **args, int *orig_arg, struct proxy *px, + struct act_rule *rule, char **err) +{ + return do_log_parse_act(do_log_http_after_res, args, orig_arg, px, rule, err); +} + /************************************************************************/ /* All supported http-request action keywords must be declared here. */ /************************************************************************/ @@ -2387,6 +2421,7 @@ static struct action_kw_list http_req_actions = { { "del-map", parse_http_set_map, KWF_MATCH_PREFIX }, { "deny", parse_http_deny, 0 }, { "disable-l7-retry", parse_http_req_disable_l7_retry, 0 }, + { "do-log", parse_http_req_do_log, 0 }, { "early-hint", parse_http_set_header, 0 }, { "normalize-uri", parse_http_normalize_uri, KWF_EXPERIMENTAL }, { "redirect", parse_http_redirect, 0 }, @@ -2425,6 +2460,7 @@ static struct action_kw_list http_res_actions = { { "del-header", parse_http_del_header, 0 }, { "del-map", parse_http_set_map, KWF_MATCH_PREFIX }, { "deny", parse_http_deny, 0 }, + { "do-log", parse_http_res_do_log, 0 }, { "redirect", parse_http_redirect, 0 }, { "replace-header", parse_http_replace_header, 0 }, { "replace-value", parse_http_replace_header, 0 }, @@ -2450,6 +2486,7 @@ static struct action_kw_list http_after_res_actions = { { "del-acl", parse_http_set_map, KWF_MATCH_PREFIX }, { "del-header", parse_http_del_header, 0 }, { "del-map", parse_http_set_map, KWF_MATCH_PREFIX }, + { "do-log", parse_http_after_res_do_log, 0 }, { "replace-header", parse_http_replace_header, 0 }, { "replace-value", parse_http_replace_header, 0 }, { "set-header", parse_http_set_header, 0 }, diff --git a/src/quic_rules.c b/src/quic_rules.c index b92420953..4a9ad3d27 100644 --- a/src/quic_rules.c +++ b/src/quic_rules.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -92,6 +93,23 @@ static enum act_parse_ret parse_dgram_drop(const char **args, int *orig_arg, return ACT_RET_PRS_OK; } +static enum log_orig_id do_log_quic_init; + +static void init_do_log(void) +{ + do_log_quic_init = log_orig_register("quic-init"); + BUG_ON(do_log_quic_init == LOG_ORIG_UNSPEC); +} + +INITCALL0(STG_PREPARE, init_do_log); + +static enum act_parse_ret parse_do_log(const char **args, int *orig_arg, + struct proxy *px, + struct act_rule *rule, char **err) +{ + return do_log_parse_act(do_log_quic_init, args, orig_arg, px, rule, err); +} + static enum act_return quic_init_action_reject(struct act_rule *rule, struct proxy *px, struct session *sess, struct stream *s, int flags) { @@ -145,6 +163,7 @@ struct action_kw *action_quic_init_custom(const char *kw) static struct action_kw_list quic_init_actions = { ILH, { { "accept", parse_accept, 0 }, { "dgram-drop", parse_dgram_drop, 0 }, + { "do-log", parse_do_log, 0 }, { "reject", parse_reject, 0 }, { "send-retry", parse_send_retry, 0 }, { /* END */ }, diff --git a/src/tcp_act.c b/src/tcp_act.c index c8f5ca286..8a4fd2f90 100644 --- a/src/tcp_act.c +++ b/src/tcp_act.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -789,8 +790,51 @@ static enum act_parse_ret tcp_parse_silent_drop(const char **args, int *cur_arg, return ACT_RET_PRS_OK; } +static enum log_orig_id do_log_tcp_req_conn; +static enum log_orig_id do_log_tcp_req_sess; +static enum log_orig_id do_log_tcp_req_cont; +static enum log_orig_id do_log_tcp_res_cont; + +static void init_do_log(void) +{ + do_log_tcp_req_conn = log_orig_register("tcp-req-conn"); + BUG_ON(do_log_tcp_req_conn == LOG_ORIG_UNSPEC); + do_log_tcp_req_sess = log_orig_register("tcp-req-sess"); + BUG_ON(do_log_tcp_req_sess == LOG_ORIG_UNSPEC); + do_log_tcp_req_cont = log_orig_register("tcp-req-cont"); + BUG_ON(do_log_tcp_req_cont == LOG_ORIG_UNSPEC); + do_log_tcp_res_cont = log_orig_register("tcp-res-cont"); + BUG_ON(do_log_tcp_res_cont == LOG_ORIG_UNSPEC); +} + +INITCALL0(STG_PREPARE, init_do_log); + +static enum act_parse_ret tcp_req_conn_parse_do_log(const char **args, int *orig_arg, struct proxy *px, + struct act_rule *rule, char **err) +{ + return do_log_parse_act(do_log_tcp_req_conn, args, orig_arg, px, rule, err); +} + +static enum act_parse_ret tcp_req_sess_parse_do_log(const char **args, int *orig_arg, struct proxy *px, + struct act_rule *rule, char **err) +{ + return do_log_parse_act(do_log_tcp_req_sess, args, orig_arg, px, rule, err); +} + +static enum act_parse_ret tcp_req_cont_parse_do_log(const char **args, int *orig_arg, struct proxy *px, + struct act_rule *rule, char **err) +{ + return do_log_parse_act(do_log_tcp_req_cont, args, orig_arg, px, rule, err); +} + +static enum act_parse_ret tcp_res_cont_parse_do_log(const char **args, int *orig_arg, struct proxy *px, + struct act_rule *rule, char **err) +{ + return do_log_parse_act(do_log_tcp_res_cont, args, orig_arg, px, rule, err); +} static struct action_kw_list tcp_req_conn_actions = {ILH, { + { "do-log" , tcp_req_conn_parse_do_log }, { "set-dst" , tcp_parse_set_src_dst }, { "set-dst-port", tcp_parse_set_src_dst }, { "set-fc-mark", tcp_parse_set_mark }, @@ -807,6 +851,7 @@ INITCALL1(STG_REGISTER, tcp_req_conn_keywords_register, &tcp_req_conn_actions); static struct action_kw_list tcp_req_sess_actions = {ILH, { { "attach-srv" , tcp_parse_attach_srv }, + { "do-log", tcp_req_sess_parse_do_log }, { "set-dst" , tcp_parse_set_src_dst }, { "set-dst-port", tcp_parse_set_src_dst }, { "set-fc-mark", tcp_parse_set_mark }, @@ -822,6 +867,7 @@ static struct action_kw_list tcp_req_sess_actions = {ILH, { INITCALL1(STG_REGISTER, tcp_req_sess_keywords_register, &tcp_req_sess_actions); static struct action_kw_list tcp_req_cont_actions = {ILH, { + { "do-log", tcp_req_cont_parse_do_log }, { "set-bc-mark", tcp_parse_set_mark }, { "set-bc-tos", tcp_parse_set_tos }, { "set-dst" , tcp_parse_set_src_dst }, @@ -839,6 +885,7 @@ static struct action_kw_list tcp_req_cont_actions = {ILH, { INITCALL1(STG_REGISTER, tcp_req_cont_keywords_register, &tcp_req_cont_actions); static struct action_kw_list tcp_res_cont_actions = {ILH, { + { "do-log", tcp_res_cont_parse_do_log }, { "set-fc-mark", tcp_parse_set_mark }, { "set-fc-tos", tcp_parse_set_tos }, { "set-mark", tcp_parse_set_mark }, // DEPRECATED, see set-fc-mark