[리눅스] GRUB 부트로더를 이용한 응급조치/부트로더

목차

리눅스에서 root 비밀번호를 잊어버렸을 때, GRUB 부트로더를 이용하면 시스템을 재설치하지 않고도 응급조치로 비밀번호를 복구할 수 있다. GRUB 부팅 메뉴에서 커널 옵션을 잠깐 바꿔 셸로 진입한 뒤 passwd로 새 비밀번호를 설정하는 방식이다. 이 글에서는 GRUB으로 root 비밀번호를 재설정하는 절차와, 반대로 아무나 이 방법을 악용하지 못하도록 GRUB 자체에 비밀번호를 거는 보안 설정까지 CentOS 7·8 기준으로 정리한다.

GRUB2 부트로더란?

GRUB(GRand Unified Bootloader)은 컴퓨터의 전원을 켰을 때 가장 먼저 실행되어 운영체제를 메모리에 올리고 시동을 거는 프로그램이다. 지금 CentOS·RHEL·Ubuntu 등 대부분의 리눅스 배포판이 쓰는 버전은 GRUB2로, 부팅 메뉴 표시·커널 선택·커널 부팅 옵션 전달을 담당한다.

리눅스의 부팅 과정을 단순화하면 다음 순서를 거친다.

  1. BIOS/UEFI — 하드웨어를 점검하고 부팅 디스크를 찾는다.
  2. 부트로더(GRUB2) — 부팅할 커널을 고르고 커널 옵션을 붙여 실행한다.
  3. 커널 + initramfs — 커널이 올라오고 임시 루트(initramfs)가 실제 루트 파일시스템을 마운트한다.
  4. systemd — 첫 프로세스가 떠 서비스들을 차례로 올린다.

여기서 핵심은 GRUB2 단계에서 커널에 전달하는 부팅 옵션을 바꿀 수 있다는 점이다. 비밀번호 검증을 담당하는 정상적인 init(systemd) 대신 셸을 직접 띄우도록 옵션을 바꾸면, 로그인 없이 root 권한으로 진입해 비밀번호를 새로 설정할 수 있다. GRUB 응급조치는 바로 이 원리를 이용한다. GRUB 설정과 커널 이미지는 /boot 디렉터리에 들어 있다.

GRUB 응급조치가 필요한 경우

상황을 하나 가정해보자. 리눅스 작업을 해야 하는데 root 사용자의 비밀번호를 잊어버려 로그인이 안 된다. 단순 ‘학습’용이라면 재설치하면 그만이지만, 중요한 파일이 있거나 현업 서버라면 재설치는 선택지가 아니다. 이럴 때 GRUB 부트로더로 셸에 진입해 root 비밀번호만 새로 설정하면 시스템을 그대로 살릴 수 있다.

단, 이 작업에는 전제가 있다. 물리 콘솔(또는 콘솔 접근권)이 있어야 한다. SSH 같은 원격 접속만으로는 GRUB 메뉴를 편집할 수 없다. 바꿔 말하면, 콘솔에 손댈 수 있는 사람은 누구나 root 권한을 가져갈 수 있다는 뜻이라 이후 본 글의 후반부에서 GRUB 자체에 잠금을 거는 보안 설정을 함께 다룬다.

GRUB으로 root 비밀번호 재설정

root 비밀번호를 분실해 로그인이 안 되는 상황이라고 가정한다. 시스템을 부팅하면 아래와 같은 GRUB 부팅 선택 화면이 나타난다.

GRUB2 부팅 선택 화면 - 커널 항목 선택

1단계 — GRUB 메뉴에서 커널 옵션 편집

부팅할 커널 항목에 커서를 둔 상태에서 E 키를 누른다. 그러면 해당 항목의 부팅 설정을 직접 수정할 수 있는 편집 화면으로 들어간다. 방향키로 linux(또는 linux16)로 시작하는 커널 행을 찾아 행 맨 끝으로 이동한다. 이 행은 다음과 비슷한 모습이다.

linux ($root)/boot/vmlinuz-3.10.0-... root=/dev/mapper/cl-root ro rhgb quiet

여기서 화면 출력을 가리는 rhgb quiet 두 문구를 지운다(셸 메시지를 보기 위함). 그리고 행 맨 끝에 다음을 덧붙인다.

init=/bin/sh

이 옵션은 정상적인 부팅 과정(systemd) 대신 셸(/bin/sh)을 곧바로 첫 프로세스로 실행하라는 뜻이다. 편집을 마쳤으면 Ctrl + X(또는 F10)를 눌러 부팅한다.

2단계 — 셸 진입 및 root 확인

부팅이 끝나면 로그인 절차 없이 sh-4.4#와 같은 프롬프트가 나타난다. 프롬프트가 바로 보이지 않으면 Enter를 한 번 눌러 보자. 현재 사용자가 root인지 확인한다.

whoami
# 출력: root

3단계 — 루트 파티션을 읽기/쓰기로 재마운트

이 상태에서 바로 passwd를 실행하면 다음과 같은 에러가 난다.

passwd: Authentication token manipulation error

인증 토큰 조작 오류‘라는 이 메시지는, 루트(/) 파티션이 읽기 전용(read-only)으로 마운트되어 있어 비밀번호 파일에 쓸 수 없기 때문에 발생한다. mount 명령으로 확인하면 / 파티션이 ro(read-only)로 잡혀 있다. 다음 명령으로 읽기/쓰기 모드로 다시 마운트한다.

mount -o remount,rw /

다시 mount를 실행해 / 파티션이 rw로 바뀌었는지 확인한다.

4단계 — 비밀번호 변경 및 SELinux 재라벨링

이제 passwd로 root 비밀번호를 새로 설정한다. 8자 이상으로 입력하면 ‘password updated successfully’ 메시지가 나온다.

passwd
# 새 비밀번호 입력 → 재입력

여기서 한 가지 빠뜨리기 쉬운 단계가 있다. SELinux가 Enforcing 상태라면, 방금 수정한 /etc/shadow 파일의 보안 컨텍스트가 어긋나 다음 부팅 때 새 비밀번호로 로그인이 막힐 수 있다. 이를 막으려면 다음 부팅 시 파일시스템 전체의 SELinux 라벨을 다시 매기도록 표시 파일을 만들어 둔다.

touch /.autorelabel

마지막으로 정상 부팅으로 빠져나온다. init=/bin/sh로 들어왔기 때문에 일반 reboot가 동작하지 않을 수 있어 다음 중 하나를 사용한다.

exec /sbin/init        # 정상 부팅으로 전환
# 또는
exec /sbin/reboot      # 재부팅

/.autorelabel을 만들었다면 재부팅 시 SELinux 라벨링이 수행되어 부팅이 평소보다 오래 걸리고, 끝나면 자동으로 한 번 더 재부팅된다. 그 뒤 새 비밀번호로 root 로그인이 된다.

CentOS 8 / RHEL 8 — rd.break 방식

init=/bin/sh 방식은 CentOS 7 계열에서 가장 직관적이지만, CentOS 8·RHEL 8·Rocky·Alma 등 최신 배포판에서는 rd.break를 이용한 표준 절차가 더 안정적이다. 이 방식은 실제 루트가 마운트되기 직전(initramfs 단계)에서 멈춘 뒤 chroot로 진짜 시스템에 들어가 비밀번호를 바꾼다. 순서는 다음과 같다.

  1. GRUB 메뉴에서 Elinux 행 끝에 rhgb quiet 대신 rd.break 추가 → Ctrl + X
  2. switch_root:/# 프롬프트에서 mount -o remount,rw /sysroot
  3. chroot /sysroot 로 실제 시스템으로 전환
  4. passwd 로 새 비밀번호 설정
  5. touch /.autorelabel 로 SELinux 재라벨링 예약
  6. exit 두 번 입력해 재부팅(chroot 종료 → rd.break 종료)
# rd.break 진입 후
mount -o remount,rw /sysroot
chroot /sysroot
passwd
touch /.autorelabel
exit
exit

두 방식 모두 핵심은 같다. GRUB에서 커널 옵션을 바꿔 인증을 우회 → 루트를 쓰기 가능하게 → passwd → SELinux 재라벨링이다. 자신의 배포판 버전에 맞는 쪽을 쓰면 된다.

GRUB 부트로더에 비밀번호 걸기

여기서 의문이 든다. 위 방법만 알면 콘솔에 접근할 수 있는 누구나 root 권한을 얻을 수 있지 않은가? 실제로 이는 물리 보안이 확보되지 않은 환경에서 심각한 취약점이다. 그래서 이번에는 GRUB 메뉴 편집 자체에 비밀번호를 걸어 부팅 옵션을 함부로 바꾸지 못하게 만든다.

먼저 root 계정으로 로그인한다(반드시 root 권한 필요). 먼저 GRUB 메뉴를 충분히 볼 수 있도록 부팅 대기 시간을 늘려 둔다. /etc/default/grub 파일을 vi로 열어 다음 값을 수정한다.

vi /etc/default/grub
# 아래 값으로 수정
GRUB_TIMEOUT=20

이제 GRUB 슈퍼유저와 비밀번호를 정의한다. /etc/grub.d/00_header 파일을 열어 맨 아래에 다음 블록을 추가하고 저장한다(:wq). thisislinux는 GRUB 슈퍼유저 이름, 그 뒤 값은 비밀번호다.

vi /etc/grub.d/00_header

cat << EOF
set superusers="thisislinux"
password thisislinux 1234
EOF

여기서 password ... 1234는 비밀번호를 평문으로 적은 형태다. 실제 운영에서는 평문 대신 암호화 해시를 권장한다. grub2-mkpasswd-pbkdf2로 해시를 생성한 뒤 password_pbkdf2 지시어를 쓰는 방식이다.

# 비밀번호 해시 생성(권장)
grub2-mkpasswd-pbkdf2
# 출력된 grub.pbkdf2.sha512... 해시를 아래처럼 사용
# password_pbkdf2 thisislinux grub.pbkdf2.sha512.10000.XXXX...

설정을 마쳤으면 실제 부팅에 사용되는 grub.cfg를 다시 생성해 변경 사항을 반영한다(BIOS 기준 경로).

grub2-mkconfig -o /boot/grub2/grub.cfg
# UEFI 부팅 시스템이라면 경로가 다를 수 있다
# grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg

reboot으로 재부팅한 뒤 GRUB 화면에서 E 키를 누르면, 이제는 곧바로 편집되지 않고 슈퍼유저 이름과 비밀번호를 요구한다. 인증에 성공해야만 부팅 옵션을 편집할 수 있다.

주의: 위 실습은 학습 목적이라 비밀번호를 1234로 설정했지만, 실무에서는 절대 이렇게 단순한 값을 쓰면 안 된다. 충분히 길고 복잡한 비밀번호를 사용하고, 위에서 소개한 password_pbkdf2 해시 방식으로 평문 노출을 피해야 한다. 또한 GRUB 잠금은 어디까지나 물리 보안의 보조 수단일 뿐, BIOS/UEFI 비밀번호와 디스크 암호화(LUKS)를 함께 적용해야 실질적인 방어가 된다.

자주 묻는 질문(FAQ)

init=/bin/sh와 rd.break는 무엇이 다른가?

init=/bin/sh는 실제 루트가 마운트된 뒤 systemd 대신 셸을 첫 프로세스로 띄우는 방식이고, rd.break는 그보다 이른 initramfs 단계에서 멈춘 뒤 chroot /sysroot로 실제 시스템에 들어가는 방식이다. CentOS 7에서는 전자가, CentOS 8 이상에서는 후자가 표준으로 안내된다. 둘 다 비밀번호 변경 후 touch /.autorelabel이 필요하다는 점은 동일하다.

touch /.autorelabel을 빼먹으면 어떻게 되나?

SELinux가 Enforcing이면 변경한 /etc/shadow의 보안 컨텍스트가 어긋나, 비밀번호는 분명히 바꿨는데도 새 비밀번호로 로그인이 안 되는 증상이 생긴다. SELinux를 Permissive로 운영 중이거나 비활성화한 시스템이라면 생략해도 되지만, 기본값(Enforcing)에서는 반드시 실행하는 편이 안전하다.

SSH 원격 접속만 있을 때도 가능한가?

불가능하다. GRUB 메뉴 편집은 부팅 초기 단계라 콘솔(물리 화면 또는 클라우드·가상화 콘솔)이 필요하다. 클라우드 인스턴스라면 제공사의 시리얼 콘솔/VNC 콘솔 기능을 통해 동일하게 작업할 수 있다.

정리

GRUB 부트로더를 이용하면 root 비밀번호를 잊어버려도 재설치 없이 복구할 수 있다. 핵심은 GRUB 메뉴에서 커널 옵션을 바꿔 인증을 우회하고(CentOS 7은 init=/bin/sh, CentOS 8 이상은 rd.break), 루트를 mount -o remount,rw로 쓰기 가능하게 만든 뒤 passwd로 비밀번호를 변경하고, touch /.autorelabel로 SELinux 라벨을 다시 매기는 것이다. 다만 이 방법은 콘솔 접근만 있으면 누구나 root를 탈취할 수 있다는 보안 취약점이 되므로, GRUB에 슈퍼유저·비밀번호를 설정해 부트로더 편집 자체를 막아 두는 것이 안전하다. 부팅·복구를 더 깊이 이해하려면 리눅스 파일 시스템 구조/boot 디렉터리 역할도 함께 알아 두면 좋다.

Reference

💬 댓글 0

💬 댓글을 남기려면?
첫 댓글을 남겨보세요 ✨

이 콘텐츠가 도움이 됐나요?

누스쿨 커뮤니티에서 더 많은 커리어 전략을 나눠요