]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: log: handle log-forward "option host"
authorAurelien DARRAGON <adarragon@haproxy.com>
Mon, 10 Mar 2025 09:02:53 +0000 (10:02 +0100)
committerAurelien DARRAGON <adarragon@haproxy.com>
Wed, 12 Mar 2025 09:52:07 +0000 (10:52 +0100)
Following previous patch, we know implement the logic for the host
option under log-forward section. Possible strategies are:

      replace If input message already contains a value for the host
              field, we replace it by the source IP address from the
              sender.
              If input message doesn't contain a value for the host field
              (ie: '-' as input rfc5424 message or non compliant rfc3164
              or rfc5424 message), we use the source IP address from the
              sender as host field.

      fill    If input message already contains a value for the host field,
              we keep it.
              If input message doesn't contain a value for the host field
              (ie: '-' as input rfc5424 message or non compliant rfc3164
              or rfc5424 message), we use the source IP address from the
              sender as host field.

      keep    If input message already contains a value for the host field,
              we keep it.
              If input message doesn't contain a value for the host field,
              we set it to localhost (rfc3164) or '-' (rfc5424).
              (This is the default)

      append  If input message already contains a value for the host field,
              we append a comma followed by the IP address from the sender.
              If input message doesn't contain a value for the host field,
              we use the source IP address from the sender.

Default value (unchanged) is "keep" strategy. option host is only relevant
with rfc3164 or rfc5424 format on log targets. Also, if the source address
is not available (ie: UNIX socket), default behavior prevails.

Documentation was updated.

doc/configuration.txt
src/log.c

index 9e4f7901ff4bef0ea608513f2d266fe1035ad61a..cadf5f294a4c2d91c303506505ad41746b815ed1 100644 (file)
@@ -5370,6 +5370,41 @@ option dont-parse-log
   traditional formats. This option should be used with the format raw setting on
   destination log targets to ensure the original message content is preserved.
 
+option host { replace | fill | keep | append }
+  Set the host strategy that should be used on the log-forward section
+  regarding syslog host field for outbound rfc3164 or rfc5424 messages.
+
+      replace If input message already contains a value for the host field,
+              we replace it by the source IP address from the sender.
+              If input message doesn't contain a value for the host field (ie:
+              '-' as input rfc5424 message or non compliant rfc3164 or rfc5424
+              message), we use the source IP address from the sender as host
+              field.
+
+      fill    If input message already contains a value for the host field,
+              we keep it.
+              If input message doesn't contain a value for the host field
+              (ie: '-' as input rfc5424 message or non compliant rfc3164 or
+              rfc5424 message), we use the source IP address from the sender as
+              host field.
+
+      keep    If input message already contains a value for the host field,
+              we keep it.
+              If input message doesn't contain a value for the host field,
+              we set it to 'localhost' (rfc3164) or '-' (rfc5424).
+              (This is the default)
+
+      append  If input message already contains a value for the host field,
+              we append a comma followed by the IP address from the sender.
+              If input message doesn't contain a value for the host field,
+              we use the source IP address from the sender.
+
+  For all options above, if the source IP address from the sender is not
+  available (ie: UNIX/ABNS socket), then the resulting strategy is "keep".
+
+  Note that this option is only relevant for rfc3164 or rfc5424 destination
+  log format. Else setting the option will have no visible effect.
+
 3.11. HTTPClient tuning
 -----------------------
 
index 3dc6f1a81caebc2afeb273e93b45a22c141c660d..20a8fcfa95977cd3817943ebe4ec39dbba8cb769 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -5722,6 +5722,7 @@ static void syslog_process_message(struct proxy *frontend, struct listener *l,
                                    struct buffer *buf)
 {
        static THREAD_LOCAL struct ist metadata[LOG_META_FIELDS];
+       char *src_addr = NULL;
        size_t size;
        char *message;
        int level;
@@ -5733,10 +5734,46 @@ static void syslog_process_message(struct proxy *frontend, struct listener *l,
 
        prepare_log_message(buf->area, buf->data, &level, &facility, metadata, &message, &size);
 
-       if (!(frontend->options3 & PR_O3_DONTPARSELOG))
-               parse_log_message(buf->area, buf->data, &level, &facility, metadata, &message, &size);
+       if (frontend->options3 & PR_O3_DONTPARSELOG)
+               goto end;
+
+       parse_log_message(buf->area, buf->data, &level, &facility, metadata, &message, &size);
+
+       if (real_family(saddr->ss_family) == AF_UNIX)
+               saddr = NULL; /* no source information for UNIX addresses */
+
+       /* handle host options */
+       if (!(frontend->options3 & PR_O3_LOGF_HOST_KEEP)) {
+               if (saddr)
+                       src_addr = sa2str(saddr, -1, 0);
 
+               if ((frontend->options3 & PR_O3_LOGF_HOST_REPLACE) && src_addr) {
+                       /* unconditional replace, unless source is not available */
+                       metadata[LOG_META_HOST] = ist(src_addr);
+               }
+               else if ((frontend->options3 & PR_O3_LOGF_HOST_FILL) &&
+                         src_addr && !metadata[LOG_META_HOST].len) {
+                       /* only fill if missing */
+                       metadata[LOG_META_HOST] = ist(src_addr);
+               }
+               else if ((frontend->options3 & PR_O3_LOGF_HOST_APPEND) && src_addr) {
+                       /* append source after existing host */
+                       if (metadata[LOG_META_HOST].len) {
+                               memprintf(&src_addr, "%.*s,%s",
+                                         (int)metadata[LOG_META_HOST].len,
+                                         metadata[LOG_META_HOST].ptr, src_addr);
+                               if (src_addr)
+                                       metadata[LOG_META_HOST] = ist(src_addr);
+                       }
+                       else
+                               metadata[LOG_META_HOST] = ist(src_addr);
+               }
+       }
+       // else nothing to do
+
+ end:
        process_send_log(NULL, &frontend->loggers, level, facility, metadata, message, size);
+       ha_free(&src_addr);
 }
 
 /*
@@ -6033,6 +6070,7 @@ int cfg_parse_log_forward(const char *file, int linenum, char **args, int kwm)
                px->accept = frontend_accept;
                px->default_target = &syslog_applet.obj_type;
                px->id = strdup(args[1]);
+               px->options3 |= PR_O3_LOGF_HOST_KEEP;
        }
        else if (strcmp(args[0], "maxconn") == 0) {  /* maxconn */
                if (warnifnotcap(cfg_log_forward, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))