2023-06-19 17:12:39 +02:00
#!/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 <<EOF
[ req ]
prompt = no
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
C = CZ
L = Brno
O = Foo
OU = Bar
CN = localhost
EOF
openssl req -x509 -nodes -newkey rsa:2048 -sha256 -days 7 \
-config /tmp/openssl.conf \
-keyout /run/systemd/journal-remote-tls/key.pem \
-out /run/systemd/journal-remote-tls/cert.pem
chown -R systemd-journal-remote /run/systemd/journal-remote-tls
# Configure journal-upload to upload journals to journal-remote without client certificates
mkdir -p /run/systemd/journal-{ remote,upload} .conf.d
cat >/run/systemd/journal-remote.conf.d/99-test.conf <<EOF
[ Remote]
SplitMode = host
ServerKeyFile = /run/systemd/journal-remote-tls/key.pem
ServerCertificateFile = /run/systemd/journal-remote-tls/cert.pem
TrustedCertificateFile = -
EOF
cat >/run/systemd/journal-upload.conf.d/99-test.conf <<EOF
[ Upload]
URL = https://localhost:19532
ServerKeyFile = -
ServerCertificateFile = -
TrustedCertificateFile = -
EOF
systemd-analyze cat-config systemd/journal-remote.conf
systemd-analyze cat-config systemd/journal-upload.conf
systemctl restart systemd-journal-remote.socket
systemctl restart systemd-journal-upload
2023-09-06 14:51:07 +02:00
timeout 15 bash -xec 'until systemctl -q is-active systemd-journal-remote.service; do sleep 1; done'
2023-06-19 17:12:39 +02:00
systemctl status systemd-journal-{ remote,upload}
# It may take a bit until the whole journal is transferred
2023-09-06 14:51:07 +02:00
timeout 30 bash -xec " until journalctl --directory=/var/log/journal/remote --identifier=' $TEST_TAG ' --grep=' $TEST_MESSAGE '; do sleep 1; done "
2023-06-19 17:12:39 +02:00
systemctl stop systemd-journal-upload
systemctl stop systemd-journal-remote.{ socket,service}
rm -rf /var/log/journal/remote/*
# Now let's do the same, but with a full PKI setup
#
# journal-upload keeps the cursor of the last uploaded message, so let's send a fresh one
echo " $TEST_MESSAGE " | systemd-cat -t " $TEST_TAG "
journalctl --sync
mkdir /run/systemd/remote-pki
cat >/run/systemd/remote-pki/ca.conf <<EOF
[ req ]
prompt = no
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
C = CZ
L = Brno
O = Foo
OU = Bar
CN = Test CA
test: make sure the dummy CA certificate is marked as such
With OpenSSL 3.2.0+ this is necessary, otherwise the verification
of such CA certificate fails badly:
$ openssl s_client -CAfile /run/systemd/remote-pki/ca.crt -connect localhost:19532
...
Connecting to ::1
CONNECTED(00000003)
Can't use SSL_get_servername
depth=1 C=CZ, L=Brno, O=Foo, OU=Bar, CN=Test CA
verify error:num=79:invalid CA certificate
verify return:1
depth=1 C=CZ, L=Brno, O=Foo, OU=Bar, CN=Test CA
verify error:num=26:unsuitable certificate purpose
verify return:1
...
---
SSL handshake has read 1566 bytes and written 409 bytes
Verification error: unsuitable certificate purpose
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
This TLS version forbids renegotiation.
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 26 (unsuitable certificate purpose)
2023-12-23 13:33:11 +01:00
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
basicConstraints = CA:true
2023-06-19 17:12:39 +02:00
EOF
cat >/run/systemd/remote-pki/client.conf <<EOF
[ req ]
prompt = no
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
C = CZ
L = Brno
O = Foo
OU = Bar
CN = Test Client
EOF
cat >/run/systemd/remote-pki/server.conf <<EOF
[ req ]
prompt = no
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
C = CZ
L = Brno
O = Foo
OU = Bar
CN = localhost
EOF
# Generate a dummy CA
openssl req -x509 -nodes -newkey rsa:2048 -sha256 -days 7 \
test: make sure the dummy CA certificate is marked as such
With OpenSSL 3.2.0+ this is necessary, otherwise the verification
of such CA certificate fails badly:
$ openssl s_client -CAfile /run/systemd/remote-pki/ca.crt -connect localhost:19532
...
Connecting to ::1
CONNECTED(00000003)
Can't use SSL_get_servername
depth=1 C=CZ, L=Brno, O=Foo, OU=Bar, CN=Test CA
verify error:num=79:invalid CA certificate
verify return:1
depth=1 C=CZ, L=Brno, O=Foo, OU=Bar, CN=Test CA
verify error:num=26:unsuitable certificate purpose
verify return:1
...
---
SSL handshake has read 1566 bytes and written 409 bytes
Verification error: unsuitable certificate purpose
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
This TLS version forbids renegotiation.
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 26 (unsuitable certificate purpose)
2023-12-23 13:33:11 +01:00
-extensions v3_ca \
2023-06-19 17:12:39 +02:00
-config /run/systemd/remote-pki/ca.conf \
-keyout /run/systemd/remote-pki/ca.key \
-out /run/systemd/remote-pki/ca.crt
test: make sure the dummy CA certificate is marked as such
With OpenSSL 3.2.0+ this is necessary, otherwise the verification
of such CA certificate fails badly:
$ openssl s_client -CAfile /run/systemd/remote-pki/ca.crt -connect localhost:19532
...
Connecting to ::1
CONNECTED(00000003)
Can't use SSL_get_servername
depth=1 C=CZ, L=Brno, O=Foo, OU=Bar, CN=Test CA
verify error:num=79:invalid CA certificate
verify return:1
depth=1 C=CZ, L=Brno, O=Foo, OU=Bar, CN=Test CA
verify error:num=26:unsuitable certificate purpose
verify return:1
...
---
SSL handshake has read 1566 bytes and written 409 bytes
Verification error: unsuitable certificate purpose
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
This TLS version forbids renegotiation.
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 26 (unsuitable certificate purpose)
2023-12-23 13:33:11 +01:00
openssl x509 -in /run/systemd/remote-pki/ca.crt -noout -text
2023-06-19 17:12:39 +02:00
echo 01 >/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
2023-12-04 21:33:15 +01:00
chown -R systemd-journal-remote:systemd-journal /run/systemd/remote-pki
chmod -R g+rwX /run/systemd/remote-pki
2023-06-19 17:12:39 +02:00
# Reconfigure journal-upload/journal remote with the new keys
cat >/run/systemd/journal-remote.conf.d/99-test.conf <<EOF
[ Remote]
SplitMode = host
ServerKeyFile = /run/systemd/remote-pki/server.key
ServerCertificateFile = /run/systemd/remote-pki/server.crt
TrustedCertificateFile = /run/systemd/remote-pki/ca.crt
EOF
cat >/run/systemd/journal-upload.conf.d/99-test.conf <<EOF
[ Upload]
URL = https://localhost:19532
ServerKeyFile = /run/systemd/remote-pki/client.key
ServerCertificateFile = /run/systemd/remote-pki/client.crt
TrustedCertificateFile = /run/systemd/remote-pki/ca.crt
EOF
systemd-analyze cat-config systemd/journal-remote.conf
systemd-analyze cat-config systemd/journal-upload.conf
systemctl restart systemd-journal-remote.socket
systemctl restart systemd-journal-upload
2023-09-06 14:51:07 +02:00
timeout 15 bash -xec 'until systemctl -q is-active systemd-journal-remote.service; do sleep 1; done'
2023-06-19 17:12:39 +02:00
systemctl status systemd-journal-{ remote,upload}
# It may take a bit until the whole journal is transferred
2023-09-06 14:51:07 +02:00
timeout 30 bash -xec " until journalctl --directory=/var/log/journal/remote --identifier=' $TEST_TAG ' --grep=' $TEST_MESSAGE '; do sleep 1; done "
2023-06-19 17:12:39 +02:00
systemctl stop systemd-journal-upload
systemctl stop systemd-journal-remote.{ socket,service}
# Let's test if journal-remote refuses connection from journal-upload with invalid client certs
#
# We should end up with something like this:
# systemd-journal-remote[726]: Client is not authorized
# systemd-journal-upload[738]: Upload to https://localhost:19532/upload failed with code 401:
# systemd[1]: systemd-journal-upload.service: Main process exited, code=exited, status=1/FAILURE
# systemd[1]: systemd-journal-upload.service: Failed with result 'exit-code'.
#
cat >/run/systemd/journal-upload.conf.d/99-test.conf <<EOF
[ Upload]
URL = https://localhost:19532
ServerKeyFile = /run/systemd/journal-remote-tls/key.pem
ServerCertificateFile = /run/systemd/journal-remote-tls/cert.pem
TrustedCertificateFile = /run/systemd/remote-pki/ca.crt
EOF
systemd-analyze cat-config systemd/journal-upload.conf
2023-10-17 12:49:03 +02:00
mkdir -p /run/systemd/system/systemd-journal-upload.service.d
cat >/run/systemd/system/systemd-journal-upload.service.d/99-test.conf <<EOF
[ Service]
Restart = no
EOF
systemctl daemon-reload
2023-12-04 21:33:15 +01:00
chgrp -R systemd-journal /run/systemd/journal-remote-tls
chmod -R g+rwX /run/systemd/journal-remote-tls
2023-06-19 17:12:39 +02:00
systemctl restart systemd-journal-upload
timeout 10 bash -xec 'while [[ "$(systemctl show -P ActiveState systemd-journal-upload)" != failed ]]; do sleep 1; done'
( ! systemctl status systemd-journal-upload)