Linux 6.9 이후 LUKS suspend가 디스크 암호화 키를 메모리에서 지우지 못함
요약
Linux 커널 6.9 버전에서 LUKS suspend 기능이 메모리 내 디스크 암호화 키를 제대로 삭제하지 못하는 회귀 버그가 발견되었습니다. 이로 인해 Debian 등 특정 배포판의 보안 기능이 의도대로 동작하지 않을 수 있으나, 일반적인 RAM suspend 환경에서는 큰 영향이 없습니다.
핵심 포인트
- Linux 커널 6.9에서 thread keyring 속성 변화로 인한 LUKS 키 삭제 실패 발생
- Debian의 cryptsetup-suspend 애드온이 메모리에서 키를 지우지 못하는 문제
- RAM suspend와 Hibernate(디스크 suspend)의 보안 메커니즘 차이 설명
- Intel/AMD CPU의 전체 메모리 암호화 기능을 통한 콜드 부트 공격 방어 가능성
흥미로운 버그인 건 맞지만, 제목은 약간 클릭베이트처럼 느껴짐
이해한 바로는 cryptsetup luksSuspend가 공식 지원 기능이라기보다 Debian에서 만든 확장에 가까워서, 이 회귀가 영향을 준 것도 Debian뿐 아닌가 싶음
지원되거나 널리 테스트되는 것도 아닌 기능에 대해 커널을 탓할 수 있는지 잘 모르겠음
그래도 인상적이고, 이 회귀가 다시 생기지 않도록 테스트가 생긴 건 좋음. NixOSTests는 정말 훌륭하다는 OP 의견에도 동의함
다만 제목만 보면 특정 배포판 하나가 아니라 널리 퍼진 문제처럼 보임
기술적으로 정확한 제목을 노렸고 클릭을 유도하려던 건 아니었음
맞음. 기본 설정을 쓰는 사람들에게는 영향을 주지 않는데, 애초에 suspend 중에 볼륨 키가 안전하다고 기대하지 않을 것이기 때문임
Debian의 해법은 여러, 아마 대부분의 다른 배포판으로 포팅됐고, 개인 포트를 유지하던 사람도 꽤 있었을 것 같음 thread-keyring(7) 매뉴얼 페이지는 “thread keyring은 그것을 참조하는 스레드가 종료되면 파괴된다”고 약속함 cryptsetup 프로젝트는 사용자 공간에서 커널 공간으로 키를 올리는 메커니즘에서 이 속성에 의존했는데, 커널 6.9가 이 속성을 깨는 회귀를 도입함
이 기능을 Arch에서 써봤고, 일반적인 LUKS에서도 사용할 수 있음. 다만 아는 한 suspend할 때 기본으로 쓰이진 않음
아마 luksSuspend 이후 실제로 유용한 방식으로 RAM suspend를 실행하는 장치를 말하는 것 같은데, 그건 처음에 Debian 대상이었고 이후 Arch에도 생겼지만 둘 다 기본값은 아니었음
Debian 어느 버전에서 처음 6.9를 배포했는지 궁금함
다른 방법이 잘 안 보임. 절전, 즉 RAM suspend를 하면 모든 것이 RAM에 저장되고 암호화돼 있지만, 마스터 키는 커널 메모리에 남아 있는 것으로 기억함
반면 hibernate, 즉 디스크 suspend를 하면 RAM 전체 내용이 마스터 키까지 포함해 디스크에 기록되고 암호화되며 RAM은 지워짐
다시 깨울 때는 마스터 키를 복호화해 디스크 내용을 메모리로 다시 올리기 위해 패스프레이즈를 다시 입력해야 함
맞음. 대부분의 기본 Linux 배포판에서 그냥 노트북을 suspend하면 마스터 키를 포함한 모든 것이 메모리에 남아 있음
하지만 Debian은 선택 기능인 cryptsetup-suspend 애드온을 먼저 만들었고, 이건 메모리에서 키를 지우도록 되어 있는 luksSuspend 명령을 실행한 뒤 resume 시 패스프레이즈를 다시 요구함
커널 6.8까지는 설명대로 동작했지만, 커널 6.9부터는 조용히 동작하지 않게 됨
최근 5년 정도의 Intel/AMD CPU는 둘 다 운영체제에는 투명한 전체 메모리 암호화를 지원함
이 기능을 켜면 콜드 부트 공격은 과거 일이 됨. 보통 RAM 속도를 약 0.5% 낮춰서 기본으로 꺼져 있을 뿐임
Sleep 이후에 부팅 비밀번호를 다시 입력하지 않으니, 암호화 키가 아직 메모리에 남아 있는 게 분명함
배포판이 cryptsetup-luksSuspend를 쓰지 않는 게 분명함
이건 나에게 크게 신경 쓰이는 문제는 아님
디스크 암호화를 하는 유일한 이유는 노트북을 팔 때 누군가 세금 문서나 신용카드 정보를 뒤지는 걸 걱정하지 않기 위해서임
물론 노트북도 지우지만, 데이터가 드라이브 수준에서 암호화돼 있으면 포렌식 도구 같은 걸로 데이터를 복구할 위험이 아주 작다고 봄
적당한 절충안으로 LUKS 헤더만 지워도 됨
LUKS는 디스크를 열려면 볼륨 키 전체가 있어야 하는 안티 포렌식 알고리즘을 사용함. 키 블록들을 확산 알고리즘으로 결합하고 XOR해서 실제 마스터 키를 만드는 식이라, 이론상 볼륨 키의 한 섹터만 지워도 전체가 복구 불가능해야 함
즉 키의 블록 하나라도 없으면 나머지를 쉽게 추측할 수 없다는 뜻임
암호화 키가 강하다는 가정이면, 지우기는 이론적으로 중복 작업임
보안 전문가는 전혀 아니지만, 요즘 “리팩터링 중 파일을 넘나드는 C 체크 한 줄을 놓쳐서 생긴” 치명적 보안 버그가 정기적으로 발견되는 걸 보면 거대한 안전한 오픈소스 C 코드베이스라는 전제 자체가 의심스러움
C만의 문제는 아니지만, 특히 C에서는 불변식을 일관되게 강제하고 추적하기가 더 어렵고, 코드 변경 시에는 더 그렇다고 봄
불변식을 타입에 인코딩하는 함수형 프로그래밍이 현실적으로 확장 가능한 해법인지도 모르겠음. 모델 검사? LLM 퍼징? 명확한 경계를 가진 더 적은 기본 요소? seLinux는 그런 식으로 “검사”된 건가?
C의 단점은 보이고 새 프로젝트에 일반적으로 추천하지도 않지만, 이 특정 버그가 Rust의 borrow checker나 다른 언어의 타입 시스템이 잡아낼 좋은 예라고 보진 않음. 정적 분석기도 못 잡을 것 같음
본질적으로 이런 식임:
original: DoTheThing()
new: DoTheThingSlightlyDifferentButKeepMyCredentialsAlive()
fix: DoTheThingSlightlyDifferentButDoInFactNOTKeepMyCredentialsAlive()
경험상 까다로운 버그의 상당수는 상위 수준 시스템 불변식 위반에서 나오고, 이런 건 자동화할 수 있는 성격으로 보이지 않음
Lean 같은 것으로도 프로그램이 특정 속성을 만족한다는 건 증명할 수 있지만, 그 속성을 먼저 떠올렸어야 함. 증명이 불변식을 대신 발견해주지는 않음
관련 보안 속성을 떠올렸다면 회귀 테스트를 작성하는 건 어렵지 않았을 것임. 정말 어려운 부분은 구현을 안전하게 표현하는 게 아니라, 구현이 보존해야 하는 속성이 있다는 사실을 깨닫는 데 있다고 봄
안전한 공개 코드베이스라는 전제 자체는 괜찮음
문제는 감사 가능성이 더 높다고 해서 자동으로 더 많이 감사되는 건 아니라는 데 있음
충분한 실력을 가진 사람들이 충분한 시간을 들여 작업해야 함
Rust로 번역해도 “Rust 체크 한 줄을 놓쳤다”가 됐을 것임
이건 관심사가 교차하고 도메인 간 지식이 부족해서 생긴 버그임. Lisp나 어셈블리어에서도 아마 같았을 것임
여기서 얻을 교훈은 어떤 기능에 최소한 관련 테스트 케이스가 없다면, 실제 기능이 아니라는 것임
“거대한 안전한 오픈소스 C 코드베이스”라는 전제가 의심스럽게 보이는 이유는, 코드 리뷰가 때로는 명세의 형식화된 버전에 접근할 수 있는 이상화된 정지 문제와 크게 다르지 않기 때문임
다시 말해 무엇이 보안 이슈인지에 대한 엄격한 정의가 없음
연방기관이 키를 얻을 방법이 절실히 필요했던 건가? 이건 버그도어인가? 커밋 추적은 됐나?
최근 이런 패턴을 많이 봐서 조금 의심스러워지기 시작함. 사람들이 여기에 더 민감해져서 더 많이 올리기 때문일 수도 있음
이건 회귀임. 사용자 공간 애플리케이션도 조용히 실패했을 것이고, 여러 부주의가 이어진 결과임
암호화 키가 메모리에 있다는 게 곧 추출할 수 있다는 뜻은 아님. 원래 있으면 안 되는 곳에 불필요하게 무기한 남겨둔 것에 가까움
이런 회귀는 모든 것이 계속 “동작”하기 때문에 놓치기 쉬움. 보안 버그는 자기를 드러내지 않는 경우가 많음
Fedora 노트북에서는 suspend 15분 뒤 디스크로 hibernate하도록 Linux를 설정해뒀음. 메모리 전원을 꺼버리면 이런 Debian 특정 버그는 문제가 되지 않음
Debian의 Linux 도구 확장이 이론상으로는 좋지만, 실제로 콜드 부트 공격을 걱정한다면 LUKS 키뿐 아니라 모든 키와 중요한 문서가 메모리에서 지워져야 함
그래서 콜드 부트를 막는 제대로 된 방법은 결국 hibernate뿐임
그런데 resume할 때 메모리를 복호화할 키는 어디서 가져옴?
아는 한 TPM을 쓰지 않으면 실용적이지 않음. 그리고 TPM을 쓰면 사실상 TPM에 운명을 맡기는 셈임
이 취약점이 상용 운영체제에 있었다면 이 HN 스레드가 어떻게 보였을지 상상해보면 됨
최상위 댓글은 분명 Applosoft가 더 이상 소프트웨어 품질에 신경 쓰지 않는다거나 “OS에 바이브 코딩 쓰레기를 허용하면 이렇게 된다”는 내용이었을 것임
그 아래 댓글은 감시 산업 복합체와 NSA에 대한 음모론이었을 텐데, 다른 곳에서는 미친 소리겠지만 HN에서는 그렇지 않았을 것임
AI 자동 생성 콘텐츠
본 콘텐츠는 GeekNews의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기