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
|
# The mount's own issuer list is the only answer that cannot be
|
||||||
# stale.
|
# stale.
|
||||||
#
|
#
|
||||||
# `bao list ${servicesPkiMountPath}/issuers` is a 404 (non-zero) on a
|
# `bao list` exits 2 both on a mount with no issuer and on a request
|
||||||
# mount with no issuer and a key list once one exists, so its exit
|
# that failed, so its exit status cannot tell them apart. Under
|
||||||
# status IS the question — no output parsing, no error string to
|
# `-format=json` only the empty mount prints `{}`. The default
|
||||||
# recognise. The default issuer is what `${servicesPkiMountPath}/issue/`
|
# issuer is what `${servicesPkiMountPath}/issue/` signs with, and
|
||||||
# signs with, and there is exactly one.
|
# there is exactly one.
|
||||||
#
|
#
|
||||||
# "Never twice" is the rule; "an issuer that cannot issue" is not a
|
# "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
|
# 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
|
# the asymmetry: this replaces a root that is already useless, and
|
||||||
# still never touches one a leaf can be issued under.
|
# still never touches one a leaf can be issued under.
|
||||||
regenerate=0
|
regenerate=0
|
||||||
if ! bao list ${lib.escapeShellArg "${servicesPkiMountPath}/issuers"} >/dev/null 2>&1; then
|
if issuers="$(bao list -format=json ${lib.escapeShellArg "${servicesPkiMountPath}/issuers"})"; then
|
||||||
regenerate=1
|
# A root this unit could not read is not known to be useless, so
|
||||||
elif ! bao read -field=certificate ${lib.escapeShellArg "${servicesPkiMountPath}/cert/ca"} \
|
# every step before `-checkend` fails the unit, and the unit retries.
|
||||||
| openssl x509 -noout -checkend ${toString servicesPkiLeafTtlSeconds} >/dev/null 2>&1; then
|
if ! root_ca="$(bao read -field=certificate ${lib.escapeShellArg "${servicesPkiMountPath}/cert/ca"})"; then
|
||||||
echo "the ${servicesPkiMountPath} root cannot outlive a ${servicesPkiLeafTtl} leaf — replacing it" >&2
|
echo "could not read the ${servicesPkiMountPath} root — leaving it in place" >&2
|
||||||
# `root` rather than the named issuer: the replacement re-uses
|
exit 1
|
||||||
# `issuer_name`, and generating into a name already in use is a
|
fi
|
||||||
# refusal. Clears the mount's keys with it, which is the whole of
|
if ! openssl x509 -noout <<<"$root_ca" >/dev/null 2>&1; then
|
||||||
# what it holds — one issuer, by the design above.
|
echo "the ${servicesPkiMountPath} root that bao returned does not parse — leaving it in place" >&2
|
||||||
bao delete ${lib.escapeShellArg "${servicesPkiMountPath}/root"} >/dev/null
|
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
|
regenerate=1
|
||||||
|
else
|
||||||
|
echo "could not list the ${servicesPkiMountPath} issuers — not minting a root over one that may exist" >&2
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$regenerate" = 1 ]; then
|
if [ "$regenerate" = 1 ]; then
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue