guardia-itsm/scripts/sm/ssl/ssl_expiry_check.sh
2026-05-30 23:02:43 +09:00

95 lines
3.8 KiB
Bash

#!/bin/bash
# ==============================================================================
# GUARDiA ITSM — SSL 인증서 만료일 점검 스크립트
# 경로: /opt/guardia/scripts/ssl/ssl_expiry_check.sh
#
# 사용법:
# ./ssl_expiry_check.sh <호스트> [포트(기본 443)] [timeout(기본 5초)]
#
# 출력 (JSON):
# 성공: {"host":"...","port":443,"expiry":"...","days_left":N,"level":"OK|WARN|CRITICAL","issuer":"..."}
# 실패: {"host":"...","port":443,"status":"ERROR","message":"..."}
#
# 반환 코드:
# 0 — 점검 완료 (OK/WARN/CRITICAL 모두)
# 1 — 인증서 조회 실패
# ==============================================================================
HOST="${1}"
PORT="${2:-443}"
TIMEOUT="${3:-5}"
if [ -z "${HOST}" ]; then
echo '{"status":"ERROR","message":"호스트 인수가 필요합니다. 사용법: ssl_expiry_check.sh <host> [port]"}'
exit 1
fi
# openssl 설치 확인
if ! command -v openssl &>/dev/null; then
echo '{"status":"ERROR","message":"openssl 명령어를 찾을 수 없습니다."}'
exit 1
fi
# ── 인증서 정보 조회 ──────────────────────────────────────────────────────────
CERT_INFO=$(echo | timeout "${TIMEOUT}" openssl s_client \
-servername "${HOST}" \
-connect "${HOST}:${PORT}" \
2>/dev/null)
if [ -z "${CERT_INFO}" ]; then
echo "{\"host\":\"${HOST}\",\"port\":${PORT},\"status\":\"ERROR\",\"message\":\"연결 실패 또는 타임아웃 (${TIMEOUT}s)\"}"
exit 1
fi
# 만료일 추출
EXPIRY=$(echo "${CERT_INFO}" | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
if [ -z "${EXPIRY}" ]; then
echo "{\"host\":\"${HOST}\",\"port\":${PORT},\"status\":\"ERROR\",\"message\":\"인증서 만료일을 파싱할 수 없습니다.\"}"
exit 1
fi
# 발급기관 추출
ISSUER=$(echo "${CERT_INFO}" | openssl x509 -noout -issuer 2>/dev/null \
| sed 's/^issuer=//' | tr -d '\n' | sed 's/"/\\"/g')
# 주체(CN) 추출
SUBJECT_CN=$(echo "${CERT_INFO}" | openssl x509 -noout -subject 2>/dev/null \
| grep -oP '(?<=CN = )[^,]+' | head -1 | tr -d '\n' | sed 's/"/\\"/g')
# ── 날짜 계산 ─────────────────────────────────────────────────────────────────
# Linux date 와 macOS date 모두 지원
EXPIRY_TS=$(date -d "${EXPIRY}" +%s 2>/dev/null)
if [ -z "${EXPIRY_TS}" ]; then
# macOS/BSD 형식 시도
EXPIRY_TS=$(date -jf "%b %d %T %Y %Z" "${EXPIRY}" +%s 2>/dev/null)
fi
if [ -z "${EXPIRY_TS}" ]; then
# 추가 형식 시도 (Jan 1 ...)
EXPIRY_TS=$(date -d "$(echo "${EXPIRY}" | tr -s ' ')" +%s 2>/dev/null)
fi
if [ -z "${EXPIRY_TS}" ]; then
echo "{\"host\":\"${HOST}\",\"port\":${PORT},\"expiry\":\"${EXPIRY}\",\"status\":\"ERROR\",\"message\":\"날짜 파싱 실패\"}"
exit 1
fi
NOW_TS=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_TS - NOW_TS) / 86400 ))
# ── 알림 등급 ─────────────────────────────────────────────────────────────────
LEVEL="OK"
if [ "${DAYS_LEFT}" -le 0 ]; then
LEVEL="EXPIRED"
elif [ "${DAYS_LEFT}" -le 7 ]; then
LEVEL="CRITICAL"
elif [ "${DAYS_LEFT}" -le 30 ]; then
LEVEL="WARN"
fi
# ── JSON 출력 ─────────────────────────────────────────────────────────────────
cat <<EOF
{"host":"${HOST}","port":${PORT},"expiry":"${EXPIRY}","days_left":${DAYS_LEFT},"level":"${LEVEL}","issuer":"${ISSUER}","subject_cn":"${SUBJECT_CN}"}
EOF
exit 0