[systemd-devel] [PATCH 2/2] journald: Add UDP syslog listener

Lubomir Rintel lkundrak at v3.sk
Wed May 28 13:30:57 PDT 2014


This is fairly simple, yet useful with netconsole. Remote socket address is not
used to obtain hostname, it would be easy to fake it via UDP anyway, which is
probably not desirable. If clients wish, they should identify themselves via
identifier field in syslog packets.

Disabled by default.
---
 man/systemd-journald.service.xml |  6 ++++++
 src/journal/journald-server.c    | 16 +++++++++++++---
 src/journal/journald-server.h    |  1 +
 src/journal/journald-syslog.c    | 10 ++++++++++
 units/systemd-journald.socket    |  1 +
 5 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml
index 7158888..7c0d277 100644
--- a/man/systemd-journald.service.xml
+++ b/man/systemd-journald.service.xml
@@ -97,6 +97,12 @@
                 obtains the the handles from systemd via activation socket-passing
                 interface, or opens them itself.</para>
 
+                <para>Additionally, journal might be passed an open
+                <constant>SOCK_DGRAM</constant> inet socket, which will be used for
+                an UDP syslog protocol listener. Note that you should not normally
+                need this and it would allow remote machines to inject logs into
+                journal without any authentication.</para>
+
                 <para><filename>systemd-journald</filename> will
                 forward all received log messages to the <constant>AF_UNIX</constant>
                 <constant>SOCK_DGRAM</constant> socket
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 381d80a..7f7bf6e 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -1108,7 +1108,7 @@ int process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userda
         Server *s = userdata;
 
         assert(s);
-        assert(fd == s->native_fd || fd == s->syslog_fd);
+        assert(fd == s->native_fd || fd == s->syslog_fd || fd == s->syslog_udp_fd);
 
         if (revents != EPOLLIN) {
                 log_error("Got invalid event from epoll for datagram fd: %"PRIx32, revents);
@@ -1191,7 +1191,7 @@ int process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userda
                         }
                 }
 
-                if (fd == s->syslog_fd) {
+                if (fd == s->syslog_fd || fd == s->syslog_udp_fd) {
                         if (n > 0 && n_fds == 0) {
                                 s->buffer[n] = 0;
                                 server_process_syslog_message(s, strstrip(s->buffer), ucred, tv, label, label_len);
@@ -1460,7 +1460,7 @@ int server_init(Server *s) {
         assert(s);
 
         zero(*s);
-        s->syslog_fd = s->native_fd = s->stdout_fd = s->dev_kmsg_fd = s->hostname_fd = -1;
+        s->syslog_fd = s->syslog_udp_fd = s->native_fd = s->stdout_fd = s->dev_kmsg_fd = s->hostname_fd = -1;
         s->compress = true;
         s->seal = true;
 
@@ -1544,6 +1544,15 @@ int server_init(Server *s) {
 
                         s->syslog_fd = fd;
 
+                } else if (sd_is_socket_inet(fd, AF_UNSPEC, SOCK_DGRAM, -1, 514) > 0) {
+
+                        if (s->syslog_udp_fd >= 0) {
+                                log_error("Too many syslog UDP sockets passed.");
+                                return -EINVAL;
+                        }
+
+                        s->syslog_udp_fd = fd;
+
                 } else {
                         log_error("Unknown socket passed.");
                         return -EINVAL;
@@ -1648,6 +1657,7 @@ void server_done(Server *s) {
         sd_event_unref(s->event);
 
         safe_close(s->syslog_fd);
+        safe_close(s->syslog_udp_fd);
         safe_close(s->native_fd);
         safe_close(s->stdout_fd);
         safe_close(s->dev_kmsg_fd);
diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h
index e468b82..c757704 100644
--- a/src/journal/journald-server.h
+++ b/src/journal/journald-server.h
@@ -56,6 +56,7 @@ typedef struct StdoutStream StdoutStream;
 
 typedef struct Server {
         int syslog_fd;
+        int syslog_udp_fd;
         int native_fd;
         int stdout_fd;
         int dev_kmsg_fd;
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 434eac4..8fe2eae 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -478,6 +478,16 @@ int server_open_syslog_socket(Server *s) {
                 return r;
         }
 
+        if (s->syslog_udp_fd > 0) {
+                fd_nonblock(s->syslog_udp_fd, 1);
+
+                r = sd_event_add_io(s->event, &s->syslog_event_source, s->syslog_udp_fd, EPOLLIN, process_datagram, s);
+                if (r < 0) {
+                        log_error("Failed to add syslog server fd to event loop: %s", strerror(-r));
+                        return r;
+                }
+        }
+
         return 0;
 }
 
diff --git a/units/systemd-journald.socket b/units/systemd-journald.socket
index fbeb10b..add6785 100644
--- a/units/systemd-journald.socket
+++ b/units/systemd-journald.socket
@@ -16,6 +16,7 @@ Before=sockets.target
 # hence let's exclude this from isolate requests.
 IgnoreOnIsolate=yes
 
+# You can enable syslog UDP listener by adding ListenDatagram=514
 [Socket]
 ListenStream=/run/systemd/journal/stdout
 ListenDatagram=/run/systemd/journal/socket
-- 
1.9.3



More information about the systemd-devel mailing list