diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c index db94644ceb..0b99505aed 100644 --- a/src/journal-remote/journal-remote-main.c +++ b/src/journal-remote/journal-remote-main.c @@ -16,6 +16,7 @@ #include "main-func.h" #include "memory-util.h" #include "parse-argument.h" +#include "parse-helpers.h" #include "pretty-print.h" #include "process-util.h" #include "rlimit-util.h" @@ -369,8 +370,8 @@ static int setup_microhttpd_server(RemoteServer *s, const char *cert, const char *trust) { struct MHD_OptionItem opts[] = { - { MHD_OPTION_NOTIFY_COMPLETED, (intptr_t) request_meta_free}, { MHD_OPTION_EXTERNAL_LOGGER, (intptr_t) microhttpd_logger}, + { MHD_OPTION_NOTIFY_COMPLETED, (intptr_t) request_meta_free}, { MHD_OPTION_LISTEN_SOCKET, fd}, { MHD_OPTION_CONNECTION_MEMORY_LIMIT, 128*1024}, { MHD_OPTION_END}, @@ -385,9 +386,9 @@ static int setup_microhttpd_server(RemoteServer *s, MHD_USE_EPOLL | MHD_USE_ITC; + _cleanup_(MHDDaemonWrapper_freep) MHDDaemonWrapper *d = NULL; const union MHD_DaemonInfo *info; int r, epoll_fd; - MHDDaemonWrapper *d; assert(fd >= 0); @@ -435,75 +436,49 @@ static int setup_microhttpd_server(RemoteServer *s, request_handler, NULL, MHD_OPTION_ARRAY, opts, MHD_OPTION_END); - if (!d->daemon) { - log_error("Failed to start μhttp daemon"); - r = -EINVAL; - goto error; - } + if (!d->daemon) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to start μhttp daemon"); log_debug("Started MHD %s daemon on fd:%d (wrapper @ %p)", key ? "HTTPS" : "HTTP", fd, d); info = MHD_get_daemon_info(d->daemon, MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY); - if (!info) { - log_error("μhttp returned NULL daemon info"); - r = -EOPNOTSUPP; - goto error; - } + if (!info) + return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "μhttp returned NULL daemon info"); epoll_fd = info->listen_fd; - if (epoll_fd < 0) { - log_error("μhttp epoll fd is invalid"); - r = -EUCLEAN; - goto error; - } + if (epoll_fd < 0) + return log_error_errno(SYNTHETIC_ERRNO(EUCLEAN), "μhttp epoll fd is invalid"); r = sd_event_add_io(s->events, &d->io_event, epoll_fd, EPOLLIN, dispatch_http_event, d); - if (r < 0) { - log_error_errno(r, "Failed to add event callback: %m"); - goto error; - } + if (r < 0) + return log_error_errno(r, "Failed to add event callback: %m"); r = sd_event_source_set_description(d->io_event, "io_event"); - if (r < 0) { - log_error_errno(r, "Failed to set source name: %m"); - goto error; - } + if (r < 0) + return log_error_errno(r, "Failed to set source name: %m"); r = sd_event_add_time(s->events, &d->timer_event, CLOCK_MONOTONIC, UINT64_MAX, 0, null_timer_event_handler, d); - if (r < 0) { - log_error_errno(r, "Failed to add timer_event: %m"); - goto error; - } + if (r < 0) + return log_error_errno(r, "Failed to add timer_event: %m"); r = sd_event_source_set_description(d->timer_event, "timer_event"); - if (r < 0) { - log_error_errno(r, "Failed to set source name: %m"); - goto error; - } + if (r < 0) + return log_error_errno(r, "Failed to set source name: %m"); r = hashmap_ensure_put(&s->daemons, &uint64_hash_ops, &d->fd, d); - if (r == -ENOMEM) { - log_oom(); - goto error; - } - if (r < 0) { - log_error_errno(r, "Failed to add daemon to hashmap: %m"); - goto error; - } + if (r == -ENOMEM) + return log_oom(); + if (r < 0) + return log_error_errno(r, "Failed to add daemon to hashmap: %m"); + TAKE_PTR(d); s->active++; return 0; - -error: - MHD_stop_daemon(d->daemon); - free(d->daemon); - free(d); - return r; } static int setup_microhttpd_socket(RemoteServer *s, @@ -762,7 +737,7 @@ static int parse_config(void) { { "Remote", "SplitMode", config_parse_write_split_mode, 0, &arg_split_mode }, { "Remote", "ServerKeyFile", config_parse_path, 0, &arg_key }, { "Remote", "ServerCertificateFile", config_parse_path, 0, &arg_cert }, - { "Remote", "TrustedCertificateFile", config_parse_path, 0, &arg_trust }, + { "Remote", "TrustedCertificateFile", config_parse_path_or_ignore, 0, &arg_trust }, { "Remote", "MaxUse", config_parse_iec_uint64, 0, &arg_max_use }, { "Remote", "MaxFileSize", config_parse_iec_uint64, 0, &arg_max_size }, { "Remote", "MaxFiles", config_parse_uint64, 0, &arg_n_max_files }, @@ -866,7 +841,7 @@ static int parse_argv(int argc, char *argv[]) { case ARG_URL: if (arg_url) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "cannot currently set more than one --url"); + "Cannot currently set more than one --url="); arg_url = optarg; break; @@ -874,7 +849,7 @@ static int parse_argv(int argc, char *argv[]) { case ARG_GETTER: if (arg_getter) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "cannot currently use --getter more than once"); + "Cannot currently use --getter= more than once"); arg_getter = optarg; break; @@ -882,7 +857,7 @@ static int parse_argv(int argc, char *argv[]) { case ARG_LISTEN_RAW: if (arg_listen_raw) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "cannot currently use --listen-raw more than once"); + "Cannot currently use --listen-raw= more than once"); arg_listen_raw = optarg; break; @@ -890,7 +865,7 @@ static int parse_argv(int argc, char *argv[]) { case ARG_LISTEN_HTTP: if (arg_listen_http || http_socket >= 0) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "cannot currently use --listen-http more than once"); + "Cannot currently use --listen-http= more than once"); r = negative_fd(optarg); if (r >= 0) @@ -902,7 +877,7 @@ static int parse_argv(int argc, char *argv[]) { case ARG_LISTEN_HTTPS: if (arg_listen_https || https_socket >= 0) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "cannot currently use --listen-https more than once"); + "Cannot currently use --listen-https= more than once"); r = negative_fd(optarg); if (r >= 0) @@ -936,27 +911,23 @@ static int parse_argv(int argc, char *argv[]) { case ARG_TRUST: #if HAVE_GNUTLS - if (arg_trust || arg_trust_all) + if (arg_trust) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Confusing trusted CA configuration"); + "Cannot use --trust more= than once"); - if (streq(optarg, "all")) - arg_trust_all = true; - else { - arg_trust = strdup(optarg); - if (!arg_trust) - return log_oom(); - } + arg_trust = strdup(optarg); + if (!arg_trust) + return log_oom(); #else return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Option --trust is not available."); + "Option --trust= is not available."); #endif break; case 'o': if (arg_output) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "cannot use --output/-o more than once"); + "Cannot use --output=/-o more than once"); r = parse_path_argument(optarg, /* suppress_root = */ false, &arg_output); if (r < 0) @@ -1000,7 +971,7 @@ static int parse_argv(int argc, char *argv[]) { break; #else return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Option --gnutls-log is not available."); + "Option --gnutls-log= is not available."); #endif case '?': @@ -1020,12 +991,12 @@ static int parse_argv(int argc, char *argv[]) { || sd_listen_fds(false) > 0; if (type_a && type_b) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Cannot use file input or --getter with " - "--arg-listen-... or socket activation."); + "Cannot use file input or --getter= with " + "--listen-...= or socket activation."); if (type_a) { if (!arg_output) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Option --output must be specified with file input or --getter."); + "Option --output= must be specified with file input or --getter=."); if (!IN_SET(arg_split_mode, JOURNAL_WRITE_SPLIT_NONE, _JOURNAL_WRITE_SPLIT_INVALID)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), @@ -1051,6 +1022,11 @@ static int parse_argv(int argc, char *argv[]) { return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "For SplitMode=host, output must be a directory."); + if (STRPTR_IN_SET(arg_trust, "-", "all")) { + arg_trust_all = true; + arg_trust = mfree(arg_trust); + } + log_debug("Full config: SplitMode=%s Key=%s Cert=%s Trust=%s", journal_write_split_mode_to_string(arg_split_mode), strna(arg_key), @@ -1096,7 +1072,7 @@ static int load_certificates(char **key, char **cert, char **trust) { if ((arg_listen_raw || arg_listen_http) && *trust) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Option --trust makes all non-HTTPS connections untrusted."); + "Option --trust= makes all non-HTTPS connections untrusted."); return 0; } diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c index 8b64bc78e9..5b845a520f 100644 --- a/src/journal-remote/journal-remote.c +++ b/src/journal-remote/journal-remote.c @@ -20,6 +20,7 @@ #include "macro.h" #include "managed-journal-file.h" #include "parse-util.h" +#include "parse-helpers.h" #include "process-util.h" #include "socket-util.h" #include "stdio-util.h" @@ -30,11 +31,28 @@ #define filename_escape(s) xescape((s), "/ ") +#if HAVE_MICROHTTPD +MHDDaemonWrapper *MHDDaemonWrapper_free(MHDDaemonWrapper *d) { + if (!d) + return NULL; + + if (d->daemon) + MHD_stop_daemon(d->daemon); + sd_event_source_unref(d->io_event); + sd_event_source_unref(d->timer_event); + + return mfree(d); +} +#endif + static int open_output(RemoteServer *s, Writer *w, const char* host) { _cleanup_free_ char *_filename = NULL; const char *filename; int r; + assert(s); + assert(w); + switch (s->split_mode) { case JOURNAL_WRITE_SPLIT_NONE: filename = s->output; @@ -104,6 +122,9 @@ int journal_remote_get_writer(RemoteServer *s, const char *host, Writer **writer const void *key; int r; + assert(s); + assert(writer); + switch (s->split_mode) { case JOURNAL_WRITE_SPLIT_NONE: key = "one and only"; @@ -172,6 +193,7 @@ static int get_source_for_fd(RemoteServer *s, /* This takes ownership of name, but only on success. */ + assert(s); assert(fd >= 0); assert(source); @@ -275,10 +297,11 @@ int journal_remote_add_source(RemoteServer *s, int fd, char* name, bool own_name } int journal_remote_add_raw_socket(RemoteServer *s, int fd) { - int r; _unused_ _cleanup_close_ int fd_ = fd; char name[STRLEN("raw-socket-") + DECIMAL_STR_MAX(int) + 1]; + int r; + assert(s); assert(fd >= 0); r = sd_event_add_io(s->events, &s->listen_event, @@ -293,7 +316,7 @@ int journal_remote_add_raw_socket(RemoteServer *s, int fd) { if (r < 0) return r; - fd_ = -EBADF; + TAKE_FD(fd_); s->active++; return 0; } @@ -338,18 +361,12 @@ int journal_remote_server_init( return 0; } -#if HAVE_MICROHTTPD -static void MHDDaemonWrapper_free(MHDDaemonWrapper *d) { - MHD_stop_daemon(d->daemon); - sd_event_source_unref(d->io_event); - sd_event_source_unref(d->timer_event); - free(d); -} -#endif - void journal_remote_server_destroy(RemoteServer *s) { size_t i; + if (!s) + return; + #if HAVE_MICROHTTPD hashmap_free_with_destructor(s->daemons, MHDDaemonWrapper_free); #endif @@ -389,6 +406,7 @@ int journal_remote_handle_raw_source( * 0 if data is currently exhausted, negative on error. */ + assert(s); assert(fd >= 0 && fd < (ssize_t) MALLOC_ELEMENTSOF(s->sources)); source = s->sources[fd]; assert(source->importer.fd == fd); @@ -424,9 +442,11 @@ int journal_remote_handle_raw_source( static int dispatch_raw_source_until_block(sd_event_source *event, void *userdata) { - RemoteSource *source = userdata; + RemoteSource *source = ASSERT_PTR(userdata); int r; + assert(event); + /* Make sure event stays around even if source is destroyed */ sd_event_source_ref(event); @@ -449,7 +469,7 @@ static int dispatch_raw_source_event(sd_event_source *event, int fd, uint32_t revents, void *userdata) { - RemoteSource *source = userdata; + RemoteSource *source = ASSERT_PTR(userdata); int r; assert(source->event); @@ -471,7 +491,7 @@ static int dispatch_raw_source_event(sd_event_source *event, static int dispatch_blocking_source_event(sd_event_source *event, void *userdata) { - RemoteSource *source = userdata; + RemoteSource *source = ASSERT_PTR(userdata); return journal_remote_handle_raw_source(event, source->importer.fd, EPOLLIN, journal_remote_server_global); } @@ -485,6 +505,9 @@ static int accept_connection( _cleanup_close_ int fd2 = -EBADF; int r; + assert(addr); + assert(hostname); + log_debug("Accepting new %s connection on fd:%d", type, fd); fd2 = accept4(fd, &addr->sockaddr.sa, &addr->size, SOCK_NONBLOCK|SOCK_CLOEXEC); if (fd2 < 0) { @@ -530,7 +553,7 @@ static int dispatch_raw_connection_event( uint32_t revents, void *userdata) { - RemoteServer *s = userdata; + RemoteServer *s = ASSERT_PTR(userdata); int fd2; SocketAddress addr = { .size = sizeof(union sockaddr_union), diff --git a/src/journal-remote/journal-remote.h b/src/journal-remote/journal-remote.h index 39d0446481..8d73f95dc9 100644 --- a/src/journal-remote/journal-remote.h +++ b/src/journal-remote/journal-remote.h @@ -20,6 +20,9 @@ struct MHDDaemonWrapper { sd_event_source *io_event; sd_event_source *timer_event; }; + +MHDDaemonWrapper *MHDDaemonWrapper_free(MHDDaemonWrapper *d); +DEFINE_TRIVIAL_CLEANUP_FUNC(MHDDaemonWrapper*, MHDDaemonWrapper_free); #endif struct RemoteServer { diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c index fac90d22a2..32da75e598 100644 --- a/src/journal-remote/journal-upload.c +++ b/src/journal-remote/journal-upload.c @@ -518,45 +518,6 @@ static int perform_upload(Uploader *u) { return update_cursor_state(u); } -static int config_parse_path_or_ignore( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - _cleanup_free_ char *n = NULL; - bool fatal = ltype; - char **s = ASSERT_PTR(data); - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - - if (isempty(rvalue)) - goto finalize; - - n = strdup(rvalue); - if (!n) - return log_oom(); - - if (streq(n, "-")) - goto finalize; - - r = path_simplify_and_warn(n, PATH_CHECK_ABSOLUTE | (fatal ? PATH_CHECK_FATAL : 0), unit, filename, line, lvalue); - if (r < 0) - return fatal ? -ENOEXEC : 0; - -finalize: - return free_and_replace(*s, n); -} - static int parse_config(void) { const ConfigTableItem items[] = { { "Upload", "URL", config_parse_string, CONFIG_PARSE_STRING_SAFE, &arg_url }, @@ -663,7 +624,7 @@ static int parse_argv(int argc, char *argv[]) { case 'u': if (arg_url) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "cannot use more than one --url"); + "Cannot use more than one --url="); arg_url = optarg; break; @@ -671,7 +632,7 @@ static int parse_argv(int argc, char *argv[]) { case ARG_KEY: if (arg_key) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "cannot use more than one --key"); + "Cannot use more than one --key="); arg_key = optarg; break; @@ -679,7 +640,7 @@ static int parse_argv(int argc, char *argv[]) { case ARG_CERT: if (arg_cert) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "cannot use more than one --cert"); + "Cannot use more than one --cert="); arg_cert = optarg; break; @@ -687,7 +648,7 @@ static int parse_argv(int argc, char *argv[]) { case ARG_TRUST: if (arg_trust) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "cannot use more than one --trust"); + "Cannot use more than one --trust="); arg_trust = optarg; break; @@ -707,7 +668,7 @@ static int parse_argv(int argc, char *argv[]) { case 'M': if (arg_machine) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "cannot use more than one --machine/-M"); + "Cannot use more than one --machine=/-M"); arg_machine = optarg; break; @@ -715,7 +676,7 @@ static int parse_argv(int argc, char *argv[]) { case 'D': if (arg_directory) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "cannot use more than one --directory/-D"); + "Cannot use more than one --directory=/-D"); arg_directory = optarg; break; @@ -729,7 +690,7 @@ static int parse_argv(int argc, char *argv[]) { case ARG_CURSOR: if (arg_cursor) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "cannot use more than one --cursor/--after-cursor"); + "Cannot use more than one --cursor=/--after-cursor="); arg_cursor = optarg; break; @@ -737,7 +698,7 @@ static int parse_argv(int argc, char *argv[]) { case ARG_AFTER_CURSOR: if (arg_cursor) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "cannot use more than one --cursor/--after-cursor"); + "Cannot use more than one --cursor=/--after-cursor="); arg_cursor = optarg; arg_after_cursor = true; @@ -770,11 +731,11 @@ static int parse_argv(int argc, char *argv[]) { if (!arg_url) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Required --url/-u option missing."); + "Required --url=/-u option missing."); if (!!arg_key != !!arg_cert) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Options --key and --cert must be used together."); + "Options --key= and --cert= must be used together."); if (optind < argc && (arg_directory || arg_file || arg_machine || arg_journal_type)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), diff --git a/src/shared/parse-helpers.c b/src/shared/parse-helpers.c index e09797bbf1..f48baf7146 100644 --- a/src/shared/parse-helpers.c +++ b/src/shared/parse-helpers.c @@ -196,3 +196,42 @@ int parse_socket_bind_item( *port_min = mn; return 0; } + +int config_parse_path_or_ignore( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_free_ char *n = NULL; + bool fatal = ltype; + char **s = ASSERT_PTR(data); + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) + goto finalize; + + n = strdup(rvalue); + if (!n) + return log_oom(); + + if (streq(n, "-")) + goto finalize; + + r = path_simplify_and_warn(n, PATH_CHECK_ABSOLUTE | (fatal ? PATH_CHECK_FATAL : 0), unit, filename, line, lvalue); + if (r < 0) + return fatal ? -ENOEXEC : 0; + +finalize: + return free_and_replace(*s, n); +} diff --git a/src/shared/parse-helpers.h b/src/shared/parse-helpers.h index 49da2815fb..38a47e85c3 100644 --- a/src/shared/parse-helpers.h +++ b/src/shared/parse-helpers.h @@ -23,3 +23,15 @@ int parse_socket_bind_item( int *ip_protocol, uint16_t *nr_ports, uint16_t *port_min); + +int config_parse_path_or_ignore( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata); diff --git a/sysusers.d/systemd-remote.conf b/sysusers.d/systemd-remote.conf index ca20c24896..341ae4e0a1 100644 --- a/sysusers.d/systemd-remote.conf +++ b/sysusers.d/systemd-remote.conf @@ -6,3 +6,4 @@ # (at your option) any later version. u systemd-journal-remote - "systemd Journal Remote" +u systemd-journal-upload - "systemd Journal Upload" diff --git a/test/units/testsuite-04.journal-gatewayd.sh b/test/units/testsuite-04.journal-gatewayd.sh index 1efdc3cae0..75f51dd745 100755 --- a/test/units/testsuite-04.journal-gatewayd.sh +++ b/test/units/testsuite-04.journal-gatewayd.sh @@ -57,7 +57,13 @@ curl -Lfs --header "Accept: text/event-stream" http://localhost:19531/entries | # Same thing as journalctl --output=export mkdir /tmp/remote-journal curl -Lfs --header "Accept: application/vnd.fdo.journal" http://localhost:19531/entries | \ - /usr/lib/systemd/systemd-journal-remote -o /tmp/remote-journal/system.journal --split-mode=none - + /usr/lib/systemd/systemd-journal-remote --output=/tmp/remote-journal/system.journal --split-mode=none - +journalctl --directory=/tmp/remote-journal -t "$TEST_TAG" --grep "$TEST_MESSAGE" +rm -rf /tmp/remote-journal/* +# Let's do the same thing again, but let systemd-journal-remote spawn curl itself +/usr/lib/systemd/systemd-journal-remote --url=http://localhost:19531/entries \ + --output=/tmp/remote-journal/system.journal \ + --split-mode=none journalctl --directory=/tmp/remote-journal -t "$TEST_TAG" --grep "$TEST_MESSAGE" rm -rf /tmp/remote-journal diff --git a/test/units/testsuite-04.journal-remote.sh b/test/units/testsuite-04.journal-remote.sh new file mode 100755 index 0000000000..6bdc3ccdec --- /dev/null +++ b/test/units/testsuite-04.journal-remote.sh @@ -0,0 +1,216 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +# shellcheck disable=SC2016 +set -eux +set -o pipefail + +if [[ ! -x /usr/lib/systemd/systemd-journal-remote || ! -x /usr/lib/systemd/systemd-journal-upload ]]; then + echo "Built without systemd-journal-remote/upload support, skipping the test" + exit 0 +fi + +if ! command -v openssl >/dev/null; then + echo "openssl command not available, skipping the tests" + exit 0 +fi + +at_exit() { + set +e + + systemctl stop systemd-journal-upload + systemctl stop systemd-journal-remote.{socket,service} + # Remove any remote journals on exit, so we don't try to export them together + # with the local journals, causing a mess + rm -rf /var/log/journal/remote +} + +trap at_exit EXIT + +TEST_MESSAGE="-= This is a test message $RANDOM =-" +TEST_TAG="$(systemd-id128 new)" + +echo "$TEST_MESSAGE" | systemd-cat -t "$TEST_TAG" +journalctl --sync + +/usr/lib/systemd/systemd-journal-remote --version +/usr/lib/systemd/systemd-journal-remote --help +/usr/lib/systemd/systemd-journal-upload --version +/usr/lib/systemd/systemd-journal-upload --help + +# Generate a self-signed certificate for systemd-journal-remote +# +# Note: older OpenSSL requires a config file with some extra options, unfortunately +# Note2: /run here is used on purpose, since the systemd-journal-remote service uses PrivateTmp=yes +mkdir -p /run/systemd/journal-remote-tls +cat >/tmp/openssl.conf </run/systemd/journal-remote.conf.d/99-test.conf </run/systemd/journal-upload.conf.d/99-test.conf </run/systemd/remote-pki/ca.conf </run/systemd/remote-pki/client.conf </run/systemd/remote-pki/server.conf </run/systemd/remote-pki/ca.srl +# Generate a client key and signing request +openssl req -nodes -newkey rsa:2048 -sha256 \ + -config /run/systemd/remote-pki/client.conf \ + -keyout /run/systemd/remote-pki/client.key \ + -out /run/systemd/remote-pki/client.csr +# Sign the request with the CA key +openssl x509 -req -days 7 \ + -in /run/systemd/remote-pki/client.csr \ + -CA /run/systemd/remote-pki/ca.crt \ + -CAkey /run/systemd/remote-pki/ca.key \ + -out /run/systemd/remote-pki/client.crt +# And do the same for the server +openssl req -nodes -newkey rsa:2048 -sha256 \ + -config /run/systemd/remote-pki/server.conf \ + -keyout /run/systemd/remote-pki/server.key \ + -out /run/systemd/remote-pki/server.csr +openssl x509 -req -days 7 \ + -in /run/systemd/remote-pki/server.csr \ + -CA /run/systemd/remote-pki/ca.crt \ + -CAkey /run/systemd/remote-pki/ca.key \ + -out /run/systemd/remote-pki/server.crt +setfacl -R -m "u:systemd-journal-remote:rwX" /run/systemd/remote-pki +setfacl -R -m "u:systemd-journal-upload:rwX" /run/systemd/remote-pki + +# Reconfigure journal-upload/journal remote with the new keys +cat >/run/systemd/journal-remote.conf.d/99-test.conf </run/systemd/journal-upload.conf.d/99-test.conf </run/systemd/journal-upload.conf.d/99-test.conf <