Linux 로그 경로 정리 · 30/50 · Part 3. Ubuntu / Debian 로그 경로
선행 학습 → 29. 배포판별 로그 분석 전략 · 기초 29. 명령어 조합을 이용한 시스템 분석
이번 글 → Linux 로그 경로 자동 탐색 스크립트
이어서 → 31. systemd-journald 이해
29편의 탐색 전략을 스크립트로 자동화합니다. 목표는 두 가지입니다.
핵심 요약
- 점검 6항목: OS · Logging System · Key log files · SSH log source · Service log dirs · Rotation
- 안전 원칙: 읽기 전용 명령만, 출력은 표준출력으로, 존재하지 않는 파일은 "(없음)"으로 표시
- 실행 결과 자체가 "가시성 평가서"가 된다.
| 설계 원칙 | 구현 |
|---|---|
| 읽기 전용 | stat, grep -c, systemctl is-active, ls 만 사용 (rm, sed -i, > 리다이렉션 없음) |
| 배포판 독립 | /etc/os-release 의 ID_LIKE 로 계열 판단 후 파일 목록 선택 |
| 실패 허용 | 2>/dev/null, 없는 파일은 "(없음)" 출력, set -u 로 오타 변수 방지 |
| 읽기 쉬운 출력 | printf '%-22s %s' 로 2열 정렬 |

[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 자체 순환
스크립트가 점검하는 경로:
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}
#!/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 (결과는 조사 디렉터리에 저장)

위 이미지는 이 스크립트를 Rocky Linux 9.8 컨테이너 실습 환경에서 실제로 실행한 결과입니다. 같은 스크립트를 Ubuntu 24.04 환경에서도 실행해 Family debian, journal storage persistent, auditd tools not installed 로 판별되는 것을 확인했습니다.
실제 출력에서 읽어낸 사실:
| 출력 | 해석 |
|---|---|
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 ROTATE | audit.log는 logrotate가 아니라 auditd가 8MB × 5개로 직접 순환(41편) |
이 결과 하나로 "이 서버는 파일 로그·감사 로그 모두 가시성이 없다"는 판단 근거를 제시할 수 있습니다.
| 정상 서버 기대 결과 | 의심 결과 |
|---|---|
| 3개 로깅 서비스 active | 운영 서버인데 rsyslog/auditd inactive |
| 핵심 로그 mtime 최신 | 한 파일만 오래 멈춘 mtime |
| 감사 룰 수 > 0 | 룰 0 (규칙 삭제 가능성: auditctl -D) |
| 권한 600/640 | 644 이상 또는 비root 소유 |
<wodle name="command"> 또는 <localfile><log_format>full_command</log_format> 로 주기 실행하여 로깅 상태 변화를 감시할 수 있다(47편에서 에이전트 기본 설정의 full_command 항목을 실제로 확인).[ ] 스크립트가 읽기 전용 명령만 쓰는지 검토
[ ] Rocky / Ubuntu 에서 각각 실행
[ ] 결과를 조사 디렉터리에 저장
[ ] n/a·(없음) 항목을 가시성 한계로 해석
[ ] auditd 자체 순환 설정 확인
[ ] 결과로 1차/2차 분석 소스 결정
| 구분 | 글 |
|---|---|
| ◀ 이전 글 | 29. 배포판별 로그 분석 전략 |
| ▶ 다음 글 | 31. systemd-journald 이해 |
| 시리즈 | Linux 로그 경로 정리 전체 보기 |
| 선행 시리즈 | 리눅스 시스템 기초 · 파일 · 권한 · 사용자 관리 · 서비스 · 프로세스 관리 · Linux 시스템 보안 기초 |