-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcheck_cert_expiration.sh
More file actions
executable file
·68 lines (59 loc) · 2.56 KB
/
Copy pathcheck_cert_expiration.sh
File metadata and controls
executable file
·68 lines (59 loc) · 2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/bin/sh
# SSL Expiry Checker
# Created by Traek Malan @ Ungatech (github.com/ungatech)
#
# Usage: ./check_cert_expiration.sh <domain>
# Returns: 0 = OK (> 30d) or NOTICE (8-30d)
# 1 = WARNING (0-7d)
# 2 = CRITICAL (Expired)
# 3 = UNKNOWN (File missing, parsing error, or OpenSSL failure)
# Note: Optimized for 90-day lifecycles. Handles BusyBox date parsing.
set -eu
# Configuration
CERT_PATH="/etc/letsencrypt/live"
CERT_NAME="fullchain.pem"
# 1. Validate Input
if [ $# -eq 0 ]; then
echo "Usage: $0 <domain>" >&2; exit 3
fi
DOMAIN=$1
# 2. Check for Certificate File
CERT_FILE="$CERT_PATH/$DOMAIN/$CERT_NAME"
if [ ! -f "$CERT_FILE" ]; then
echo "[UNKNOWN] Certificate file for $DOMAIN not found at $CERT_FILE" >&2; exit 3
fi
# 3. Extract and Reformat Expiration Date
# We reformat "Mar 30 05:36:20 2026 GMT" to "2026-03-30 05:36:20"
# This is required because BusyBox date cannot parse the OpenSSL default format.
cert_enddate=$(openssl x509 -enddate -noout -in "$CERT_FILE" | cut -d = -f 2-) || {
echo "[UNKNOWN] OpenSSL failed to read $CERT_FILE." >&2; exit 3
}
expiration_date=$(echo "$cert_enddate" | awk '{
split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", months, " ");
for (i in months) m[months[i]] = i;
printf "%s-%02d-%02d %s", $4, m[$1], $2, $3
}')
# Validate that awk produced a usable ISO date (YYYY-MM-DD)
case "$expiration_date" in
[0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]\ *) ;; # Valid ISO date; do nothing
*) echo "[UNKNOWN] Malformed date string produced: $expiration_date (original: $cert_enddate)" >&2; exit 3 ;;
esac
# 4. Perform Date Calculation
# exp_sec: Keep this -u (UTC) for accurate math against the cert's GMT time
exp_sec=$(date -u -D "%Y-%m-%d %H:%M:%S" -d "$expiration_date" +%s)
now_sec=$(date -u +%s)
days_left=$(( (exp_sec - now_sec) / 86400 ))
# local_expiration: The "Bridge" method to force BusyBox to shift to local TZ
local_expiration=$(date -d "@$exp_sec" +"%Y-%m-%d %H:%M:%S %Z")
# 5. Output Results & Exit Codes
# Format: [STATUS] domain: X days remaining (YYYY-MM-DD HH:MM:SS TZ)
if [ "$days_left" -lt 0 ]; then
# Using ${days_left#-} removes the negative sign for "X days ago"
echo "[CRITICAL] $DOMAIN EXPIRED ${days_left#-} days ago ($local_expiration)!" >&2; exit 2
elif [ "$days_left" -le 7 ]; then
echo "[WARNING] $DOMAIN: $days_left days remaining ($local_expiration)!" >&2; exit 1
elif [ "$days_left" -le 30 ]; then
echo "[NOTICE] $DOMAIN: $days_left days remaining ($local_expiration)"
else
echo "[OK] $DOMAIN: $days_left days remaining ($local_expiration)"
fi