물리 서버 백업 볼륨의 LUKS2 키 교체와 읽기 전용 복구

물리 서버 백업 볼륨의 LUKS2 키 교체와 읽기 전용 복구

물리 서버 백업 볼륨의 LUKS2 키 교체와 읽기 전용 복구

백업 파일을 디스크에 저장하고 수신 계정도 격리했더라도, 퇴역한 디스크나 오프라인 사본의 데이터를 그대로 읽을 수 있는지는 별도로 확인해야 할 보안 경계입니다. 볼륨 암호화는 잠금이 해제되지 않은 데이터를 보호하는 수단이지, 운영 중인 시스템의 접근 제어를 대체하는 수단은 아닙니다. 암호를 교체하면 이전 암호를 무효화할 수 있지만, 이미 유출된 데이터를 되돌릴 수는 없습니다. 이 글에서는 기존 데이터 디스크를 건드리지 않고 독립된 파일 컨테이너로 LUKS2 키 교체와 복구를 실습합니다.

1. 암호화로 보호할 대상부터 정의하기

OnuCloud 물리 서버에는 1TB NVMe 2개가 기본 제공됩니다. 각 드라이브는 직접 연결되며 하드웨어 RAID는 구성되어 있지 않습니다. 볼륨 암호화, 디스크 이중화, 원격지 백업은 각각 다른 문제를 해결합니다. 암호화는 오프라인 상태에서의 데이터 읽기를 제한하고, 이중화는 장치 고장에 대비하며, 원격지 백업은 독립된 사본을 확보합니다. 디스크 2개를 모두 암호화한다고 해서 복구 가능한 백업이 저절로 생기는 것은 아닙니다.

아래 실습은 Ubuntu Server 24.04 LTS를 기준으로 합니다. 관리자 권한과 cryptsetup, e2fsprogs, 약 256 MiB의 실제 여유 공간이 필요합니다. 먼저 배포판의 패키지 관리 도구로 필요한 도구를 설치한 다음, 실습 전용 관리자 셸을 여세요. 변수가 사라지지 않도록 이후 명령은 모두 같은 셸에서 실행합니다.

잠금이 해제된 볼륨은 해당 권한을 가진 프로세스에서 여전히 읽을 수 있습니다. 볼륨 암호화는 관리자 권한의 악용을 막지 못하며, 쓰기가 진행 중인 데이터베이스의 사본에 애플리케이션 일관성을 자동으로 보장하지도 않습니다.

운영 환경에 적용하기 전에 암호 보관 담당자, 헤더 백업을 읽을 수 있는 사람, 인력 변경 시 접근 권한을 회수하는 절차를 정해야 합니다. 암호를 명령 인수, 스크립트, 지원 티켓 본문에 적지 마세요.

2. 실제 디스크를 건드리지 않는 실습 볼륨 만들기

mktemp로 독립된 작업 디렉터리를 만들고, 모든 포맷 작업은 그 안에 새로 만든 파일만 대상으로 수행합니다. 실행 전에 매핑 이름 backup-drill이 사용 중인지 확인하세요. 이미 존재한다면 작업을 중단하고 원인을 조사해야 하며, 정체를 모르는 매핑을 닫아서는 안 됩니다. 예제에서는 암호를 대화형으로 입력하며, 최초 암호는 슬롯 0에 저장합니다.

umask 077
work=$(mktemp -d /var/tmp/luks-drill.XXXXXX)
image="$work/backup.img"
mountpoint="$work/mnt"
mkdir "$mountpoint"
truncate -s 256M "$image"
cryptsetup luksFormat --type luks2 --key-slot 0 "$image"
cryptsetup open "$image" backup-drill
mkfs.ext4 /dev/mapper/backup-drill
mount /dev/mapper/backup-drill "$mountpoint"
printf 'backup-recovery-check\n' > "$mountpoint/probe.txt"
(
  cd "$mountpoint"
  sha256sum probe.txt
) > "$work/expected.sha256"
sync
umount "$mountpoint"
cryptsetup close backup-drill

각 명령이 성공한 것을 확인한 뒤 다음 명령을 실행하세요. 특히 잠금 해제에 실패한 상태에서 포맷을 계속해서는 안 되며, 파일 경로를 확인되지 않은 NVMe 장치 이름으로 바꿔서도 안 됩니다. 희소 파일의 논리적 크기는 실제 디스크 사용량과 다릅니다. 실습 중에도 파일이 저장된 파일 시스템에 충분한 여유 공간이 있는지 확인해야 합니다.

체크섬 목록은 복구할 때 독립적으로 대조할 수 있도록 컨테이너 밖에 저장합니다. 운영 환경에서도 목록의 출처를 신뢰할 수 있어야 합니다. 데이터와 목록을 함께 변조할 수 있다면, 해시가 일치한다는 사실만으로 출처의 신뢰성을 입증할 수는 없습니다.

3. 새 슬롯을 먼저 검증한 뒤 이전 암호 폐기하기

먼저 cryptsetup luksDump "$image"를 실행해 유형이 LUKS2인지, 슬롯 0이 활성화되어 있고 슬롯 1이 비어 있는지 확인합니다. 실제 볼륨의 슬롯 구성은 다를 수 있으므로 번호를 그대로 따라 사용해서는 안 됩니다. 아래에서 새 암호를 추가할 때는 먼저 이전 암호를 입력해 작업을 승인한 다음, 안내에 따라 새 암호를 설정합니다.

cryptsetup luksAddKey --key-slot 1 "$image"
cryptsetup open --test-passphrase --key-slot 1 "$image"
cryptsetup luksDump "$image"

두 번째 명령에서는 새 암호를 입력합니다. 종료 코드가 0이어야 검증에 성공한 것입니다. --test-passphrase는 잠금 해제 가능 여부만 시험하고 매핑을 만들지 않으므로 파일 시스템의 마운트 상태에 영향을 주지 않습니다. 슬롯을 추가하는 것은 볼륨 키를 교체하는 작업이 아니며, 전체 데이터를 다시 암호화한다는 뜻도 아닙니다.

권한이 있는 담당자가 새 암호를 안전하게 보관했는지 확인한 뒤 슬롯 0을 삭제합니다. 이 실습에서는 계속 사용할 새 암호로 삭제 작업을 승인합니다.

cryptsetup luksKillSlot "$image" 0
cryptsetup open --test-passphrase "$image"

마지막 명령에서는 먼저 이전 암호를 입력해 실패하는지 확인합니다. 그런 다음 같은 명령을 다시 실행하고 새 암호를 입력해 성공하는지 확인합니다. 자동 재시도로 실패를 덮거나 슬롯 목록만 보고 교체가 끝났다고 판단해서는 안 됩니다. 검증 증적에는 슬롯 변경 내역과 두 번의 시험 결과를 남기되, 암호 자체는 포함하지 않습니다.

4. 헤더 백업도 민감한 접근 수단으로 관리하기

LUKS 헤더에는 잠금 해제에 필요한 핵심 메타데이터가 저장됩니다. 데이터 영역은 남아 있지만 헤더가 손상된 경우, 헤더 백업이 복구의 전제 조건이 될 수 있습니다. 헤더 백업은 데이터 사본이 아니며, 유일한 데이터 볼륨과 함께 유실되어서도 안 됩니다. 교체가 성공한 뒤 현재 헤더를 내보냅니다.

cryptsetup luksHeaderBackup "$image" \
  --header-backup-file "$work/header-current.bin"
chmod 600 "$work/header-current.bin"
cryptsetup luksDump "$image" > "$work/luks-layout.txt"

디렉터리와 파일 권한은 로컬 접근만 제한합니다. 운영용 헤더 사본은 접근이 통제되는 별도의 보관 위치에 저장해야 합니다. 해당 볼륨, 교체 작업 차수, 접근 권한이 있는 담당자를 기록하고, 어떤 데이터 사본에 대응하는지도 명확히 관리하세요. 헤더 파일을 일반적인 진단 자료처럼 첨부해 보내서는 안 됩니다.

특히 과거 버전을 별도로 관리해야 합니다. 이전 헤더에는 이미 폐기한 슬롯이 남아 있을 수 있으며, 그 헤더를 복원하면 이전 암호가 다시 유효해질 수 있습니다. 따라서 현재 볼륨에서 이전 슬롯을 삭제했다고 해서 모든 과거 자료에 남아 있는 접근 수단까지 폐기된 것은 아닙니다. 볼륨 키 유출이 위협에 포함된다면 암호만 바꾸는 것으로는 부족하므로, 재암호화나 마이그레이션을 별도로 계획해야 합니다.

5. 읽기 전용 복구는 파일 내용까지 검증하기

실습 볼륨은 정상적으로 마운트 해제된 상태입니다. 이제 읽기 전용 매핑을 다시 만들고, ext4 파일 시스템을 읽기 전용이면서 저널을 재생하지 않는 방식으로 마운트할 수 있습니다. 두 단계의 제한은 각각 블록 장치와 파일 시스템의 동작을 제어합니다.

cryptsetup open --readonly --key-slot 1 "$image" backup-drill
mount -t ext4 -o ro,noload /dev/mapper/backup-drill "$mountpoint"
findmnt -no SOURCE,FSTYPE,OPTIONS "$mountpoint"
(
  cd "$mountpoint"
  sha256sum -c "$work/expected.sha256"
)
touch "$mountpoint/should-not-exist"

새 암호를 입력한 뒤에는 마운트 옵션에 ro가 포함되어 있어야 하고, 체크섬 검증은 성공해야 하며, 마지막 쓰기 시도는 실패해야 합니다. 쓰기가 성공한다면 즉시 검증을 중단하고 실제 마운트 대상을 확인해야 합니다. 이를 사소한 예외로 넘겨서는 안 됩니다. noload는 비정상적인 파일 시스템 상태를 감추기 위한 옵션이 아닙니다. 정상적으로 마운트 해제되지 않은 사본을 다룰 때는 먼저 원본을 보존하고 작업용 사본에서 복구 가능성과 방법을 검토해야 합니다.

작업을 마치면 먼저 디렉터리의 마운트를 해제하고 그다음 매핑을 닫습니다. 남아 있는 마운트와 매핑이 없는지 확인한 뒤 실습 디렉터리를 정리하세요. 운영 자료는 정해진 보관 규칙에 따라 관리하고, 임시 파일 정리에 섞어 처리하지 않습니다.

최종 기록은 다음 네 가지 질문에 답할 수 있어야 합니다. 새 암호만으로 잠금을 해제할 수 있는가, 이전 암호는 무효화되었는가, 헤더 사본은 통제된 상태로 보관되는가, 복구한 파일은 신뢰할 수 있는 체크섬 목록과 일치하는가. 네 항목을 모두 통과해야 나중에 검토할 수 있는 키 교체 및 복구 실습이 완성됩니다.

자주 묻는 질문

LUKS2 암호를 바꾸면 볼륨 전체가 다시 암호화되나요?

이 절차는 볼륨 키를 해제하는 슬롯의 암호 자료만 변경합니다. 전체 데이터를 다시 암호화하거나 볼륨 키를 바꾸지 않습니다. 새 슬롯을 먼저 검증한 뒤 이전 슬롯을 삭제합니다.

이전 암호를 폐기한 뒤에도 과거 헤더 백업을 보호해야 하나요?

그렇습니다. 과거 헤더에는 이전 슬롯이 남아 있을 수 있어 복원 시 이전 암호가 다시 작동할 수 있습니다. 민감한 키 자료로 보관하고 교체 후 새 헤더를 백업합니다.

읽기 전용 매핑과 ro,noload를 함께 쓰는 이유는 무엇인가요?

읽기 전용 매핑은 블록 쓰기를 차단하고 ext4의 ro,noload는 저널 재생도 막습니다. 정상적으로 마운트 해제한 실습 볼륨을 읽는 용도이며 파일시스템 복구를 대신하지 않습니다.

AMD EPYC 7543P 전용 서버

월 $472부터

OnuCloud 전용 서버 구성 OnuCloud 요금 확인

워크로드에 맞춘 전용 서버 구성

AMD EPYC 7543P 전용 서버입니다. 스토리지 이중화와 데이터 백업은 관리자가 직접 계획해야 합니다.