syslogd: Add rfc3164-strict format option

The syslogd bsd/rfc3164 message format does not strictly conform to the
format recommended in RFC 3164 when syslog messages are forwarded from
remote hosts.

The new rfc3164-strict format generates messages that conform with the
RFC 3164 recommended format. The existing format is maintained for
backwards compatibility.

PR:		220246
Reviewed by:	markj
MFC after:	3 weeks
Pull Request:	https://github.com/freebsd/freebsd-src/pull/1536
This commit is contained in:
Michal Scigocki
2024-12-23 04:36:57 +00:00
committed by Mark Johnston
parent 65c61840ee
commit 8cc248fb92
5 changed files with 107 additions and 11 deletions
+9 -2
View File
@@ -269,14 +269,21 @@ The values
.Ar bsd
and
.Ar rfc3164
are used to generate RFC 3164 log messages.
are used to generate legacy RFC 3164 log messages.
The value
.Ar rfc3164-strict
is used to generate log messages using the RFC 3164 recommended format,
where messages sent over the network include the hostname,
and messages forwarded by a relay exclude the
.Dq Forwarded from
field.
The values
.Ar syslog
and
.Ar rfc5424
are used to generate RFC 5424 log messages,
having RFC 3339 timestamps with microsecond precision.
The default is to generate RFC 3164 log messages.
The default is to generate legacy RFC 3164 log messages.
.It Fl o
Prefix kernel messages with the full kernel boot file as determined by
.Xr getbootfile 3 .
+25 -9
View File
@@ -194,6 +194,13 @@ static STAILQ_HEAD(, socklist) shead = STAILQ_HEAD_INITIALIZER(shead);
#define RFC3164_DATELEN 15
#define RFC3164_DATEFMT "%b %e %H:%M:%S"
/*
* FORMAT_BSD_LEGACY and FORMAT_RFC3164_STRICT are two variations of
* the RFC 3164 logging format.
*/
#define IS_RFC3164_FORMAT (output_format == FORMAT_BSD_LEGACY || \
output_format == FORMAT_RFC3164_STRICT)
static STAILQ_HEAD(, filed) fhead =
STAILQ_HEAD_INITIALIZER(fhead); /* Log files that we write to */
static struct filed consfile; /* Console */
@@ -315,7 +322,11 @@ static int LogFacPri; /* Put facility and priority in log message: */
static bool KeepKernFac; /* Keep remotely logged kernel facility */
static bool needdofsync = true; /* Are any file(s) waiting to be fsynced? */
static struct pidfh *pfh;
static bool RFC3164OutputFormat = true; /* Use legacy format by default. */
static enum {
FORMAT_BSD_LEGACY, /* default, RFC 3164 with legacy deviations */
FORMAT_RFC3164_STRICT, /* compliant to RFC 3164 recommendataions */
FORMAT_RFC5424, /* RFC 5424 format */
} output_format = FORMAT_BSD_LEGACY;
static int kq; /* kqueue(2) descriptor. */
struct iovlist;
@@ -635,10 +646,12 @@ main(int argc, char *argv[])
case 'O':
if (strcmp(optarg, "bsd") == 0 ||
strcmp(optarg, "rfc3164") == 0)
RFC3164OutputFormat = true;
output_format = FORMAT_BSD_LEGACY;
else if (strcmp(optarg, "rfc3164-strict") == 0)
output_format = FORMAT_RFC3164_STRICT;
else if (strcmp(optarg, "syslog") == 0 ||
strcmp(optarg, "rfc5424") == 0)
RFC3164OutputFormat = false;
output_format = FORMAT_RFC5424;
else
usage();
break;
@@ -666,7 +679,7 @@ main(int argc, char *argv[])
if ((argc -= optind) != 0)
usage();
if (RFC3164OutputFormat && MaxForwardLen > 1024)
if (IS_RFC3164_FORMAT && MaxForwardLen > 1024)
errx(1, "RFC 3164 messages may not exceed 1024 bytes");
pfh = pidfile_open(PidFile, 0600, &spid);
@@ -1993,7 +2006,10 @@ fprintlog_rfc3164(struct filed *f, const char *hostname, const char *app_name,
iovlist_append(&il, priority_number);
iovlist_append(&il, ">");
iovlist_append(&il, timebuf);
if (strcasecmp(hostname, LocalHostName) != 0) {
if (output_format == FORMAT_RFC3164_STRICT) {
iovlist_append(&il, " ");
iovlist_append(&il, hostname);
} else if (strcasecmp(hostname, LocalHostName) != 0) {
iovlist_append(&il, " Forwarded from ");
iovlist_append(&il, hostname);
iovlist_append(&il, ":");
@@ -2092,7 +2108,7 @@ fprintlog_first(struct filed *f, const char *hostname, const char *app_name,
return;
}
if (RFC3164OutputFormat)
if (IS_RFC3164_FORMAT)
fprintlog_rfc3164(f, hostname, app_name, procid, msg, flags);
else
fprintlog_rfc5424(f, hostname, app_name, procid, msgid,
@@ -2215,7 +2231,7 @@ cvthname(struct sockaddr *f)
if (hl > 0 && hname[hl-1] == '.')
hname[--hl] = '\0';
/* RFC 5424 prefers logging FQDNs. */
if (RFC3164OutputFormat)
if (IS_RFC3164_FORMAT)
trimdomain(hname, hl);
return (hname);
}
@@ -2599,7 +2615,7 @@ init(bool reload)
err(EX_OSERR, "gethostname() failed");
if ((p = strchr(LocalHostName, '.')) != NULL) {
/* RFC 5424 prefers logging FQDNs. */
if (RFC3164OutputFormat)
if (IS_RFC3164_FORMAT)
*p = '\0';
LocalDomain = p + 1;
} else {
@@ -3134,7 +3150,7 @@ cfline(const char *line, const char *prog, const char *host,
if (hl > 0 && f.f_host[hl-1] == '.')
f.f_host[--hl] = '\0';
/* RFC 5424 prefers logging FQDNs. */
if (RFC3164OutputFormat)
if (IS_RFC3164_FORMAT)
trimdomain(f.f_host, hl);
}
@@ -63,6 +63,25 @@ O_flag_rfc3164_basic_cleanup()
syslogd_stop
}
atf_test_case "O_flag_rfc3164strict_basic" "cleanup"
O_flag_rfc3164strict_basic_head()
{
atf_set descr "rfc3164-strict format test on local syslog message"
}
O_flag_rfc3164strict_basic_body()
{
local format="rfc3164-strict"
local logfile="${PWD}/O_flag_${format}_basic.log"
setup_basic_format_test "${format}" "${logfile}"
atf_check -s exit:0 -o match:"${REGEX_RFC3164_LOGFILE}" cat "${logfile}"
}
O_flag_rfc3164strict_basic_cleanup()
{
syslogd_stop
}
atf_test_case "O_flag_syslog_basic" "cleanup"
O_flag_syslog_basic_head()
{
@@ -105,6 +124,7 @@ atf_init_test_cases()
{
atf_add_test_case "O_flag_bsd_basic"
atf_add_test_case "O_flag_rfc3164_basic"
atf_add_test_case "O_flag_rfc3164strict_basic"
atf_add_test_case "O_flag_syslog_basic"
atf_add_test_case "O_flag_rfc5424_basic"
}
@@ -94,6 +94,31 @@ O_flag_rfc3164_forwarded_cleanup()
"${SERVER_2_PORT}"
}
atf_test_case "O_flag_rfc3164strict_forwarded" "cleanup"
O_flag_rfc3164strict_forwarded_head()
{
atf_set descr "rfc3164-strict format test on a forwarded syslog message"
set_common_atf_metadata
}
O_flag_rfc3164strict_forwarded_body()
{
local format="rfc3164-strict"
local logfile="${PWD}/${format}_forwarded.log"
local pcapfile="${PWD}/${format}_forwarded.pcap"
setup_forwarded_format_test "${format}" "${logfile}" "${pcapfile}"
atf_check -s exit:0 -o match:"${REGEX_RFC3164_LOGFILE}" cat "${logfile}"
atf_check -s exit:0 -e ignore -o match:"${REGEX_RFC3164_PAYLOAD}" \
tcpdump -A -r "${pcapfile}"
}
O_flag_rfc3164strict_forwarded_cleanup()
{
syslogd_stop_on_ports \
"${SYSLOGD_UDP_PORT_1}" \
"${SYSLOGD_UDP_PORT_2}"
}
atf_test_case "O_flag_syslog_forwarded" "cleanup"
O_flag_syslog_forwarded_head()
{
@@ -205,6 +230,7 @@ atf_init_test_cases()
{
atf_add_test_case "O_flag_bsd_forwarded"
atf_add_test_case "O_flag_rfc3164_forwarded"
atf_add_test_case "O_flag_rfc3164strict_forwarded"
atf_add_test_case "O_flag_syslog_forwarded"
atf_add_test_case "O_flag_rfc5424_forwarded"
@@ -101,6 +101,32 @@ O_flag_rfc3164_relayed_cleanup()
"${SERVER_3_PORT}"
}
atf_test_case "O_flag_rfc3164strict_relayed" "cleanup"
O_flag_rfc3164strict_relayed_head()
{
atf_set descr "rfc3164-strict format test on a relayed syslog message"
set_common_atf_metadata
}
O_flag_rfc3164strict_relayed_body()
{
local format="rfc3164-strict"
local logfile="${PWD}/${format}_relayed.log"
local pcapfile="${PWD}/${format}_relayed.pcap"
setup_relayed_format_test "${format}" "${logfile}" "${pcapfile}"
atf_check -s exit:0 -o match:"${REGEX_RFC3164_LOGFILE}" cat "${logfile}"
atf_check -s exit:0 -e ignore -o match:"${REGEX_RFC3164_PAYLOAD}" \
tcpdump -A -r "${pcapfile}"
}
O_flag_rfc3164strict_relayed_cleanup()
{
syslogd_stop_on_ports \
"${SYSLOGD_UDP_PORT_1}" \
"${SYSLOGD_UDP_PORT_2}" \
"${SYSLOGD_UDP_PORT_3}"
}
atf_test_case "O_flag_syslog_relayed" "cleanup"
O_flag_syslog_relayed_head()
{
@@ -157,6 +183,7 @@ atf_init_test_cases()
{
atf_add_test_case "O_flag_bsd_relayed"
atf_add_test_case "O_flag_rfc3164_relayed"
atf_add_test_case "O_flag_rfc3164strict_relayed"
atf_add_test_case "O_flag_syslog_relayed"
atf_add_test_case "O_flag_rfc5424_relayed"
}