swarm-bao: fail the unit when the services root cannot be read, instead of replacing it
A failed `bao read` of the services root made the checkend pipeline non-zero, so the unit deleted a working root and minted a new trust anchor. A failed `bao list` of the issuers likewise looked like an empty mount. Both now fail the unit, which retries on its own restart budget; the root is replaced only when openssl parsed the returned certificate and -checkend said it expires inside a leaf's window. Closes #4663
This commit is contained in:
parent
c0c031a5e4
commit
5b54b6ddc8
1 changed files with 29 additions and 15 deletions
|
|
@ -1893,11 +1893,11 @@ in
|
|||
# The mount's own issuer list is the only answer that cannot be
|
||||
# stale.
|
||||
#
|
||||
# `bao list ${servicesPkiMountPath}/issuers` is a 404 (non-zero) on a
|
||||
# mount with no issuer and a key list once one exists, so its exit
|
||||
# status IS the question — no output parsing, no error string to
|
||||
# recognise. The default issuer is what `${servicesPkiMountPath}/issue/`
|
||||
# signs with, and there is exactly one.
|
||||
# `bao list` exits 2 both on a mount with no issuer and on a request
|
||||
# that failed, so its exit status cannot tell them apart. Under
|
||||
# `-format=json` only the empty mount prints `{}`. The default
|
||||
# issuer is what `${servicesPkiMountPath}/issue/` signs with, and
|
||||
# there is exactly one.
|
||||
#
|
||||
# "Never twice" is the rule; "an issuer that cannot issue" is not a
|
||||
# case it was written for. A root with less than a leaf's window left
|
||||
|
|
@ -1907,17 +1907,31 @@ in
|
|||
# the asymmetry: this replaces a root that is already useless, and
|
||||
# still never touches one a leaf can be issued under.
|
||||
regenerate=0
|
||||
if ! bao list ${lib.escapeShellArg "${servicesPkiMountPath}/issuers"} >/dev/null 2>&1; then
|
||||
regenerate=1
|
||||
elif ! bao read -field=certificate ${lib.escapeShellArg "${servicesPkiMountPath}/cert/ca"} \
|
||||
| openssl x509 -noout -checkend ${toString servicesPkiLeafTtlSeconds} >/dev/null 2>&1; then
|
||||
echo "the ${servicesPkiMountPath} root cannot outlive a ${servicesPkiLeafTtl} leaf — replacing it" >&2
|
||||
# `root` rather than the named issuer: the replacement re-uses
|
||||
# `issuer_name`, and generating into a name already in use is a
|
||||
# refusal. Clears the mount's keys with it, which is the whole of
|
||||
# what it holds — one issuer, by the design above.
|
||||
bao delete ${lib.escapeShellArg "${servicesPkiMountPath}/root"} >/dev/null
|
||||
if issuers="$(bao list -format=json ${lib.escapeShellArg "${servicesPkiMountPath}/issuers"})"; then
|
||||
# A root this unit could not read is not known to be useless, so
|
||||
# every step before `-checkend` fails the unit, and the unit retries.
|
||||
if ! root_ca="$(bao read -field=certificate ${lib.escapeShellArg "${servicesPkiMountPath}/cert/ca"})"; then
|
||||
echo "could not read the ${servicesPkiMountPath} root — leaving it in place" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! openssl x509 -noout <<<"$root_ca" >/dev/null 2>&1; then
|
||||
echo "the ${servicesPkiMountPath} root that bao returned does not parse — leaving it in place" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! openssl x509 -noout -checkend ${toString servicesPkiLeafTtlSeconds} <<<"$root_ca" >/dev/null 2>&1; then
|
||||
echo "the ${servicesPkiMountPath} root cannot outlive a ${servicesPkiLeafTtl} leaf — replacing it" >&2
|
||||
# `root` rather than the named issuer: the replacement re-uses
|
||||
# `issuer_name`, and generating into a name already in use is a
|
||||
# refusal. Clears the mount's keys with it, which is the whole of
|
||||
# what it holds — one issuer, by the design above.
|
||||
bao delete ${lib.escapeShellArg "${servicesPkiMountPath}/root"} >/dev/null
|
||||
regenerate=1
|
||||
fi
|
||||
elif [ "$issuers" = '{}' ]; then
|
||||
regenerate=1
|
||||
else
|
||||
echo "could not list the ${servicesPkiMountPath} issuers — not minting a root over one that may exist" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$regenerate" = 1 ]; then
|
||||
|
|
|
|||
Loading…
Reference in a new issue