did way to much,,,,,, mostly added monitors, but almost every file was edited in some way

This commit is contained in:
2026-04-14 17:11:49 -04:00
parent 6564c9362e
commit f1529db3a0
12 changed files with 2154 additions and 305 deletions
+182
View File
@@ -0,0 +1,182 @@
#!/bin/bash
# -----------------------------------------------------------------------------------------------
# --------------------------------- Certificate Monitor ----------------------------------------
# -----------------------------------------------------------------------------------------------
# Monitors SSL certificate expiry for all configured domains by connecting directly
# via openssl — no dependency on NPM or any other service. Reads the actual certificate
# the server is presenting to the outside world.
#
# This approach catches real-world cert issues that API-based checks miss:
# - Cert renewed but server not reloaded
# - Wrong cert being served
# - Cert chain issues
#
# Each domain and subdomain is a separate entry — they have independent certs.
# Silent when all certs are healthy. Notifies when any approach warning threshold.
# Notifications batched per severity — one message for warnings, one for criticals.
#
# All configuration in Master.conf under Certificate Monitor section.
# Supports --dry-run to check certs and show results without sending notifications.
# -----------------------------------------------------------------------------------------------
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../Master.conf"
source "$SCRIPT_DIR/../common.sh"
parse_args "$@"
# -----------------------------------------------------------------------------------------------
# ━━━ $ICON_GEAR Setup ━━━
# -----------------------------------------------------------------------------------------------
echo ""
echo "━━━ $ICON_GEAR Setup ━━━"
if ! command -v openssl >/dev/null 2>&1; then
error "openssl not found — required for certificate checks"
exit 1
fi
success "openssl available"
if [[ ${#CERT_MONITOR_DOMAINS[@]} -eq 0 ]]; then
warn "CERT_MONITOR_DOMAINS is empty in Master.conf — add your domains to enable monitoring"
exit 0
fi
info "$ICON_CERT Domains to check: ${#CERT_MONITOR_DOMAINS[@]}"
# -----------------------------------------------------------------------------------------------
# ━━━ $ICON_SUMMARY Status ━━━
# -----------------------------------------------------------------------------------------------
if [[ "$SHOW_STATUS" == true ]]; then
echo ""
echo "━━━━━ $ICON_SUMMARY STATUS ━━━━━"
echo "$ICON_CERT Domains: ${CERT_MONITOR_DOMAINS[*]}"
echo "$ICON_WARN Warn at: ${CERT_WARN_DAYS} days remaining"
echo "$ICON_ERROR Crit at: ${CERT_CRIT_DAYS} days remaining"
echo "$ICON_TIME Timeout: ${CERT_TIMEOUT}s per domain"
echo "$ICON_GEAR Dry Run: $DRY_RUN"
echo "━━━━━━━━━━━━━━━━━━━━━━━"
exit 0
fi
[[ "$DRY_RUN" == true ]] && warn "DRY RUN — results shown but no notifications sent"
# -----------------------------------------------------------------------------------------------
# CERT CHECK FUNCTION
# Connects to domain:443 via openssl, extracts expiry date, calculates days remaining.
# Returns 0=healthy 1=warning 2=critical 3=failed
# -----------------------------------------------------------------------------------------------
check_cert() {
local domain="$1"
local port="${2:-443}"
local expiry_str
expiry_str=$(echo | timeout "$CERT_TIMEOUT" openssl s_client \
-connect "${domain}:${port}" \
-servername "$domain" \
2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
if [[ -z "$expiry_str" ]]; then
error "$ICON_CERT $domain — could not retrieve certificate"
return 3
fi
local expiry_epoch
expiry_epoch=$(date -d "$expiry_str" +%s 2>/dev/null)
if [[ -z "$expiry_epoch" ]]; then
error "$ICON_CERT $domain — could not parse expiry date: $expiry_str"
return 3
fi
local now days_remaining expiry_display
now=$(date +%s)
days_remaining=$(( (expiry_epoch - now) / 86400 ))
expiry_display=$(date -d "$expiry_str" '+%Y-%m-%d' 2>/dev/null)
if [[ "$days_remaining" -le "$CERT_CRIT_DAYS" ]]; then
error "$ICON_CERT $domain — CRITICAL: ${days_remaining} days remaining (expires $expiry_display)"
return 2
elif [[ "$days_remaining" -le "$CERT_WARN_DAYS" ]]; then
warn "$ICON_CERT $domain — WARNING: ${days_remaining} days remaining (expires $expiry_display)"
return 1
else
success "$ICON_CERT $domain — OK: ${days_remaining} days remaining (expires $expiry_display)"
return 0
fi
}
# -----------------------------------------------------------------------------------------------
# ━━━ $ICON_CERT Certificate Monitor ━━━
# -----------------------------------------------------------------------------------------------
echo ""
echo "━━━ $ICON_CERT Certificate Monitor — $(date '+%Y-%m-%d %H:%M:%S') ━━━"
echo "$ICON_WARN Warn threshold: ${CERT_WARN_DAYS} days"
echo "$ICON_ERROR Crit threshold: ${CERT_CRIT_DAYS} days"
echo ""
START=$(date +%s)
HEALTHY=()
WARNING=()
CRITICAL=()
FAILED=()
declare -A DOMAIN_STATUS
for domain in "${CERT_MONITOR_DOMAINS[@]}"; do
[[ -z "$domain" ]] && continue
echo "━━━ $ICON_CERT $domain ━━━"
check_cert "$domain"
result=$?
case $result in
0) HEALTHY+=("$domain"); DOMAIN_STATUS["$domain"]="OK" ;;
1) WARNING+=("$domain"); DOMAIN_STATUS["$domain"]="WARN" ;;
2) CRITICAL+=("$domain"); DOMAIN_STATUS["$domain"]="CRIT" ;;
3) FAILED+=("$domain"); DOMAIN_STATUS["$domain"]="FAIL" ;;
esac
echo ""
done
END=$(date +%s)
if [[ "$DRY_RUN" == false ]]; then
[[ ${#CRITICAL[@]} -gt 0 ]] && \
notify "Certificate CRITICAL on $(hostname) — expiring within ${CERT_CRIT_DAYS} days: ${CRITICAL[*]}" "Certificate Monitor" "warning"
[[ ${#WARNING[@]} -gt 0 ]] && \
notify "Certificate WARNING on $(hostname) — expiring within ${CERT_WARN_DAYS} days: ${WARNING[*]}" "Certificate Monitor" "warning"
[[ ${#FAILED[@]} -gt 0 ]] && \
notify "Certificate check FAILED on $(hostname) — could not reach: ${FAILED[*]}" "Certificate Monitor" "warning"
fi
# -----------------------------------------------------------------------------------------------
# ━━━ $ICON_SUMMARY Summary ━━━
# -----------------------------------------------------------------------------------------------
echo "━━━━━ $ICON_SUMMARY CERTIFICATE MONITOR SUMMARY ━━━━━"
echo "$ICON_TIME Duration: $(format_duration $((END - START)))"
echo ""
echo " $ICON_SUCCESS Healthy: ${#HEALTHY[@]} $ICON_WARN Warning: ${#WARNING[@]} $ICON_ERROR Critical: ${#CRITICAL[@]} Failed: ${#FAILED[@]}"
echo ""
for domain in "${CERT_MONITOR_DOMAINS[@]}"; do
[[ -z "$domain" ]] && continue
case "${DOMAIN_STATUS[$domain]:-UNKN}" in
OK) echo " $ICON_SUCCESS $domain" ;;
WARN) echo " $ICON_WARN $domain" ;;
CRIT) echo " $ICON_ERROR $domain" ;;
FAIL) echo " $ICON_ERROR $domain (unreachable)" ;;
esac
done
echo ""
if [[ "$DRY_RUN" == true ]]; then
echo "$ICON_WARN Status: DRY RUN — no notifications sent"
elif [[ ${#CRITICAL[@]} -gt 0 || ${#FAILED[@]} -gt 0 ]]; then
echo "$ICON_ERROR Status: ACTION REQUIRED"
elif [[ ${#WARNING[@]} -gt 0 ]]; then
echo "$ICON_WARN Status: WARNINGS — renewal recommended"
else
echo "$ICON_DONE Status: $ICON_SUCCESS ALL CERTS HEALTHY"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
[[ ${#CRITICAL[@]} -gt 0 || ${#FAILED[@]} -gt 0 ]] && exit 1
exit 0