Skip to content

Instantly share code, notes, and snippets.

@ktsaou
Last active October 15, 2023 23:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ktsaou/d62b8a6501cf9a0da94f03cbbb71c5c7 to your computer and use it in GitHub Desktop.
Save ktsaou/d62b8a6501cf9a0da94f03cbbb71c5c7 to your computer and use it in GitHub Desktop.
systemd-journal-remote/upload self-signed certificates management script
#!/usr/bin/env bash
# The directory to save the generated certificates (and everything about this certificate authority).
# This is only used on the node generating the certificates (usually on the journals server).
DIR="/etc/ssl/systemd-journal-remote"
# The journals centralization server name (the CN of the server certificate).
SERVER="server-hostname"
# All the DNS names or IPs this server is reachable at (the certificate will include them).
# Journal clients can use any of them to connect to this server.
# systemd-journal-upload validates its URL= hostname, against this list.
SERVER_ALIASES=("DNS:server-hostname1" "DNS:server-hostname2" "IP:1.2.3.4" "IP:10.1.1.1" "IP:172.16.1.1")
# All the names of the journal clients that will be sending logs to the server (the CNs of their certificates).
# These names are used by systemd-journal-remote to name the journal files in /var/log/journal/remote/.
# Also the remote hosts will be presented using these names on Netdata dashboards.
CLIENTS=("vm1" "vm2" "vm3" "add_as_may_as_needed")
# stop on all errors
set -e
if [ $UID -ne 0 ]
then
echo >&2 "Hey! sudo me: sudo ${0}"
exit 1
fi
if [ ! -d "${DIR}" ]
then
mkdir -p "${DIR}"
chgrp systemd-journal-remote "${DIR}"
chmod 750 "${DIR}"
fi
cd "${DIR}"
# -----------------------------------------------------------------------------
# Create the CA
test ! -f ca.conf && cat >ca.conf <<EOF
[ ca ]
default_ca = CA_default
[ CA_default ]
new_certs_dir = .
certificate = ca.pem
database = ./index
private_key = ca.key
serial = ./serial
default_days = 3650
default_md = default
policy = policy_anything
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
EOF
test ! -f index && touch index
test ! -f serial && echo 0001 >serial
if [ ! -f ca.pem -o ! -f ca.key ]
then
echo >&2 "Generating ca.pem ..."
openssl req -newkey rsa:2048 -days 3650 -x509 -nodes -out ca.pem -keyout ca.key -subj "/CN=systemd-journal-remote-ca/"
chgrp systemd-journal-remote ca.pem
chmod 0640 ca.pem
fi
# -----------------------------------------------------------------------------
# Create the server certificate
if [ ! -f "${SERVER}.pem" -o ! -f "${SERVER}.key" ]
then
echo "subjectAltName = $(echo "${SERVER_ALIASES[*]}" | tr " " ",")" >"${SERVER}.conf"
echo >&2 "Generating ${SERVER}.pem and ${SERVER}.key ..."
openssl req -newkey rsa:2048 -nodes -out "${SERVER}.csr" -keyout "${SERVER}.key" -subj "/CN=${SERVER}/"
openssl ca -batch -config ca.conf -notext -in "${SERVER}.csr" -out "${SERVER}.pem" -extfile "${SERVER}.conf"
chgrp systemd-journal-remote "${SERVER}.pem" "${SERVER}.key"
chmod 0640 "${SERVER}.pem" "${SERVER}.key"
fi
# -----------------------------------------------------------------------------
# Create the client certificates
for x in "${CLIENTS[@]}"
do
if [ ! -f "${x}.pem" -o ! -f "${x}.key" ]
then
echo >&2 "Generating ${x}.pem and ${x}.key ..."
openssl req -newkey rsa:2048 -nodes -out "${x}.csr" -keyout "${x}.key" -subj "/CN=${x}/"
openssl ca -batch -config ca.conf -notext -in "${x}.csr" -out "${x}.pem"
chgrp systemd-journal-remote "${x}.pem" "${x}.key"
chmod 0640 "${x}.pem" "${x}.key"
fi
done
# -----------------------------------------------------------------------------
# Create the client installation script
for x in "${SERVER}" "${CLIENTS[@]}"
do
svc="systemd-journal-upload"
group="systemd-journal-upload"
config="/etc/systemd/journal-upload.conf"
dst="/etc/ssl/systemd-journal-upload"
if [ "${x}" = "${SERVER}" ]
then
svc="systemd-journal-remote.socket"
dst="/etc/ssl/systemd-journal-remote"
group="systemd-journal-remote"
config="/etc/systemd/journal-remote.conf"
fi
cat >runme-on-${x}.sh <<EOFC1
#!/usr/bin/env bash
if [ \$UID -ne 0 ]
then
echo >&2 "Hey! sudo me: sudo \${0}"
exit 1
fi
getent passwd ${group} >/dev/null 2>&1 || \
adduser --system --home /run/systemd --no-create-home --disabled-login --group ${group}
set -e
mkdir -p "${dst}"
chgrp ${group} "${dst}"
chmod 750 "${dst}"
cd "${dst}"
cat >ca.pem <<EOFCAPEM
$(cat ca.pem)
EOFCAPEM
chgrp ${group} ca.pem
chmod 0640 ca.pem
cat >"${x}.pem" <<EOFCLIENTPEM
$(cat $x.pem)
EOFCLIENTPEM
chgrp ${group} "${x}.pem"
chmod 0640 "${x}.pem"
cat >"${x}.key" <<EOFCLIENTKEY
$(cat $x.key)
EOFCLIENTKEY
chgrp ${group} "${x}.key"
chmod 0640 "${x}.key"
# keep a backup of the file
test ! -f ${config}.orig && cp ${config} ${config}.orig
# fix its contents
sed -i "s|^#\\?\\s*ServerKeyFile=.*$|ServerKeyFile=${dst}/${x}.key|" ${config}
sed -i "s|^#\\?\\s*ServerCertificateFile=.*$|ServerCertificateFile=${dst}/${x}.pem|" ${config}
sed -i "s|^#\\?\\s*TrustedCertificateFile=.*$|TrustedCertificateFile=${dst}/ca.pem|" ${config}
systemctl restart ${svc}
systemctl status ${svc}
EOFC1
chmod 0700 runme-on-${x}.sh
done
echo >&2
echo >&2 "ALL DONE"
echo >&2 "Check the runme-on-XXX.sh scripts..."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment