80 lines
4.6 KiB
Bash
Executable File
80 lines
4.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# ==============================================================================================
|
|
# ================================ Certificate History =========================================
|
|
# ==============================================================================================
|
|
#
|
|
# PURPOSE
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Records what happens to every certificate NPM holds — first seen, renewals, failures, and how
|
|
# long each domain has been tracked — into DB_DIR/cert_history.json. The Certs tab reads it.
|
|
#
|
|
# NPM knows what a certificate is today and nothing about what it was, and cert_monitor.sh writes
|
|
# a snapshot the next run overwrites. Ten certificates on this host had been failing renewal for
|
|
# months without anything on any page being able to say so.
|
|
#
|
|
# ==============================================================================================
|
|
# OPERATIONAL MODEL
|
|
# ==============================================================================================
|
|
#
|
|
# A wrapper. The work is in cert_history.php, next to the NPM client it needs — the API token
|
|
# handling lives in include/auth.php and reimplementing it in bash to avoid a php call would be a
|
|
# second copy of the thing most worth having only one of. Same split as api_cache_writer and
|
|
# ai_repair_sweep.
|
|
#
|
|
# Counts start from zero on first run and are only ever observed. first_seen is seeded from NPM's
|
|
# own created_on, which is a real date; nothing else is back-filled.
|
|
#
|
|
# ==============================================================================================
|
|
# DESIGN PRINCIPLES
|
|
# ==============================================================================================
|
|
#
|
|
# History is accumulated, never reconstructed.
|
|
# NPM holds only the present, so every past state this file knows about is one it observed at
|
|
# the time. Counts start at zero on first run and nothing is back-filled — first_seen is the
|
|
# single exception, seeded from NPM's own created_on because that is a real recorded date
|
|
# rather than an inference.
|
|
#
|
|
# A domain is retired on strikes, not on a single bad pass.
|
|
# A pass fails for a domain when it is absent from NPM's list or its expiry is already in the
|
|
# past — and NPM's list can come back short for reasons that have nothing to do with the
|
|
# certificate, such as an API hiccup or a restart mid-pass. CERT_HISTORY_STRIKES consecutive
|
|
# failures are required before a domain is retired, and it stays in the store afterwards, so
|
|
# one bad read can neither erase months of history nor hide a genuine expiry.
|
|
#
|
|
# The wrapper holds no logic.
|
|
# The work sits next to the NPM client it needs, because token handling lives in
|
|
# include/auth.php and a bash reimplementation would be a second copy of the thing most worth
|
|
# having only one of. Flags are forwarded verbatim.
|
|
#
|
|
# ==============================================================================================
|
|
# OPERATIONAL SAFEGUARDS
|
|
# ==============================================================================================
|
|
#
|
|
# The store is replaced atomically: temp file, verified, then renamed over the original. A pass
|
|
# that fails partway leaves the previous history intact rather than a truncated file — this is
|
|
# the only record of what these certificates did, and there is no second copy to restore from.
|
|
#
|
|
# --dry-run reports every change it would make and writes nothing. --status only reads.
|
|
#
|
|
# Read-only against NPM. Certificates are observed; nothing here renews, deletes or edits one.
|
|
#
|
|
# ==============================================================================================
|
|
# RUNTIME MODES
|
|
# ==============================================================================================
|
|
#
|
|
# cert_history.sh one pass, updates the store
|
|
# cert_history.sh --dry-run reports what it would change, writes nothing
|
|
# cert_history.sh --status prints the store as a table
|
|
#
|
|
# ==============================================================================================
|
|
# CONFIGURATION
|
|
# ==============================================================================================
|
|
#
|
|
# CERT_HISTORY_STRIKES consecutive failed passes before a domain is retired (default 5)
|
|
# DB_DIR cert_history.json is written here
|
|
#
|
|
# ==============================================================================================
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
php "$SCRIPT_DIR/cert_history.php" "$@"
|