feat: 新增 check_ssl.sh — 檢查 tpesupporter 憑證狀態

部署於 hospital_web:~/check_ssl.sh,檢查目標網域憑證的主機名匹配與
到期天數。GCA G3 verify code 20 已於腳本內視為正常,不當失敗處理。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-16 09:12:15 +08:00
parent c6c1d95290
commit 77915be5d3

93
check_ssl.sh Executable file
View File

@@ -0,0 +1,93 @@
#!/usr/bin/env bash
# check_ssl.sh — 檢查 tpesupporter.tpech.gov.tw SSL 憑證狀態
#
# 用法:./check_ssl.sh [domain] [port]
# 預設 domain=tpesupporter.tpech.gov.tw, port=443
#
# 備註:憑證由 GCA G3政府憑證管理中心簽發根憑證不在 Linux 預設
# 信任庫。openssl verify 會回 code 20屬**正常現象**,瀏覽器端可正常
# 驗證。此腳本不把 verify code 當成失敗條件,只看期限與主機名匹配。
#
# 結束碼:
# 0 — 憑證正常
# 1 — 連線失敗或無法取得憑證
# 2 — 憑證已過期
# 3 — 憑證將於 WARN_DAYS 天內到期
# 4 — 憑證主體與目標網域不符
set -u
DOMAIN="${1:-tpesupporter.tpech.gov.tw}"
PORT="${2:-443}"
WARN_DAYS="${WARN_DAYS:-30}"
echo "== SSL 憑證檢查:${DOMAIN}:${PORT} =="
echo
# --- 1. 取得憑證 ---
RAW=$(echo | openssl s_client -connect "${DOMAIN}:${PORT}" -servername "${DOMAIN}" 2>/dev/null </dev/null)
if [ -z "$RAW" ] || ! grep -q "BEGIN CERTIFICATE" <<<"$RAW"; then
echo "[FAIL] 無法連線或取得憑證"
exit 1
fi
PEM=$(sed -n "/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p" <<<"$RAW" | awk "/BEGIN/{f=1} f; /END/{exit}")
# --- 2. 解析憑證欄位 ---
SUBJECT=$(openssl x509 -noout -subject <<<"$PEM" 2>/dev/null)
ISSUER=$(openssl x509 -noout -issuer <<<"$PEM" 2>/dev/null)
DATES=$(openssl x509 -noout -dates <<<"$PEM" 2>/dev/null)
SAN=$(openssl x509 -noout -ext subjectAltName <<<"$PEM" 2>/dev/null | sed -n "2p" | sed "s/^[ \t]*//")
END_DATE=$(openssl x509 -noout -enddate <<<"$PEM" | sed "s/notAfter=//")
echo "$SUBJECT"
echo "$ISSUER"
echo "$DATES"
echo "SAN: ${SAN:-(無)}"
echo
# --- 3. 計算到期天數 ---
END_EPOCH=$(date -d "$END_DATE" +%s 2>/dev/null || echo 0)
NOW_EPOCH=$(date +%s)
if [ "$END_EPOCH" -eq 0 ]; then
echo "[WARN] 無法解析到期日:$END_DATE"
DAYS_LEFT="?"
else
DAYS_LEFT=$(( (END_EPOCH - NOW_EPOCH) / 86400 ))
fi
echo "到期日:${END_DATE}"
echo "剩餘天數:${DAYS_LEFT}"
# --- 4. 驗證 Code僅資訊性 ---
VCODE=$(grep -oE "Verify return code: [0-9]+" <<<"$RAW" | tail -1 | awk "{print \$NF}")
echo "openssl verify code${VCODE:-?}GCA G3 根憑證不在 Linux 預設信任庫,回 20 屬正常)"
# --- 5. 主機名匹配CN / SAN ---
if grep -qi "DNS:${DOMAIN}" <<<"$SAN" || grep -qi "CN[[:space:]]*=[[:space:]]*${DOMAIN}" <<<"$SUBJECT"; then
HOST_MATCH=1
else
HOST_MATCH=0
fi
echo
# --- 6. 判定 ---
if [ "$HOST_MATCH" -eq 0 ]; then
echo "[FAIL] 憑證 CN/SAN 不包含 ${DOMAIN}"
exit 4
fi
if [ "$DAYS_LEFT" = "?" ]; then
echo "[WARN] 憑證期限無法解析"
exit 3
fi
if [ "$DAYS_LEFT" -lt 0 ]; then
echo "[FAIL] 憑證已過期 $((-DAYS_LEFT))"
exit 2
elif [ "$DAYS_LEFT" -lt "$WARN_DAYS" ]; then
echo "[WARN] 憑證將於 ${DAYS_LEFT} 天內到期(閾值 ${WARN_DAYS} 天)"
exit 3
else
echo "[OK] 憑證狀態正常(剩 ${DAYS_LEFT} 天)"
exit 0
fi