139 lines
4.6 KiB
Bash
Executable File
139 lines
4.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
DOMAIN="${1:-vtuber.wooo.work}"
|
||
TARGET_IP="${2:-114.32.151.246}"
|
||
DNS_RESOLVER="${3:-8.8.8.8}"
|
||
STRICT_MODE="${4:-1}"
|
||
|
||
strict_mode="${CHECK_STRICT_MODE:-${STRICT_MODE}}"
|
||
|
||
fail_count=0
|
||
resolved_count=0
|
||
|
||
need_cmd() {
|
||
if ! command -v "$1" >/dev/null 2>&1; then
|
||
echo "❌ 缺少指令:$1"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
need_cmd dig
|
||
need_cmd openssl
|
||
need_cmd curl
|
||
|
||
echo "===== DNS 解析檢查 ====="
|
||
echo "網域:${DOMAIN}"
|
||
echo "預期 A 紀錄指向:${TARGET_IP}"
|
||
echo "採用解析器:${DNS_RESOLVER}"
|
||
echo "嚴格檢查:${strict_mode}"
|
||
|
||
a_records="$(dig +short A "${DOMAIN}" @"${DNS_RESOLVER}" | awk 'NF {print $1}' | sort -u)"
|
||
aaaa_records="$(dig +short AAAA "${DOMAIN}" @"${DNS_RESOLVER}" | awk 'NF {print $1}' | sort -u)"
|
||
|
||
if [ -z "${a_records}" ] && [ -z "${aaaa_records}" ]; then
|
||
echo "⚠️ 無法解析到 A/AAAA;請檢查 DNS zone 是否有建立 ${DOMAIN} 的 A/AAAA 紀錄。"
|
||
fail_count=$((fail_count + 1))
|
||
else
|
||
echo "A 紀錄:${a_records:-(未設定)}"
|
||
echo "AAAA 紀錄:${aaaa_records:-(未設定)}"
|
||
if printf '%s\n' "${a_records}" | grep -Fxq "${TARGET_IP}"; then
|
||
echo "✅ A 紀錄包含 ${TARGET_IP}"
|
||
resolved_count=$((resolved_count + 1))
|
||
else
|
||
echo "⚠️ ${DOMAIN} 的 A 紀錄未看到 ${TARGET_IP}"
|
||
echo " 請檢查 DNS:A Record (${DOMAIN}) = ${TARGET_IP}"
|
||
echo " 修正指引:在 DNS 面板把 vtuber.wooo.work 的 A Record 指到 ${TARGET_IP}"
|
||
fail_count=$((fail_count + 1))
|
||
fi
|
||
fi
|
||
|
||
if command -v host >/dev/null 2>&1; then
|
||
host "${DOMAIN}" | sed -n '1,4p' || true
|
||
else
|
||
echo "(已略過 host 查詢,未安裝 host 指令)"
|
||
fi
|
||
echo
|
||
|
||
echo "===== HTTPS 憑證檢查 ====="
|
||
cert_pem="$(echo | openssl s_client -connect "${DOMAIN}:443" -servername "${DOMAIN}" 2>/dev/null | openssl x509 2>/dev/null || true)"
|
||
if [ -z "${cert_pem}" ]; then
|
||
echo "❌ 無法抓到 TLS 憑證(連線或憑證有問題)"
|
||
fail_count=$((fail_count + 1))
|
||
else
|
||
subject="$(printf '%s\n' "${cert_pem}" | openssl x509 -noout -subject)"
|
||
issuer="$(printf '%s\n' "${cert_pem}" | openssl x509 -noout -issuer)"
|
||
start_date="$(printf '%s\n' "${cert_pem}" | openssl x509 -noout -startdate)"
|
||
end_date="$(printf '%s\n' "${cert_pem}" | openssl x509 -noout -enddate)"
|
||
san="$(printf '%s\n' "${cert_pem}" | openssl x509 -noout -ext subjectAltName 2>/dev/null || true)"
|
||
|
||
echo "Subject: ${subject}"
|
||
echo "Issuer: ${issuer}"
|
||
echo "起始: ${start_date}"
|
||
echo "到期: ${end_date}"
|
||
echo "SAN: ${san:-(未提供)}"
|
||
|
||
if printf '%s\n' "${san}" | grep -q "DNS:${DOMAIN}"; then
|
||
echo "✅ 憑證 SAN 包含 ${DOMAIN}"
|
||
else
|
||
echo "⚠️ 憑證 SAN 未明確列出 ${DOMAIN}"
|
||
fail_count=$((fail_count + 1))
|
||
fi
|
||
|
||
if printf '%s\n' "${cert_pem}" | openssl x509 -checkend $((7*24*60*60)) >/dev/null 2>&1; then
|
||
echo "✅ 憑證未於 7 日內到期"
|
||
else
|
||
echo "⚠️ 憑證疑似 7 日內到期"
|
||
fail_count=$((fail_count + 1))
|
||
fi
|
||
fi
|
||
echo
|
||
|
||
echo "===== 路徑可達性檢查 ====="
|
||
check_url() {
|
||
local label="$1"
|
||
local url="$2"
|
||
local expect_http="${3:-200}"
|
||
local output
|
||
shift 3
|
||
output="$(curl -ksS -m 12 -o /dev/null -w 'HTTP %{http_code} | total=%{time_total}s | remote=%{remote_ip}' "$@" "$url" || true)"
|
||
local http_code
|
||
http_code="$(printf '%s\n' "${output}" | awk '{print $2}')"
|
||
|
||
if [ -z "${output}" ] || [ "${http_code}" = "000" ] || [ -z "${http_code}" ]; then
|
||
echo "❌ ${label}:連線失敗"
|
||
fail_count=$((fail_count + 1))
|
||
elif [ "${http_code}" != "${expect_http}" ]; then
|
||
echo "❌ ${label}:HTTP ${http_code}(預期 ${expect_http})"
|
||
fail_count=$((fail_count + 1))
|
||
else
|
||
echo "✅ ${label}:${output}"
|
||
fi
|
||
}
|
||
|
||
check_url "域名直連" "https://${DOMAIN}/live/demo" 200
|
||
check_url "域名繁中直連" "https://${DOMAIN}/zh-TW/live/demo" 200
|
||
check_url "SNI 直定向到 ${TARGET_IP}" "https://${DOMAIN}/live/demo" \
|
||
--resolve "${DOMAIN}:443:${TARGET_IP}" 200
|
||
check_url "IP + Host 直走 (防止 host 漏配)" "http://${TARGET_IP}/live/demo" \
|
||
-H "Host: ${DOMAIN}" 200
|
||
check_url "純 IP 訪問(不帶 Host)" "http://${TARGET_IP}/live/demo" 200
|
||
|
||
echo
|
||
if [ "${fail_count}" -eq 0 ]; then
|
||
echo "總結:✅ 全部檢查通過。"
|
||
else
|
||
echo "總結:⚠️ ${fail_count} 項提醒,需先補上對應修正。"
|
||
fi
|
||
|
||
if [ "${strict_mode}" != "0" ] && [ "${fail_count}" -gt 0 ]; then
|
||
echo "部署門檻:❌ 因嚴格模式,非 0 值結果將阻止後續流程。"
|
||
exit 1
|
||
fi
|
||
|
||
if [ "${fail_count}" -gt 0 ] && [ "${resolved_count}" -eq 0 ]; then
|
||
echo "DNS 門檻:❌ 外網無法直接導向目標主機,這通常代表流量仍在舊站。"
|
||
fi
|
||
|
||
exit 0
|