리눅스 시스템 기초 · 입문편 — 본문의 "N편"은 입문 과정 번호다. 번호별 글과 전체 250편 구성은 통합 로드맵에서 확인할 수 있다.
리눅스 시스템 기초 8 / 50 · Part 1. Linux 기본 구조
실습 환경: Rocky Linux 9 (10.0.0.200) · VMware
이전 글: 7. Linux 디렉터리 구조
서버 전원을 켜면 로그인 프롬프트가 뜨기까지 여러 단계가 순서대로 실행된다. 이번 글은 펌웨어 → GRUB2 → 커널 → systemd → 서비스 로 이어지는 부팅 과정을 정리한다.
관제 관점에서 부팅 과정을 알아야 하는 이유:
| 단계 | 구성 요소 | 하는 일 | 관련 파일 |
|---|---|---|---|
| 1 | BIOS / UEFI | 하드웨어 점검(POST), 부트 장치 선택 | 펌웨어 설정 |
| 2 | GRUB2 | 커널과 initramfs를 메모리에 올리고 커널 파라미터 전달 | /boot/grub2/grub.cfg, /boot/loader/entries/ |
| 3 | Kernel | 하드웨어 초기화, 메모리·프로세스 관리 시작 | /boot/vmlinuz-* |
| 4 | initramfs | 실제 루트 파일 시스템을 마운트하기 위한 임시 환경 | /boot/initramfs-*.img |
| 5 | systemd | 첫 번째 사용자 공간 프로세스(PID 1), 모든 서비스 시작 | /etc/systemd/system/ |
| 6 | target | 도달할 최종 상태 | multi-user.target, graphical.target |
systemd의 target 은 "이 상태에 도달하려면 어떤 서비스들이 필요한가"를 묶은 그룹이다. 과거 SysV init의 runlevel과 비슷한 개념이다.
| target | 과거 runlevel | 용도 |
|---|---|---|
poweroff.target | 0 | 종료 |
rescue.target | 1 | 단일 사용자 복구 모드 |
multi-user.target | 3 | 서버 기본 (텍스트 로그인, 네트워크) |
graphical.target | 5 | 데스크톱 |
reboot.target | 6 | 재부팅 |

Rocky 9는 BLS(Boot Loader Specification) 방식을 사용한다. 부팅 항목이 /boot/loader/entries/*.conf에 커널별로 하나씩 있고, 커널 파라미터는 grubby 명령으로 관리한다. grub.cfg를 직접 편집하는 방식은 권장되지 않는다.
커널은 디스크 드라이버, LVM, 암호화 모듈이 있어야 루트(/) 파일 시스템을 읽을 수 있다. 그런데 그 모듈은 루트 파일 시스템 안에 있다. 이 문제를 풀기 위해 필요한 모듈만 담은 작은 임시 루트(initramfs) 를 먼저 메모리에 올리고, 여기서 실제 루트를 마운트한 뒤 제어권을 넘긴다. RHEL 계열은 dracut으로 생성한다.
커널이 실행하는 첫 번째 사용자 공간 프로세스가 systemd(PID 1) 다. 모든 프로세스의 조상이며(21편 이후 프로세스 트리에서 다시 본다), 유닛 간 의존성을 계산해 서비스를 병렬로 시작한다. 부팅 로그는 journald가 기록한다.
# 1) 부팅 방식과 Secure Boot
ls /sys/firmware/efi >/dev/null 2>&1 && echo UEFI || echo BIOS
mokutil --sb-state 2>/dev/null
# 2) 부트 파일과 부팅 항목
ls -l /boot
sudo ls /boot/loader/entries/
sudo grubby --default-kernel
sudo grubby --info=ALL | grep -E '^(kernel|args)'
# 3) 현재 커널에 전달된 파라미터
cat /proc/cmdline
# 4) 기본 target과 부팅 시간
systemctl get-default
systemd-analyze
systemd-analyze blame | head -10
systemd-analyze critical-chain
# 5) 부팅 기록과 재부팅 이력
uptime -s # 마지막 부팅 시각
who -b
last -x reboot shutdown | head
journalctl --list-boots # 저널 영구 저장 시 여러 부팅 표시
# 6) 이번 부팅 / 이전 부팅 로그
journalctl -b -p warning --no-pager | tail -20
journalctl -b -1 -e # 직전 부팅의 마지막 로그 (종료 원인)
journalctl --list-boots에 현재 부팅만 나온다면 저널이 메모리(/run/log/journal)에만 저장되는 상태다./var/log/journal디렉터리가 있으면 영구 저장된다(48편에서 설정).
아래 출력은 형식 설명용 예시다.
① systemd-analyze
Startup finished in 1.2s (kernel) + 2.8s (initrd) + 9.4s (userspace) = 13.4s
multi-user.target reached after 9.3s in userspace.
| 구간 | 의미 |
|---|---|
| kernel | 커널 초기화 |
| initrd | initramfs 단계 (루트 마운트까지) |
| userspace | systemd가 서비스를 시작하는 시간 |
② last -x reboot shutdown
reboot system boot 5.14.0-xxx.el9 Wed Sep 23 09:00 still running
shutdown system down 5.14.0-xxx.el9 Tue Sep 22 23:10 - 09:00
reboot system boot 5.14.0-xxx.el9 Tue Sep 22 18:02 - 23:10
정상 재부팅은 shutdown 기록 뒤에 reboot이 이어진다. shutdown 없이 reboot만 연속으로 있으면 전원 차단, 커널 패닉 같은 비정상 종료를 의미한다. 이때 journalctl -b -1 -e로 직전 부팅의 마지막 로그를 확인한다.
③ /proc/cmdline
BOOT_IMAGE=(hd0,msdos1)/vmlinuz-5.14.0-xxx root=/dev/mapper/rl-root ro crashkernel=... rd.lvm.lv=rl/root
평소와 다른 파라미터(init=, selinux=0, audit=0, rd.break)가 있다면 부팅 설정 변조를 의심한다. 특히 audit=0은 감사 로그를 끄고, selinux=0은 SELinux를 끈다.
| 단계 | 위협 | 대응 |
|---|---|---|
| 펌웨어 | 변조된 부트로더 실행 | UEFI Secure Boot, 펌웨어 암호 |
| GRUB2 | 콘솔 접근자가 부팅 메뉴를 편집해 rd.break나 init=/bin/bash로 root 쉘 획득 (RHEL 공식 root 비밀번호 복구 절차와 같은 원리) | GRUB 암호 설정, 콘솔 물리 보안 |
| 커널 파라미터 | audit=0, selinux=0으로 보안 기능 해제 | /proc/cmdline 기준값 비교, grubby 변경 감시 |
| systemd | 악성 서비스 등록 → 부팅마다 자동 실행 | 활성 유닛 목록 기준값 비교 (37편) |
| 재부팅 | 루트킷 적용·흔적 삭제 목적의 재시작 | 재부팅 이력과 변경 작업 일정 대조 |
# 방법 1: RHEL 계열 제공 도구 (user.cfg 생성)
sudo grub2-setpassword
sudo cat /boot/grub2/user.cfg # GRUB2_PASSWORD=grub.pbkdf2.sha512...
# 방법 2: 해시 생성 후 설정 파일에 직접 작성 (40_custom 방식)
grub2-mkpasswd-pbkdf2
# 생성된 해시를 /etc/grub.d/40_custom 에 superusers / password_pbkdf2 로 기록 후
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
두 방법 모두 부팅 메뉴 편집 시 계정·암호를 요구 하도록 만든다. 교육 과정의 정보시스템 진단 실습에서는 방법 2를 사용했다.
| 항목 | 명령 | 이상 기준 |
|---|---|---|
| 재부팅 이력 | last -x reboot shutdown | 작업 일정에 없는 재부팅, shutdown 없는 reboot |
| 커널 파라미터 | cat /proc/cmdline | audit=0, selinux=0, init= |
| 부팅 항목 변경 | ls -l --time-style=full-iso /boot/loader/entries/ | 최근 수정 |
| 기본 target | systemctl get-default | 서버인데 다른 target |
| 자동 시작 유닛 | systemctl list-unit-files --state=enabled | 기준값에 없는 유닛 |
| 로그 서비스 시작 | systemctl status auditd rsyslog | 비활성, 실패 |
[Event] 서버 모니터링: 새벽 03:12 호스트 다운 → 03:14 복구
↓
[확인] last -x → shutdown 기록 없이 reboot → 비정상 종료
journalctl -b -1 -e → 직전 부팅 마지막 로그
↓
[IOC] 재부팅 직전 sudo 사용 기록, 새 커널 모듈 로드, 새 systemd 유닛
↓
[판단] 장애(하드웨어·패닉) vs 의도적 재시작(변경 적용·흔적 삭제)
↓
[대응] 변경된 부팅 항목·유닛 원복, 원인 계정 조치, 재부팅 알림 규칙 추가
/boot/loader/entries/)이며, 커널 파라미터는 grubby로 관리한다.multi-user.target이다./proc/cmdline에 audit=0, selinux=0이 있으면 보안 기능 해제 시도를 의심한다.last -x, 원인은 journalctl -b -1로 확인한다. shutdown 없는 reboot는 비정상 종료 다.다음 글 「9. Linux 환경변수 이해」 에서는 로그인 후 쉘과 프로세스에 전달되는 환경변수를 다룬다. PATH, LD_PRELOAD 같은 변수가 어떻게 상속되는지, 그리고 이를 악용한 공격을 어떻게 탐지하는지 정리한다.