#!/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 [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 <