Add optional healthcheck heartbeat

The check is silent by design on a healthy host, so an absent alert is
indistinguishable from a cron that stopped running. Ping HEALTHCHECK_URL
on a clean run and the /fail endpoint when the check alerts or cannot
complete. Empty by default, which disables the pings.
This commit is contained in:
Walusimbi Silver
2026-09-03 14:35:28 +03:00
parent 4950a0e50b
commit 3b797bb4e5
2 changed files with 35 additions and 0 deletions

View File

@@ -44,6 +44,7 @@ ALERT_ON_NO_CERTS=true
CHECK_SERVED=true
SERVED_ADDR=127.0.0.1:443
SERVED_TIMEOUT=10
HEALTHCHECK_URL=
```
### Served certificate check
@@ -102,3 +103,20 @@ alerting path.
For jobs where silence is also a failure, pair ntfy with a dead man's switch such
as Healthchecks. ntfy tells you what the script found; Healthchecks tells you when
the script did not run at all.
Set `HEALTHCHECK_URL` to enable it. The script pings that URL after a clean run
and `$HEALTHCHECK_URL/fail` when it alerts or cannot complete the check, so a
dead cron, a bad chmod or a host that never came back up stops looking like a
healthy fleet:
```cron
15 8 * * * HEALTHCHECK_URL=https://hc-ping.com/<uuid> /opt/scripts/check-cert-expiry.sh >>/var/log/cert-expiry-check.log 2>&1
```
Leaving `HEALTHCHECK_URL` empty disables the pings entirely.
This matters more than it looks for a certificate check specifically. The script
is designed to stay silent on a healthy host: certbot renews at 30 days and the
threshold is 25, so a correctly working fleet produces no notifications, ever.
Without a heartbeat, "no alert" and "the check has not run since March" are the
same observation.

View File

@@ -13,6 +13,7 @@ ALERT_ON_NO_CERTS="${ALERT_ON_NO_CERTS:-true}"
CHECK_SERVED="${CHECK_SERVED:-true}"
SERVED_ADDR="${SERVED_ADDR:-127.0.0.1:443}"
SERVED_TIMEOUT="${SERVED_TIMEOUT:-10}"
HEALTHCHECK_URL="${HEALTHCHECK_URL:-}"
host="$(hostname -f 2>/dev/null || hostname 2>/dev/null || echo "unknown-host")"
now_epoch="$(date +%s)"
@@ -59,9 +60,22 @@ served_expiry_epoch() {
date -d "${enddate#notAfter=}" +%s 2>/dev/null
}
# Dead man's switch. ntfy reports what the check found; this reports that the
# check ran at all. Without it, a dead cron, a failed boot or a bad chmod all
# look exactly like a healthy fleet.
ping_healthcheck() {
local suffix="${1:-}"
[[ -z "${HEALTHCHECK_URL}" ]] && return 0
curl -fsS -m 10 -o /dev/null "${HEALTHCHECK_URL}${suffix}" \
|| echo "Failed to ping healthcheck at ${HEALTHCHECK_URL}${suffix}" >&2
}
fail() {
local message="$1"
send_alert "${message}" || echo "Failed to send ntfy alert to ${NTFY_URL}" >&2
ping_healthcheck "/fail"
echo "${message}" >&2
exit 1
}
@@ -127,6 +141,7 @@ if (( cert_count == 0 )); then
fi
echo "No certificates found under ${CERT_DIR}; no alert sent."
ping_healthcheck
exit 0
fi
@@ -136,8 +151,10 @@ if (( ${#warnings[@]} > 0 )); then
$(printf '%s\n' "${warnings[@]}")"
send_alert "${message}" || echo "Failed to send ntfy alert to ${NTFY_URL}" >&2
ping_healthcheck "/fail"
echo "${message}" >&2
exit 1
fi
echo "All ${cert_count} certificate(s) are valid for more than ${EXPIRY_DAYS} day(s)."
ping_healthcheck