TECH 으로 돌아가기
TECH HACKER NEWS 어제 8분 읽기 42 READS

랙 하나를 통째로 훔쳐야 데이터가 열린다 — 오xide의 키 계층 설계

서버 하드웨어를 만드는 Oxide는 랙(rack) 수준의 저장 데이터 보호를 어떻게 설계할지 정리한 기술 문서(RFD 0301)를 공개했다. 핵심 질문은 단순하다. 공격자가 랙에서 디스크 몇 개나 슬레드(sled) 몇 대를 물리적으로 뜯어 가더라도, 그 안에서 쓸모 있는 정보를 복구하지 못하게 하려면 키를 어떻게 계층적으로 관리해야 하는가다. 이 글은 그 설계의 뼈대와, 분산 시스템 특유의 제약이 어떻게 설계를 비틀어 놓는지를 짚는다.

신뢰 정족수와 랙 시크릿

설계의 뿌리에는 '랙 시크릿(rack secret)'이 있다. 이 값은 신뢰 정족수(Trust Quorum) 구조 위에서 샤미르 비밀 분산(Shamir Secret Sharing)으로 관리된다. 딜러(dealer) 프로세스가 랙 시크릿을 N개의 고유한 조각(share)으로 쪼개, 각 슬레드의 부트스트랩 에이전트에게 나눠 준다. 조각을 나눌 때는 각 구성원의 플랫폼 신원 정보도 함께 전달되는데, 이 신원은 RoT(Root of Trust)의 공개키 인증서에 새겨져 있어 상대가 주장하는 대로의 존재인지 검증할 수 있다. 이후 에이전트들은 서로 sprockets 세션을 맺어 멤버십을 확인하고, 자기 것 외에 K-1개의 조각을 더 받아 총 K개로 랙 시크릿을 복원한다. 여기서 중요한 성질은, K개 미만으로는 랙 시크릿에 관한 어떤 정보도 얻을 수 없다는 점이다.

조각 자체는 현재 각 슬레드의 M.2 드라이브에 암호화되지 않은 상태로 저장된다. 따라서 공격자는 최소 K개의 드라이브를 훔쳐야 랙 시크릿을 재구성할 수 있는데, 물리적 접근과 상당한 시간·소란이 필요해 현실성이 낮다. 문서는 향후 이 조각들을 RoT로 '봉인(seal)'해 슬레드 부팅 시에만 복호화되도록 만들 계획을 밝힌다. 봉인이 적용되면 공격자는 K대의 슬레드를 통째로 훔쳐 부팅까지 성공시켜야 하며, K대분의 무게만으로도 어설픈 공격은 사실상 막힌다.

잎에서 뿌리로 거슬러 올라가는 키 트리

랙 시크릿은 그 자체로 키가 아니다. 그래서 키 유도 함수(KDF)를 거쳐 용도별 키를 만들어 낸다. 흥미로운 점은 설계 순서다. 위에서 아래로 계층을 그리는 대신, 실제로 보호할 데이터가 무엇이고 그 데이터에 어떤 잎(leaf) 키가 필요한지를 먼저 나열한 뒤, 그로부터 거꾸로 트리의 내부 노드를 채워 나간다. 보호 대상 데이터가 정해지지 않으면 어떤 키를 유도하고 어떤 키로 감쌀지 판단할 수 없기 때문이다.

보호 대상 데이터는 결국 모두 U.2 장치 위에 파일이나 데이터베이스 형태로 존재한다. Oxide는 하드웨어 기반 전체 디스크 암호화는 구현 신뢰성, 키 관리 복잡성, 다수 벤더 문제 때문에 쓰지 않기로 했고, 대신 U.2당 하나의 zpool을 두고 루트 /crypt 데이터셋에 ZFS 암호화를 적용한다. 자체 암호화를 제공하는 Crucible 같은 데이터셋은 예외로 두어 중복을 피한다. 여기서 핵심 결정은 '디스크마다 개별 키'다. 한 디스크가 털려 키가 노출되더라도 나머지 디스크는 안전하게 남기기 위함이다.

유도냐 래핑이냐, 그리고 로테이션의 딜레마

다음 계층으로 넘어가는 방법은 두 가지다. 키 유도(derivation)는 유도된 키를 디스크에 저장할 필요가 없어 언제든 재생성할 수 있지만, 상위 키가 바뀌면 하위 키가 전부 함께 바뀐다는 단점이 있다. 반대로 키 래핑(wrapping)은 상위 키를 로테이션해도 하위 키를 그대로 둘 수 있어, 대용량 저장 데이터를 다시 암호화하지 않아도 된다는 큰 장점이 있다. 대신 감싼(암호화된) 키를 어딘가에 저장해야 하고, 같은 키가 여러 곳에 쓰이면 복제까지 필요하다. 그래서 Oxide는 가능한 한 유도를 쓰되, U.2별 ZFS 암호화 키에는 래핑을 적용한다.

문제는 신뢰 정족수의 구성이 바뀔 때다. 노드가 추가·제거되면 새 조각을 만드는데, 기존 랙 시크릿을 유지한 채 조각만 갈면 과거에 랙 시크릿을 확보해 저장해 둔 악의적 노드가 이후 데이터까지 계속 복구할 수 있다. 그래서 재구성(reconfiguration)이나 조각 로테이션이 일어날 때마다 항상 새 랙 시크릿을 생성한다. 이렇게 하면 설령 기존 데이터가 전부 노출되더라도, 문제의 슬레드를 제거한 뒤 생산되는 새 데이터는 지킬 수 있다.

분산 커밋이 만드는 제약

여기서 설계가 까다로워진다. 구 그룹과 신 그룹에 모두 속한 슬레드는 옛 랙 시크릿과 새 랙 시크릿을 동시에 알아야 U.2별 ZFS 래퍼 키를 갈아 끼울 수 있다. 그런데 모든 슬레드가 새 구성의 커밋을 같은 시점에 알게 되는 것은 아니며, 커밋이 여러 번의 '헛발질(false start)' 끝에야 확정될 수도 있다. 새 랙 시크릿이 끝내 커밋되지 않으면 그로부터 유도한 래퍼 키도 무의미해지므로, 조각을 학습하자마자 곧바로 키를 바꿀 수는 없다. 2단계 커밋 프로토콜을 전제로, 새 조각은 커밋 시점이 아니라 준비(prepare) 메시지 단계에서 배포해야 한다는 결론이 나온다.

이 문서가 실무자에게 주는 함의는 분명하다. 저장 데이터 암호화의 어려움은 암호 알고리즘 자체보다, 키를 '누가 언제 알게 되고 언제 바꿀 수 있는가'라는 분산 시스템 문제에 있다는 점이다. 동시에 이 RFD는 스스로 미완성임을 여러 곳에서 인정한다. Crucible 암호화 키는 아직 CockroachDB에 저장되어 있고, MVP 이후 별도의 키 관리 시스템을 두겠다는 것은 계획일 뿐이다. 제어 평면 서비스 간 상호 TLS를 위한 내부 인증기관도 루트·잎 인증서가 필요하다는 방향만 정해졌을 뿐, 중간 인증서가 필요한지조차 아직 결정되지 않았다. 결국 이 설계는 '데이터 저장 시 보호'라는 당면 목표를 통과할 만큼의 답을 내고 다음 보안 과제로 넘어가기 위한 현재 시점의 스냅숏에 가깝다.

SOURCE · HACKER NEWS
원문 전체 보기 → https://rfd.shared.oxide.computer/rfd/0301
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기
처리 중...