#!/bin/bash # ============================================================ # GUARDiA SM | crontab_sm.sh # 대상: 시스템 crontab 관리 점검 # 파라미터: CHECK_USERS="root oracle tomcat" (공백 구분) # SYSLOG_HOURS=1 (최근 N시간 크론 실행 로그 확인) # MAX_CRON_RUNTIME=3600 (초과 시 WARN, 초) # ============================================================ set -euo pipefail CHECK_USERS=${CHECK_USERS:-"root"} SYSLOG_HOURS=${SYSLOG_HOURS:-1} MAX_CRON_RUNTIME=${MAX_CRON_RUNTIME:-3600} OK="[OK]"; WARN="[WARN]"; CRIT="[CRIT]" SEP="─────────────────────────────────────────" RESULT=0 echo "======================================================" echo " GUARDiA SM 점검 | Crontab | $(hostname -s)" echo " 점검 시각: $(date '+%Y-%m-%d %H:%M:%S %Z')" echo "======================================================" # ── 1. crond 프로세스 ───────────────────────────────────── echo; echo "[$SEP] 1. crond/cron 프로세스" CRON_PROC=$(pgrep -c "crond\|cron" 2>/dev/null || echo 0) if [ "$CRON_PROC" -gt 0 ]; then echo " ${OK} crond 실행 중 (PID: $(pgrep -f "crond|^cron$" | head -1))" else echo " ${CRIT} crond 프로세스 없음" RESULT=2 fi # ── 2. 사용자별 crontab 등록 현황 ──────────────────────── echo; echo "[$SEP] 2. 사용자 crontab 등록 현황" for U in $CHECK_USERS; do if id "$U" &>/dev/null; then CTAB=$(crontab -u "$U" -l 2>/dev/null | grep -v "^#\|^$" | head -20 || echo "") COUNT=$(echo "$CTAB" | grep -c "." 2>/dev/null || echo 0) if [ "${COUNT:-0}" -gt 0 ]; then echo " ─ ${U} (${COUNT}개):" echo "$CTAB" | sed 's/^/ /' else echo " ─ ${U}: crontab 없음" fi else echo " ─ ${U}: 계정 없음 (건너뜀)" fi done # ── 3. /etc/cron.* 디렉터리 내용 ───────────────────────── echo; echo "[$SEP] 3. 시스템 cron 디렉터리" for CRONDIR in /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly; do if [ -d "$CRONDIR" ]; then CNT=$(ls "$CRONDIR" 2>/dev/null | wc -l) echo " ${CRONDIR}: ${CNT}개" ls "$CRONDIR" 2>/dev/null | sed 's/^/ - /' | head -10 fi done # /etc/cron.d if [ -d /etc/cron.d ]; then echo " /etc/cron.d:" ls /etc/cron.d 2>/dev/null | sed 's/^/ - /' | head -10 fi # /etc/crontab if [ -r /etc/crontab ]; then echo " /etc/crontab:" grep -v "^#\|^$" /etc/crontab 2>/dev/null | sed 's/^/ /' | head -15 || true fi # ── 4. 최근 실행 로그 ───────────────────────────────────── echo; echo "[$SEP] 4. 최근 cron 실행 로그 (${SYSLOG_HOURS}시간)" for LOGFILE in /var/log/cron /var/log/cron.log /var/log/syslog; do if [ -r "$LOGFILE" ]; then CRON_RUNS=$(grep -i "cron" "$LOGFILE" 2>/dev/null | \ awk -v h="$SYSLOG_HOURS" ' BEGIN{ cmd="date --date=\"-"h" hours\" +%s 2>/dev/null || echo 0" cmd | getline cutoff; close(cmd) } { # 로그 라인의 시간 파싱 (Mmm DD HH:MM:SS 형식) print $0 }' 2>/dev/null | tail -50 || \ tail -100 "$LOGFILE" | grep -i "cron\|CMD" | tail -30 || echo "") if [ -n "$CRON_RUNS" ]; then echo " 최근 cron 실행 기록 (${LOGFILE}):" echo "$CRON_RUNS" | tail -20 | sed 's/^/ /' fi break fi done # ── 5. 실패한 cron 작업 감지 ───────────────────────────── echo; echo "[$SEP] 5. 실패한 cron 작업" for LOGFILE in /var/log/cron /var/log/cron.log /var/log/syslog; do if [ -r "$LOGFILE" ]; then FAILED=$(tail -500 "$LOGFILE" | grep -i "cron" | \ grep -iE "error|failed|exit code [^0]|SIGKILL|SIGTERM" | tail -10 || echo "") if [ -n "$FAILED" ]; then echo " ${WARN} 최근 실패 기록:" echo "$FAILED" | sed 's/^/ /' [ $RESULT -lt 1 ] && RESULT=1 else echo " ${OK} 최근 실패 없음" fi break fi done # ── 6. 현재 실행 중인 cron 작업 ────────────────────────── echo; echo "[$SEP] 6. 현재 실행 중인 cron 작업" RUNNING=$(ps aux 2>/dev/null | grep "cron" | grep -v "crond\|grep\|crontab" | head -10 || echo "") if [ -n "$RUNNING" ]; then echo " 실행 중인 cron 작업:" echo "$RUNNING" | awk '{printf " PID:%-8s ELAPSED:%-10s CMD:%s\n",$2,$10,substr($0,index($0,$11))}' | head -10 else echo " ${OK} 실행 중인 cron 작업 없음" fi # ── 7. anacron 상태 ─────────────────────────────────────── echo; echo "[$SEP] 7. anacron 상태" if command -v anacron &>/dev/null; then echo " ${OK} anacron 설치됨" ANACRON_LOG=$(cat /var/spool/anacron/cron.daily 2>/dev/null || echo "N/A") echo " 마지막 daily 실행: ${ANACRON_LOG}" else echo " anacron 미설치 (일반 crond 사용)" fi # ── 요약 ───────────────────────────────────────────────── echo echo "======================================================" case $RESULT in 0) echo " 최종 결과: ${OK} Crontab 정상" ;; 1) echo " 최종 결과: ${WARN} 주의 항목 있음" ;; 2) echo " 최종 결과: ${CRIT} 즉시 조치 필요" ;; esac echo " 점검 완료: $(date '+%Y-%m-%d %H:%M:%S')" echo "======================================================" exit $RESULT