Linux 로그 경로 정리 · 30/50 · Part 3. Ubuntu / Debian 로그 경로

선행 학습 → 29. 배포판별 로그 분석 전략 · 기초 29. 명령어 조합을 이용한 시스템 분석
이번 글 → Linux 로그 경로 자동 탐색 스크립트
이어서 → 31. systemd-journald 이해

1. 들어가며

29편의 탐색 전략을 스크립트로 자동화합니다. 목표는 두 가지입니다.

  1. 처음 보는 서버에서 30초 안에 로깅 구성을 파악한다.
  2. 아무것도 수정하지 않는다 — 조사 도구가 증거를 오염시키면 안 된다.

핵심 요약

  • 점검 6항목: OS · Logging System · Key log files · SSH log source · Service log dirs · Rotation
  • 안전 원칙: 읽기 전용 명령만, 출력은 표준출력으로, 존재하지 않는 파일은 "(없음)"으로 표시
  • 실행 결과 자체가 "가시성 평가서"가 된다.

2. 핵심 개념

설계 원칙구현
읽기 전용stat, grep -c, systemctl is-active, ls 만 사용 (rm, sed -i, > 리다이렉션 없음)
배포판 독립/etc/os-release 의 ID_LIKE 로 계열 판단 후 파일 목록 선택
실패 허용2>/dev/null, 없는 파일은 "(없음)" 출력, set -u 로 오타 변수 방지
읽기 쉬운 출력printf '%-22s %s' 로 2열 정렬

3. 로그 생성 구조

안전한 로그 탐색 스크립트 흐름

[1] OS ─▶ Family(rhel/debian) 결정
       ↓
[2] journald / rsyslog / auditd 상태 + 저널 저장 방식 + 감사 룰 수
       ↓
[3] Family 별 핵심 로그 파일: 권한·소유자·크기·mtime
       ↓
[4] SSH 로그 소스: 파일(secure/auth.log) + 저널 유닛(sshd/ssh)
       ↓
[5] 서비스 로그 디렉터리 (httpd/apache2/nginx/mariadb/mysql/apt)
       ↓
[6] 순환 정책: logrotate.conf + auditd 자체 순환

4. 실제 로그 경로

스크립트가 점검하는 경로:

RHEL  : /var/log/{secure,messages,cron,maillog,boot.log}
Debian: /var/log/{auth.log,syslog,kern.log,mail.log,dpkg.log}
공통  : /var/log/audit/audit.log, /var/log/journal, /etc/logrotate.conf, /etc/audit/auditd.conf
서비스: /var/log/{httpd,apache2,nginx,mariadb,mysql,apt}

5. 명령어 실습

#!/usr/bin/env bash
# log-recon.sh - 현재 서버의 로깅 구성과 주요 로그 경로를 "읽기 전용"으로 점검
# 사용: sudo bash log-recon.sh   (파일을 수정·삭제하지 않음)
set -u
line(){ printf '%-22s %s\n' "$1" "$2"; }
echo "=== [1] OS ==="
. /etc/os-release 2>/dev/null; line "OS" "${PRETTY_NAME:-unknown}"; line "ID_LIKE" "${ID_LIKE:-$ID}"
case "${ID_LIKE:-} ${ID:-}" in *rhel*|*fedora*|*centos*|*rocky*) FAM=rhel;; *debian*|*ubuntu*) FAM=debian;; *) FAM=unknown;; esac
line "Family" "$FAM"; line "Timezone" "$(date +%Z%z)"
echo "=== [2] Logging system ==="
for s in systemd-journald rsyslog auditd; do
  st=$(systemctl is-active "$s" 2>/dev/null); [ -z "$st" ] && st="n/a"
  line "$s" "$st"
done
[ -d /var/log/journal ] && line "journal storage" "persistent (/var/log/journal)" || line "journal storage" "volatile or n/a (/run/log/journal)"
command -v rsyslogd >/dev/null && line "rsyslogd" "installed" || line "rsyslogd" "not installed"
command -v auditctl >/dev/null && line "auditd tools" "installed ($(auditctl -l 2>/dev/null | grep -vc '^No rules') rules loaded)" || line "auditd tools" "not installed"
echo "=== [3] Key log files ==="
if [ "$FAM" = rhel ]; then L="/var/log/secure /var/log/messages /var/log/cron /var/log/maillog /var/log/boot.log"
else L="/var/log/auth.log /var/log/syslog /var/log/kern.log /var/log/mail.log /var/log/dpkg.log"; fi
for f in $L /var/log/audit/audit.log; do
  if [ -e "$f" ]; then line "$f" "$(stat -c '%a %U:%G %s bytes mtime=%y' "$f" | cut -d. -f1)"; else line "$f" "(없음)"; fi
done
echo "=== [4] SSH log source ==="
for f in /var/log/secure /var/log/auth.log; do [ -e "$f" ] && line "file" "$f ($(grep -c 'sshd' "$f" 2>/dev/null) sshd lines)"; done
for u in sshd ssh; do n=$(journalctl -u "$u" --no-pager -q 2>/dev/null | wc -l); [ "$n" -gt 0 ] && line "journal unit" "$u ($n lines)"; done
echo "=== [5] Service log dirs ==="
for d in /var/log/httpd /var/log/apache2 /var/log/nginx /var/log/mariadb /var/log/mysql /var/log/apt; do [ -d "$d" ] && line "$d" "$(ls "$d" | wc -l) files"; done
echo "=== [6] Rotation ==="
line "logrotate.conf" "$(grep -vE '^#|^$' /etc/logrotate.conf 2>/dev/null | tr '\n' ' ')"
[ -f /etc/audit/auditd.conf ] && line "auditd rotation" "$(grep -E '^(max_log_file|num_logs|max_log_file_action) ' /etc/audit/auditd.conf | tr -s ' ' | tr '\n' ' ')"
echo "=== done: $(date '+%F %T %Z') ==="

실행: sudo bash log-recon.sh | tee /root/ir-XXXX/log-recon.txt (결과는 조사 디렉터리에 저장)

6. 로그 예시

실제 실행 결과 — Rocky Linux 9.8 컨테이너 · root@rocky9-lab — log-recon.sh

위 이미지는 이 스크립트를 Rocky Linux 9.8 컨테이너 실습 환경에서 실제로 실행한 결과입니다. 같은 스크립트를 Ubuntu 24.04 환경에서도 실행해 Family debian, journal storage persistent, auditd tools not installed 로 판별되는 것을 확인했습니다.

7. 로그 필드 분석

실제 출력에서 읽어낸 사실:

출력해석
systemd-journald n/a 등컨테이너에는 systemd가 PID 1로 동작하지 않아 서비스 상태를 알 수 없다 → 환경 한계로 기록
rsyslogd installed + secure 0 bytes패키지는 있으나 데몬이 기록하지 않음 → 로그 파일만 보고 "이벤트 없음"으로 판단하면 오류
audit.log (없음), 0 rules loaded실행·파일 접근 가시성 없음
dateext순환 파일 이름이 secure-YYYYMMDD
max_log_file = 8 num_logs = 5 ROTATEaudit.log는 logrotate가 아니라 auditd가 8MB × 5개로 직접 순환(41편)

이 결과 하나로 "이 서버는 파일 로그·감사 로그 모두 가시성이 없다"는 판단 근거를 제시할 수 있습니다.

8. 보안관점

정상 서버 기대 결과의심 결과
3개 로깅 서비스 active운영 서버인데 rsyslog/auditd inactive
핵심 로그 mtime 최신한 파일만 오래 멈춘 mtime
감사 룰 수 > 0룰 0 (규칙 삭제 가능성: auditctl -D)
권한 600/640644 이상 또는 비root 소유

9. SOC 관점

  • 온보딩: 신규 서버 SIEM 등록 시 실행 → 결과를 자산 정보에 첨부.
  • Triage: Alert 대상 서버에서 첫 명령으로 실행 → 어떤 소스를 신뢰할지 결정.
  • Wazuh 연계: Wazuh의 <wodle name="command"> 또는 <localfile><log_format>full_command</log_format> 로 주기 실행하여 로깅 상태 변화를 감시할 수 있다(47편에서 에이전트 기본 설정의 full_command 항목을 실제로 확인).

10. 실습 체크리스트

[ ] 스크립트가 읽기 전용 명령만 쓰는지 검토
[ ] Rocky / Ubuntu 에서 각각 실행
[ ] 결과를 조사 디렉터리에 저장
[ ] n/a·(없음) 항목을 가시성 한계로 해석
[ ] auditd 자체 순환 설정 확인
[ ] 결과로 1차/2차 분석 소스 결정

11. 핵심 정리

  • 로깅 구성 점검은 스크립트로 표준화하면 빠르고 일관된다.
  • 조사 스크립트는 읽기 전용이어야 한다.
  • 파일 존재·크기·mtime·서비스 상태를 함께 봐야 "로그 없음"을 올바르게 해석한다.
  • audit.log는 auditd가, 나머지는 logrotate가 순환한다.
  • 실행 결과는 가시성 평가서로 보고서에 첨부한다.

12. 다음 편 연결

구분글
◀ 이전 글29. 배포판별 로그 분석 전략
▶ 다음 글31. systemd-journald 이해
시리즈Linux 로그 경로 정리 전체 보기
선행 시리즈리눅스 시스템 기초 · 파일 · 권한 · 사용자 관리 · 서비스 · 프로세스 관리 · Linux 시스템 보안 기초
profile
코드에 숨겨진 위협을 읽고 AI로 보안의 미래를 설계합니다. 프론트엔드 개발 경험을 자산 삼아 더 견고하고 지능적인 보안 운영 시스템을 구축해 나가는 과정을 기록합니다

0개의 댓글