From 9b4fb1c6ba733268a64e252ff80610263696666b Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 2 Oct 2024 10:26:09 +0200 Subject: [SS?S] slx-cert: More sanity checks, add a few comments --- .../static_files/lighttpd/opt/openslx/slx-cert | 71 ++++++++++++---------- 1 file changed, 40 insertions(+), 31 deletions(-) (limited to 'satellit_installer') diff --git a/satellit_installer/static_files/lighttpd/opt/openslx/slx-cert b/satellit_installer/static_files/lighttpd/opt/openslx/slx-cert index b2dd5cb..f721bde 100755 --- a/satellit_installer/static_files/lighttpd/opt/openslx/slx-cert +++ b/satellit_installer/static_files/lighttpd/opt/openslx/slx-cert @@ -98,14 +98,23 @@ create_conf () { MYCA } +checkend () { + # Only print errors to make script output nicer + openssl x509 -checkend "$1" -noout -in "$2" | grep -vFx 'Certificate will not expire' + return "${PIPESTATUS[0]}" +} + +# If we encounter an unexpected error later on during certificate generation, we'll +# wipe everything *once* and restart the script. This function makes sure we don't +# end up in an infinite loop should this not resolve the underlying problem. declare -ag cmdargs=( "$@" ) maybe_restart () { for i in "${cmdargs[@]}"; do - [ "$i" = "--restart" ] && exit 13 + [ "$i" = "--not-again" ] && exit 13 done echo "Restating script, wiping everything except CAs..." rm -f -- /etc/ssl/openslx/*/{srv,int}* - exec "$0" "${cmdargs[@]}" --restart + exec "$0" "${cmdargs[@]}" --not-again exit 14 } @@ -126,14 +135,15 @@ for i in "${PRIVDIR}"/ca-??????????.key; do fi cert="${CERTDIR}/ca-${ts}.crt" if ! [ -s "$cert" ] \ - || (( ts < NOW )); then + || (( ts < NOW )) \ + || ! checkend 600 "$cert"; then # Missing cert, or expired -> delete rm -f -- "$cert" "$i" continue fi # Check if key and cert match if [ "$( openssl x509 -in "$cert" -noout -pubkey )" != "$( openssl pkey -in "$i" -pubout )" ]; then - echo "Publickey in cert doesn't match publickey in keypair: $cert + $i" + echo "Publickey in CA-cert doesn't match publickey in keypair: $cert + $i" rm -f -- "$cert" "$i" continue fi @@ -189,26 +199,13 @@ if [ -n "$mknew" ] || ! [ -s "/opt/openslx/configs/modules/self-signed-ca.tar" ] ) fi -# Now check the server certificate -# First, check if we could still use old-style certs with intermediate -declare -a unt_list=() -for i in "${CERTDIR}"/intermediate-??????????.crt; do - [ -s "$i" ] || continue - if ! get_ts "$i"; then - echo "Invalid intermediate cert: $i" - rm -f -- "$i" - continue - fi - if (( ts < NOW )); then - echo "Expired intermediate: $i" - rm -f -- "$i" - continue - fi - unt_list+=( "-untrusted" "$i" ) -done +# Never worked properly anyways, from Sat 3.9, wipe and start over if required +rm -rf -- "${CERTDIR}"/intermediate-??????????.crt -# Now check existing server certs -have_srv= +# Now check existing server certs. Delete those about to expire soon, or +# where we can't find a matching CA. +makenew= +have_srv= # Will be set to 1 if we have at least one proper cert with enough lifetime left for i in "${PRIVDIR}"/srv-??????????.key; do [ -s "$i" ] || continue if ! get_ts "$i"; then @@ -217,21 +214,24 @@ for i in "${PRIVDIR}"/srv-??????????.key; do continue fi cert="${CERTDIR}/srv-${ts}.crt" - if (( ts < NOW + srv_min_remain_s )) || ! [ -s "$cert" ]; then + if (( ts < NOW + srv_min_remain_s )) \ + || ! [ -s "$cert" ] \ + || ! checkend "$srv_min_remain_s" "$cert"; then echo "Expired srv cert or key with no cert: $i" rm -f -- "$i" "$cert" continue fi # Keys match? if [ "$( openssl x509 -in "$cert" -noout -pubkey )" != "$( openssl pkey -in "$i" -pubout )" ]; then - echo "Publickey in cert doesn't match publickey in keypair: $cert + $i" + # This should actually never happen, but who knows... + echo "Publickey in SRV-cert doesn't match publickey in keypair: $cert + $i" rm -f -- "$cert" "$i" continue fi # Validate chain valid= for ca in "${ca_list[@]}"; do - if openssl verify -CAfile "$ca" "${unt_list[@]}" \ + if openssl verify -CAfile "$ca" \ "$cert" &> /dev/null; then valid=1 break @@ -245,9 +245,11 @@ for i in "${PRIVDIR}"/srv-??????????.key; do rm -f -- "$i" "$cert" done -# Now still check the current lighttpd config, in case it is out of sync -# with our generated stuff for whatever reason. -if [ -n "$have_srv" ] || [ -z "$makenew" ]; then +# Now still check the current combined pem for lighttpd, in case it is out of sync +# with our source data for whatever reason. +if [ -n "$have_srv" ] && ! [ -s "${LIGHTDIR}/server.pem" ]; then + makenew=1 +elif [ -n "$have_srv" ] || [ -z "$makenew" ]; then if [ -s "${LIGHTDIR}/ca-chain.pem" ]; then # Don't need this anymore, it never worked as separate file anyways, so make new rm -f -- "${LIGHTDIR}/ca-chain.pem" @@ -260,7 +262,10 @@ if [ -n "$have_srv" ] || [ -z "$makenew" ]; then break done if [ -z "$valid" ]; then - echo "Current lighttpd SSL setup seems invalid, making new one" + echo "Current lighttpd SSL setup seems invalid, no matching CA for cert; making new one" + makenew=1 + elif ! checkend 86400 "${LIGHTDIR}/server.pem"; then + echo 'Current lighttpd SSL cert is expired, out of sync!? Making new one' makenew=1 fi fi @@ -312,9 +317,13 @@ if [ -z "$have_srv" ] || [ -n "$makenew" ]; then # Combine cert and key, as required by (older) lighttpd echo "Writing out lighttpd PEMs..." - cat "${CERTDIR}/srv-${srv_new_ts}.crt" "${PRIVDIR}/srv-${srv_new_ts}.key" > "${LIGHTDIR}/server.pem" || exit 10 + cat "${CERTDIR}/srv-${srv_new_ts}.crt" \ + "${PRIVDIR}/srv-${srv_new_ts}.key" \ + > "${LIGHTDIR}/server.pem" \ + || exit 10 chmod 0600 "${LIGHTDIR}/server.pem" + # Restart automatically only if requested, or running from terminal if [ "$1" = "--restart" ] || [ -t 0 ]; then echo "Restarting lighttpd..." systemctl restart lighttpd.service -- cgit v1.2.3-55-g7522