Last active
October 6, 2024 20:17
-
-
Save ktsaou/d62b8a6501cf9a0da94f03cbbb71c5c7 to your computer and use it in GitHub Desktop.
systemd-journal-remote/upload self-signed certificates management script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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