diff --git a/check_ssl.sh b/check_ssl.sh new file mode 100755 index 0000000..a7474d5 --- /dev/null +++ b/check_ssl.sh @@ -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) +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