Files
106_105_181_70/check_ssl.sh
Timmy 77915be5d3 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>
2026-04-16 09:12:15 +08:00

94 lines
2.9 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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