어두운 데이터센터에서 금고 문처럼 서 있는 무광 검정 서버 드라이브, 화면 밖에서 날아드는 한 줄기 레이저 광선이 표면의 에메랄드빛 열쇠 구멍 모양 봉인을 비추는 모습
가이드

VPS 디스크를 LUKS로 암호화하기

디스크 암호화 자체는 쉬운 부분입니다. 정작 어려운 부분은 물리적으로 손댈 수 없는 서버에서 이를 해내는 것 — 콘솔 앞에 앉아 있지 않아도 새벽 4시에 서버가 문제없이 재부팅되게 만드는 것 — 인데, 대부분의 가이드는 이 부분을 건너뜁니다. 그리고 임대한 하드웨어에서 암호화가 실제로 무엇을 지켜주는지를 명확히 밝히는 부분은 거의 모든 가이드가 빠뜨립니다. 이 가이드는 이 세 가지를 모두 다룹니다: 복구 모드에서 설치하는 LUKS2 루트 볼륨, SSH를 통한 원격 잠금 해제, 그리고 이 방식이 막아주는 위협과 막지 못하는 위협을 있는 그대로 밝히는 설명까지입니다.

“제 데이터는 암호화되어 있나요?”는 저희가 가장 많이 받는 질문이며, 정직하게 답하면 “직접 암호화하지 않는 한 아닙니다.”입니다. 저희는 여러분의 디스크를 대신 암호화해 드리지 않으며, 이는 의도적인 방침입니다 — 저희가 보유한 키는 곧 저희가 제출을 강요당할 수 있는 키이기 때문입니다. 저희 문서에도 이 내용이 한 줄로 명시되어 있으며, 이 가이드는 그 긴 버전으로, 실제 명령어까지 다룹니다.

이어지는 내용은 저희가 실제로 사용하는 절차입니다: 암호화하지 않은 작은 /boot 하나, 그 외 나머지는 모두 LUKS2 컨테이너 안에 두고, initramfs 안에 작은 SSH 서버를 심어 두어 부팅 시점에 세계 어디에서든 패스프레이즈를 입력할 수 있게 하는 방식입니다. 하드웨어가 동일하기 때문에 저희의 네 개 리전인 Paris, Reykjavík, Zürich, Bucharest 어디에서나 동일하게 작동합니다. 복구 모드를 제공하는 다른 호스팅 업체에서도 마찬가지로 작동합니다. 마지막 섹션에서는 한계를 분명히 밝히는데, 암호화가 무엇을 해결해 주는지만 이야기하는 가이드는 결국 무언가를 팔려는 것이기 때문입니다.

VPS에서 디스크 암호화가 실제로 보호하는 것

암호화는 만능 프라이버시 설정이 아닙니다. 암호화가 답하는 질문은 정확히 하나뿐입니다: 키 없이 이 블록들을 읽을 수 있는가? 그 외의 모든 것 — 누가 여러분이 이 서버를 임대했다는 사실을 아는지, 트래픽이 여러분에게 귀속될 수 있는지, 법원이 무언가를 강제할 수 있는지 — 은 전혀 다른 영역의 문제입니다.

VPS에서 LUKS는 다음과 같은 위협을 실질적으로 방어합니다:

  • 폐기되거나 고장 난 하드웨어. NVMe 드라이브는 교체됩니다. 고장 난 장치에서는 보안 삭제(secure-erase)가 항상 가능한 것은 아닙니다 — 때로는 컨트롤러가 더 이상 명령을 받아들이지 못할 정도로 완전히 죽어버린 채로 랙에서 반출되기도 합니다.
  • 오프라인 이미지. 서버 전원이 꺼진 상태에서 복사된 볼륨 — 압수, 마이그레이션, 실수 등으로 인한 것이든 — 은 암호문이며 계속 암호문으로 남습니다.
  • 외부로 이동하는 백업과 스냅샷. 여러분의 통제 범위 아래에 있는 블록 계층에서 가져온 것이라면 서버를 떠날 때 이미 암호화된 상태이며, 그보다 위 계층에서 가져온 것이라면 클라이언트 측에서 별도로 암호화해야 합니다.
  • 잔여 블록. 서버를 삭제하면 해당 익스텐트는 결국 재사용됩니다. 암호화는 그 잔여물을 데이터가 아닌 잡음으로 만들어 줍니다.

다만 실행 중인 머신에 대해서는 방어해 주지 않습니다. 서버가 켜져 있는 동안 마스터 키는 커널 메모리에 존재하며, 그 메모리를 덤프할 수 있는 사람은 패스프레이즈와 무관하게 디스크를 읽을 수 있습니다. 임대 인프라에서 그 대상은 하이퍼바이저 운영자입니다. 저희는 이를 개인정보 처리방침에도 명시하고 있으며, 여기서도 분명히 말씀드립니다: 어떤 제공업체의 디스크 암호화 기능도 이 사실을 바꾸지 못하며, 이는 저희도 예외가 아닙니다. 그렇지 않다고 주장하는 제공업체가 있다면, 그것은 암호학이 아니라 마케팅을 설명하고 있는 것입니다.

세 가지 모델, 그리고 실제로 필요한 것은 무엇인가

터미널을 열기 전에 먼저 모델을 정하십시오. 세 모델은 필요한 노력의 정도가 크게 다르며, 대부분의 사람에게는 첫 번째 모델로 충분합니다.

1. 암호화된 데이터 볼륨. 시스템은 평소처럼 암호화 없이 부팅되고, 메일디렉터리나 데이터베이스, 아카이브 같은 디렉터리 트리 하나만 LUKS 컨테이너 안에 있으며, 매 부팅 후 직접 열어 줍니다. 작업 시간은 10분 정도이고, 복구 모드도 필요 없으며, 스스로 접근이 막힐 위험도 없습니다. 신경 쓰는 대상이 머신 전체가 아니라 데이터셋 하나뿐이라면 여기서 멈추십시오 — 취약점은 거의 없이 이점의 대부분을 얻을 수 있습니다. 저희가 익명 메일 서버 페이지에서 권장하는 방식이 바로 이것입니다.

2. 원격 잠금 해제가 가능한 암호화된 루트 볼륨. /boot를 제외한 모든 것이 암호화되며, 매 부팅마다 initramfs에서 멈춘 채로 SSH로 접속해 패스프레이즈를 입력할 때까지 기다립니다. 이 가이드의 나머지 부분이 다루는 모델이 바로 이것입니다. 처음 설정에 한 시간이 들고 재부팅마다 SSH 명령 하나가 필요하지만, 로그·패키지 캐시·셸 히스토리·스왑까지 함께 보호되는 유일한 모델입니다 — 누구도 의도하지 않았는데 데이터가 새어 나가는 지점들입니다.

3. 직접 관리하는 키 서버를 통해 스스로 잠금을 해제하는 암호화된 루트. 모델 2와 동일하지만, Clevis가 다른 관할권에 있는 머신의 Tang 서버로부터 잠금 해제 정보를 가져오므로 재부팅이 무인으로 처리됩니다. 이 트레이드오프는 명확하며 제대로 이해해 둘 가치가 있습니다: 이제 서버는 키 서버가 승인하는 한 스스로를 복호화할 수 있게 되는데, 이는 비밀을 없앤 것이 아니라 옮긴 것에 불과하지만, 동시에 원격 킬 스위치를 얻은 것이기도 합니다. 자세한 내용은 뒤에서 다룹니다.

저희가 여러분의 디스크를 대신 암호화해 드리지 않는 이유

많은 호스팅 업체가 “저장 데이터 암호화(encryption at rest)”를 단순한 체크박스 항목처럼 광고합니다. 이 문구가 실제로 무엇을 의미하는지는 정확히 짚고 넘어갈 가치가 있습니다. 그 안에는 전혀 다른 두 가지가 숨어 있기 때문입니다.

제공업체가 쥐고 있는 키로 하는 암호화는 도난당한 드라이브에 대해서만 보호해 줄 뿐, 그 이상은 아닙니다. 제공업체가 여러분에게 아무것도 묻지 않고 서버를 부팅할 수 있다면, 제공업체는 아무것도 묻지 않고 서버를 복호화할 수도 있으며 — 그 제공업체에게 강제력을 행사할 수 있는 누구든 마찬가지입니다. 이는 절도에 대해서는 실질적인 통제 수단이지만, 법적 절차에 대해서는 순전히 장식적인 수단일 뿐입니다.

여러분이 쥐고 있는 키로 하는 암호화가 의미 있는 방식이며, 이 방식은 구조적으로 무인 재부팅을 불가능하게 만듭니다. 이는 설계로 없애야 할 결함이 아니라, 바로 그 특성이 실제로 일을 해내는 부분입니다.

저희는 두 번째 방식만을, 그것도 설정되지 않은 상태로 제공하며 선택은 여러분의 몫으로 남겨 둡니다. 저희가 실제로 보관하는 정보는 그보다 훨씬 제한적이며 문서화되어 있습니다: 서버 root 비밀번호는 행 단위로 AES-256-CBC 암호화되어 저장되고, 플로우 로그나 패킷 캡처는 보관하지 않으며, 서명된 워런트 캐너리가 일정에 따라 게시됩니다. 이 중 어느 것도 여러분 자신의 키를 대신할 수는 없습니다 — 다만 그 사이에 저희가 책임질 수 있는 부분일 뿐입니다.

암호 방식, 키 크기, 그리고 Argon2 메모리 함정

기본값은 훌륭합니다. 다만 그중 두 가지는 덮어쓸 만한 가치가 있습니다.

암호 방식. 512비트 키를 사용하는 aes-xts-plain64가 기본값이자 올바른 선택입니다 — 512비트는 256비트 키 두 개를 의미하므로 이는 XTS 모드의 AES-256이며, 저희가 운용하는 모든 CPU에는 AES-NI가 있습니다. AES 가속 기능이 없는 머신이라면 xchacha20,aes-adiantum-plain64를 선호하겠지만, 이는 저희 하드웨어도 아니고 아마 여러분의 것도 아닐 것입니다.

키 유도. LUKS2는 기본적으로 Argon2id를 사용하며, 이는 의도적으로 메모리 소모가 큰 방식입니다. cryptsetup은 포맷 시점에 머신을 벤치마크하여 확인 가능한 RAM을 기준으로 메모리 비용을 결정합니다 — 그리고 바로 여기에 “암호화한 서버가 부팅되지 않는다”는 보고 대부분의 원인이 되는 함정이 있습니다: initramfs가 사용할 수 있는 메모리는 실행 중인 시스템보다 적습니다. 만약 대상 플랜보다 RAM이 더 많은 복구 환경에서 볼륨을 포맷했다면, 부팅 시 잠금 해제가 실패하거나 강제 종료될 수 있습니다. 이 값은 명시적으로 고정해 두십시오. Argon2 메모리 1 GiB는 공격자에게는 상당한 비용이면서, 4 GB짜리 S1 플랜에서도 충분히 감당할 수 있는 수준입니다:

cryptsetup luksFormat --type luks2 \
  --cipher aes-xts-plain64 --key-size 512 --hash sha256 \
  --pbkdf argon2id --pbkdf-memory 1048576 --pbkdf-parallel 4 \
  /dev/vda2

--pbkdf-memory의 단위는 KiB이므로 1048576은 1 GiB입니다. 이후 cryptsetup luksDump /dev/vda2로 헤더에 실제로 어떤 값이 적용되었는지 확인하십시오 — keyslot 항목에 사용될 메모리와 반복 횟수가 출력되며, 이를 한 번 확인해 두는 편이 부팅 실패를 겪는 것보다 훨씬 저렴합니다.

패스프레이즈. Argon2는 약한 패스프레이즈에 대해 시간을 벌어줄 뿐, 그것을 구제해 주지는 못합니다. 최소 여섯 단어로 이루어진 다이스웨어(diceware) 문구를 사용하십시오. 이는 시스템에서 유일한 비밀이며, 어떤 키 유도 함수도 나쁜 패스프레이즈를 대신 보완해 주지 못합니다.

원격 잠금 해제는 실제로 어떻게 동작하는가

암호화된 루트를 사용하는 Linux 부팅에는 닭과 달걀의 문제가 있습니다: 커널과 initramfs는 패스프레이즈를 요청하기도 전에 먼저 로드되어야 하는데, 정작 이들은 여러분이 잠금을 해제하려는 바로 그 디스크 위에 있습니다. 표준적인 해법은 커널, initramfs, 부트로더를 담은 작고 암호화되지 않은 /boot 파티션을 두는 것입니다. 그 외 나머지는 모두 LUKS 안으로 들어갑니다.

이후 initramfs는 멈춰서 패스프레이즈를 요청합니다. 노트북이라면 직접 입력하면 됩니다. 3천 킬로미터 떨어진 서버라면 다음 두 가지 중 하나가 필요합니다:

  • 콘솔. 대시보드의 모든 서버에는 noVNC 콘솔이 있으며 실제로 동작합니다 — 다만 키 입력이 저희 인프라를 거쳐 가는데, 이는 정확히 여러분의 키가 배제하려는 바로 그 대상입니다. 일회성 복구용으로는 괜찮지만, 일상적인 용도로는 적절하지 않습니다.
  • initramfs 안의 SSH 서버. dropbear-initramfs는 약 200 KB 크기로, 네트워크를 올리고, 원하는 포트에서 대기하며, 여러분의 공개 키 중 하나를 인증하고, 곧바로 잠금 해제 프롬프트로 연결해 줍니다. 패스프레이즈는 노트북에서 initramfs까지 종단 간 암호화되어 전달됩니다. 이것이 올바른 답입니다.

여기서 두 가지를 놓치기 쉽습니다. initramfs의 Dropbear는 자체 호스트 키를 가지고 있어 평소 사용하는 SSH 데몬과는 지문(fingerprint)이 다른데, 이는 예상된 현상이지 중간자 공격이 아니며, yes를 습관적으로 입력하기보다는 별도의 known_hosts 파일을 두는 것이 바람직합니다. 그리고 인터페이스 이름도 정확해야 합니다: Debian 13에서 virtio NIC는 보통 eth0가 아니라 ens3enp1s0로 나타납니다. 설정을 작성하기 전에 ip -br link로 확인하십시오. 잘못 지정하면 네트워크가 없는 initramfs와 함께 콘솔로 되돌아가야 하는 상황을 맞게 됩니다.

Clevis와 Tang을 이용한 무인 재부팅

커널 업데이트, 호스트 재부팅, 정전 등으로 머신이 스스로 다시 켜져야 하는 경우라면, 패스프레이즈를 직접 입력하는 방식은 현실적이지 않습니다. Clevis는 LUKS 키 슬롯을 외부 정책에 결합해 주는 도구이며, Tang은 그중 가장 단순하면서도 실용적인 정책을 구현한 작은 키 교환 서버입니다.

# on a small server you control, elsewhere
apt install -y tang
systemctl enable --now tangd.socket

# on the encrypted VPS
apt install -y clevis clevis-luks clevis-initramfs
clevis luks bind -d /dev/vda2 tang '{"url":"http://tang.internal:7500"}'
update-initramfs -u -k all

부팅 시 initramfs는 Tang과 McCallum-Relyea 교환을 수행하여 키를 복구하며, 이 과정에서 Tang 서버는 그 키는 물론 패스프레이즈도 전혀 알지 못합니다. 이 방식의 성질은 정확히 짚어 둘 가치가 있습니다:

  • VPS는 Tang에 도달할 수 있는 동안에만 스스로를 복호화합니다. Tang을 종료하거나 키를 교체하면 다음 재부팅은 그 자리에서 멈춥니다. 이는 진짜 의미의 원격 킬 스위치이며, 흔치 않으면서도 유용한 특성입니다.
  • Tang은 공개 인터넷에 두어서는 안 됩니다. WireGuard를 통하거나 Tor 어니언 서비스로 접근하도록 구성하십시오. 터널 구성 방법은 WireGuard 가이드에서 다룹니다.
  • Tang은 데이터가 있는 곳과는 다른 관할권에 두십시오. 저희 관할권 안내 페이지는 정확히 이런 분리를 위해 존재합니다.
  • 다른 키 슬롯에는 패스프레이즈도 남겨 두십시오. Clevis는 편의를 위한 계층일 뿐, 유일한 접근 수단이 되어서는 안 됩니다.

지금 구축한 것이 무엇인지 정확히 이해하십시오: 무인 머신은 대리인을 통해 자신의 키를 쥐고 있는 셈이므로, 실행 중인 VPS를 탈취하거나 여러분의 Tang 서버에 접근할 수 있는 공격자는 데이터를 손에 넣게 됩니다. 이는 머릿속에만 있는 패스프레이즈에 비하면 명백한 약화입니다. 이 방식은 기본값으로 택할 것이 아니라, 가용성이 마지막 한 조각의 기밀성보다 중요할 때만 선택하십시오.

스왑, 임시 파일, 그리고 평문이 새어 나가는 지점들

암호화된 루트는 대부분의 영역을 커버하지만, 몇몇 경로는 그 밖에 기록되거나 암호화를 우회해 살아남습니다.

  • 스왑. RAM에 있는 것은 무엇이든 디스크로 페이징될 수 있습니다 — 키, 메시지 본문, 복호화된 버퍼 등이 그렇습니다. 스왑이 스왑파일 형태로 암호화된 볼륨 안에 있다면 함께 보호됩니다. 별도의 스왑 파티션은 그렇지 않으며, 매 부팅마다 바뀌는 무작위 키와 함께 /etc/crypttab에 등록해야만 보호됩니다: cryptswap /dev/vda3 /dev/urandom swap,cipher=aes-xts-plain64,size=256. VPS에서는 스왑파일 쪽이 더 단순하므로 굳이 파티션을 선호할 이유가 없습니다.
  • /tmp. tmpfs로 마운트하면(tmpfs /tmp tmpfs defaults,nosuid,nodev,size=512M 0 0) 디스크에는 전혀 닿지 않습니다. 속도도 더 빠릅니다.
  • 하이버네이션. 마스터 키를 포함한 RAM 전체를 스왑 장치에 기록합니다. 활성화하지 마십시오. 저희 이미지에서는 기본적으로 꺼져 있습니다.
  • 암호화되지 않은 /boot. 커널, initramfs 이미지, GRUB 설정은 디스크에 오프라인으로 접근할 수 있는 사람이라면 누구나 읽을 수 있고, 더 중요하게는 쓸 수도 있습니다. LUKS는 기밀성을 제공할 뿐, 부팅 무결성을 제공하지는 않습니다. 위협 모델에 부트로더 변조가 포함된다면 암호화만으로는 이를 잡아낼 수 없습니다 — 커널을 업데이트할 때마다 /boot의 해시를 기록해 두고 외부에서 검증하거나, 이 공백을 의식적으로 감수하십시오.
  • 기존 스냅샷과 오래된 볼륨. 오늘 암호화한다고 해서 어제 찍힌 이미지에는 아무 소용이 없습니다. 서버가 한 번이라도 암호화 없이 소중한 데이터를 다룬 적이 있다면, 그 데이터는 노출된 것으로 간주하고 거기서 파생된 모든 것을 교체하십시오.

성능: 비용과 튜닝 포인트

오버헤드는 결정을 좌우할 만큼 크지는 않지만, 0도 아닙니다. 추측하지 말고 직접 측정하십시오:

cryptsetup benchmark

저희 EPYC 노드에서 512비트 키를 사용하는 aes-xts는 코어당 초당 낮은 자릿수의 기가바이트 수준을 벤치마크로 기록하며, 이는 NVMe 볼륨 하나가 요구하는 수준을 여유 있게 웃돕니다. 실제로 체감되는 비용은 처리량이 아니라 소규모 무작위 쓰기에서의 지연 시간과 CPU입니다.

NVMe에서는 두 가지 LUKS2 플래그가 중요한데, 커널의 dm-crypt 작업 큐가 지연을 없애기는커녕 오히려 더한다는 문제 때문입니다. 이를 설정하고 헤더에 영구히 고정해 두십시오:

cryptsetup refresh cryptroot \
  --perf-no_read_workqueue --perf-no_write_workqueue --persistent

세 번째 플래그인 --allow-discards는 TRIM을 하위 장치까지 그대로 전달합니다. 이는 볼륨 수명 동안 쓰기 증폭을 낮춰 주지만, 그 대가로 어떤 블록이 사용되지 않았는지가 드러나며 — 이는 원시 장치를 들여다보는 사람에게 여러분 데이터의 대략적인 크기와 형태를 노출시킵니다. 범용 서버라면 활성화하고, 볼륨이 3% 차 있다는 사실 자체가 민감한 정보라면 꺼 두십시오. 보편적으로 옳은 답은 없으며, 오직 의도를 가지고 내리는 결정이 있을 뿐입니다.

헤더, 키 슬롯, 그리고 문제가 생기는 날

LUKS 헤더는 파티션 앞부분에 위치한 약 16 MB 크기의 영역으로, 마스터 키의 암호화된 사본을 담고 있습니다. 이를 손상시키면 — 잘못 입력한 dd 명령, 장치의 시작 부분을 친절하게도 다시 써버리는 파티션 도구 등으로 — 그 뒤에 있는 모든 바이트가 사라집니다. 복구 서비스는 존재하지 않습니다. 저희도 사본을 가지고 있지 않습니다.

# back it up, off the server, before you put data on the volume
cryptsetup luksHeaderBackup /dev/vda2 \
  --header-backup-file luks-header-$(date +%F).img

# add a second passphrase while you still have the first
cryptsetup luksAddKey /dev/vda2

# see what is in the header
cryptsetup luksDump /dev/vda2

이 백업에 대해 두 가지를 알아 두어야 합니다. 첫째, 이 백업은 디스크 자체만큼이나 민감합니다: 키 슬롯을 담고 있으므로, 패스프레이즈를 변경한 뒤에 예전 헤더를 복원하면 예전 패스프레이즈가 아무렇지 않게 다시 통하게 됩니다. 패스프레이즈를 보관하는 것과 동일한 방식으로 보관하고, 교체 시에는 오래된 사본을 폐기하십시오. 둘째, LUKS2는 32개의 키 슬롯을 제공합니다 — 최소 두 개는 사용하되, 예비용은 평소 사용하는 패스프레이즈와는 다른 곳에 보관하는 길고 무작위한 패스프레이즈로 하십시오. 이렇게 하면 흔하고 사소해 보이지만 실제로 자주 일어나는 실패, 즉 패스프레이즈를 교체하면서 두 번 다 똑같이 잘못 입력해 놓고는 다음 로그인이 아니라 다음 재부팅 때가 되어서야 그 사실을 알아차리는 상황을 막을 수 있습니다.

돌아갈 방법도 마련해 두십시오. 복구 모드는 여러분의 SSH 키가 주입된 상태로, 암호화된 볼륨은 건드리지 않은 채 저희 ISO로 서버를 부팅해 주므로, cryptsetup open /dev/vda2 rescue && mount /dev/mapper/rescue /mnt를 실행해 데이터 손실 없이 손상된 crypttab이나 잘못된 initramfs를 복구할 수 있습니다. 아무 문제가 없을 때 미리, 의도적으로 한 번 시험해 보십시오.

암호화가 하지 못하는 것, 있는 그대로

이런 가이드가 할 수 있는 가장 유용한 일은 스스로의 한계를 분명히 긋는 것입니다.

  • 실행 중인 서버는 보호하지 못합니다. 마스터 키는 잠금 해제 시점부터 종료할 때까지 커널 메모리에 존재합니다. 하이퍼바이저 수준의 메모리 접근이면 이를 무력화할 수 있습니다. 메모리 암호화 — AMD SEV-SNP 및 이에 준하는 기술 — 만이 이를 실질적으로 바꿀 수 있는 유일한 기술이며, 저희는 현재 이를 제공하지 않습니다. SEV 없이도 실행 중인 VM이 이런 접근으로부터 안전하다고 주장하는 제공업체가 있다면, 그것은 착각이거나 거짓말입니다.
  • 여러분을 익명으로 만들어 주지 않습니다. Zürich에 있는 암호화된 디스크에도 IP, 결제 흔적, 그리고 어딘가에서 시작된 SSH 세션은 여전히 남아 있습니다. 이는 전혀 다른 문제이며, 그 문제가 어떻게 어긋나는지는 익명성을 무너뜨리는 실수들에 정리해 두었습니다.
  • 법원이 명령할 수 있는 범위를 바꾸지 못합니다. 무엇을 강제할 수 있는지는 관할권이 결정하고, 데이터를 읽을 수 있는지는 암호화가 결정합니다. 일부 관할권에서는 개인이 직접 패스프레이즈를 공개하라는 명령을 받을 수 있습니다. 저희가 어떤 요청에는 응하고 어떤 요청에는 응하지 않는지는 법적 절차 가이드에서 다룹니다.
  • 잃어버린 패스프레이즈를 되살려 주지 못합니다. 이는 설계상 의도된 것이며, 반복해서 말할 가치가 있습니다. 저희에게 도와 달라는 지원 티켓이 한 달에 한 번꼴로 들어오는데, 답은 언제나 같기 때문입니다.
  • 부팅 체인을 인증하지는 못합니다. 기밀성은 무결성이 아닙니다. /boot는 오프라인 상태에서 읽고 수정할 수 있습니다.

암호화가 실제로 해 주는 일은 노출의 한 범주 전체를 없애 주는 것입니다 — 디스크가 꺼져 있을 때 벌어지는 모든 일, 즉 디스크에 벌어지는 일 대부분이 여기에 해당합니다. 그만큼 한 시간을 들일 가치는 충분합니다. 여기에 노-KYC 가입, Monero 결제, 그리고 의도를 가지고 고른 관할권까지 결합하면 각 계층이 서로 다른 실패 지점을 커버하게 됩니다. 다만 그중 어느 것도 전부를 커버하지는 못합니다.

  1. 서버를 배포하고 복구 모드로 부팅하기

    플랜과 리전은 무엇을 고르든 상관없이, 기본 Debian 13 이미지로 배포하십시오 — 어차피 설치된 시스템은 곧 교체될 것이므로 이미지 선택은 거의 중요하지 않습니다. 그런 다음 Server → Recovery → Boot into rescue로 이동합니다. 복구 환경은 이미 계정에 등록된 SSH 키를 주입하고 디스크는 건드리지 않으므로, /dev/vda가 마운트 해제된 채로 비어 있는 root 셸을 얻게 됩니다. 복구 환경의 호스트 키 지문은 설치된 시스템의 것과 다른데, 이는 정상입니다.

  2. 디스크 파티셔닝: 작은 평문 /boot와 하나의 큰 LUKS 컨테이너

    파티션은 두 개입니다. /boot용으로 1 기가바이트 — 커널 여러 개를 담기에 충분한 크기 — 를 할당하고, 나머지는 모두 암호화된 볼륨에 할당합니다.

    sgdisk --zap-all /dev/vda
    sgdisk -n1:0:+1G   -t1:8300 -c1:boot   /dev/vda
    sgdisk -n2:0:0     -t2:8309 -c2:crypt  /dev/vda
    partprobe /dev/vda && lsblk /dev/vda

    타입 8309는 두 번째 파티션을 Linux LUKS 볼륨으로 표시합니다. 서버가 UEFI 모드로 부팅된다면, 파티션 1을 ESP로 만들고(-t1:ef00, FAT32로 포맷하여 /boot/efi에 마운트) 별도로 1 GB 크기의 /boot를 추가하십시오. 위의 BIOS 레이아웃은 저희 이미지가 기본으로 사용하는 방식입니다.

  3. LUKS2 볼륨을 생성하고 열기

    Argon2 메모리 비용을 명시적으로 고정해 두어, 나중에 initramfs에서도 감당할 수 있게 합니다.

    cryptsetup luksFormat --type luks2 \
      --cipher aes-xts-plain64 --key-size 512 --hash sha256 \
      --pbkdf argon2id --pbkdf-memory 1048576 --pbkdf-parallel 4 \
      /dev/vda2
    
    cryptsetup open /dev/vda2 cryptroot
    mkfs.ext4 -L root /dev/mapper/cryptroot
    mkfs.ext2 -L boot /dev/vda1

    최소 여섯 단어로 이루어진 다이스웨어 패스프레이즈를 사용하고, 계속 진행하기 전에 실물로 어딘가에 적어 두십시오. 누구도 이를 대신 복구해 줄 수 없습니다 — 그것이 바로 여러분이 이 방식에 대해 치르는 대가입니다.

  4. 암호화된 볼륨에 Debian 설치하기

    새 루트를 마운트하고, 그 안에 debootstrap으로 기본 시스템을 설치한 다음, chroot가 정상적으로 동작하도록 커널 파일시스템을 바인드합니다.

    mount /dev/mapper/cryptroot /mnt
    mkdir -p /mnt/boot && mount /dev/vda1 /mnt/boot
    
    debootstrap --arch=amd64 trixie /mnt http://deb.debian.org/debian
    
    for d in dev dev/pts proc sys run; do mount --bind /$d /mnt/$d; done
    chroot /mnt /bin/bash

    chroot 안에서, 암호화된 루트를 부팅 가능하고 접근 가능하게 만들어 주는 구성 요소들을 설치합니다:

    apt update && apt install -y linux-image-amd64 grub-pc \
      cryptsetup cryptsetup-initramfs dropbear-initramfs \
      openssh-server ifupdown ca-certificates locales
  5. crypttab, fstab, initramfs 네트워크 설정 작성하기

    crypttab은 initramfs에게 어떤 장치를 잠금 해제할지 알려주고, initramfs.conf는 먼저 어떻게 네트워크에 연결할지를 알려줍니다. 장치 이름은 바뀔 수 있으므로 /dev/vda2가 아니라 반드시 LUKS UUID를 사용하십시오.

    echo "cryptroot UUID=$(blkid -s UUID -o value /dev/vda2) none luks,discard" \
      > /etc/crypttab
    
    cat > /etc/fstab <<'EOF'
    /dev/mapper/cryptroot  /      ext4  defaults,noatime  0 1
    LABEL=boot             /boot  ext2  defaults          0 2
    tmpfs                  /tmp   tmpfs defaults,nosuid,nodev,size=512M 0 0
    EOF
    
    # DHCP on the virtio NIC. Confirm the name with `ip -br link` first.
    echo 'IP=:::::ens3:dhcp' >> /etc/initramfs-tools/initramfs.conf
    echo 'DEVICE=ens3'       >> /etc/initramfs-tools/initramfs.conf

    어떤 블록이 사용되지 않았는지 드러내고 싶지 않다면 crypttab 줄에서 ,discard를 빼십시오. DHCP 대신 고정 주소를 사용하려면 필드 순서는 IP=<ip>::<gateway>:<netmask>::<iface>:off입니다.

  6. initramfs에 잠금 해제용 키 넣고 Dropbear 잠그기

    여기에 넣은 키만이 부팅 시 머신의 잠금을 해제할 수 있습니다. 평소 사용하는 SSH 키와는 분리해 두어, 하나를 잃어도 둘 다 잃지 않도록 하십시오.

    install -d -m 0755 /etc/dropbear/initramfs
    cat > /etc/dropbear/initramfs/authorized_keys <<'EOF'
    ssh-ed25519 AAAAC3Nza... unlock@laptop
    EOF
    chmod 0600 /etc/dropbear/initramfs/authorized_keys
    
    cat > /etc/dropbear/initramfs/dropbear.conf <<'EOF'
    DROPBEAR_OPTIONS="-p 2222 -s -j -k -I 180 -c cryptroot-unlock"
    EOF
    
    update-initramfs -u -k all
    dropbearkey -y -f /etc/dropbear/initramfs/dropbear_ed25519_host_key | grep -i fingerprint

    -p 2222는 잠금 해제 서비스를 22번 포트가 아닌 곳에 두어 실행 중인 시스템의 sshd와 절대 충돌하지 않게 합니다. -s는 비밀번호 로그인을 금지하고, -j-k는 포트 포워딩을 비활성화하며, -I 180은 유휴 세션을 끊고, -c cryptroot-unlock은 로그인에 성공하면 곧바로 패스프레이즈 프롬프트로 이동하게 합니다. 이 시점에 지문을 기록해 두십시오 — 그것이 여러분이 자기 자신의 initramfs와 통신하고 있다는 것을 확인하는 방법입니다. Debian 11 이하에서는 이 파일들이 대신 /etc/dropbear-initramfs/에 있습니다.

  7. 부트로더 설치, root 비밀번호 설정, 재부팅

    GRUB는 파티션이 아니라 디스크 자체에 설치됩니다. /boot가 암호화되어 있지 않으므로 GRUB_ENABLE_CRYPTODISK는 필요하지 않습니다.

    grub-install /dev/vda
    update-grub
    passwd root
    echo 'cryptovps' > /etc/hostname
    exit                    # leave the chroot
    
    umount -R /mnt
    cryptsetup close cryptroot
    reboot

    그런 다음 대시보드에서 서버의 복구 모드를 꺼서 디스크로 부팅되도록 하십시오. 이 첫 부팅 동안에는 noVNC 콘솔을 열어 두십시오 — initramfs가 네트워크 없이 올라오는 경우 그 화면에서 바로 확인할 수 있으며, 추측할 필요 없이 인터페이스 이름을 바로잡을 수 있습니다.

  8. 원격으로 잠금 해제하고 볼륨이 실제로 암호화되었는지 확인하기

    30초 정도 기다린 다음, 2222번 포트로 initramfs에 접속하십시오. 평소 사용하는 known_hosts와 절대 섞이지 않도록 호스트 키는 별도의 파일에 고정해 두십시오.

    ssh -p 2222 -o UserKnownHostsFile=~/.ssh/known_hosts.initramfs \
        -i ~/.ssh/id_ed25519_unlock root@<server-ip>
    # the passphrase prompt appears immediately; type it, the session closes,
    # and the machine finishes booting into the decrypted root.
    
    # once you are in the running system:
    lsblk -o NAME,FSTYPE,MOUNTPOINT
    cryptsetup status cryptroot
    cryptsetup luksDump /dev/vda2 | head -20

    cryptsetup statustype: LUKS2, cipher: aes-xts-plain64, keysize: 512 bits를 보여줘야 합니다. 이제 누구나 미루기 마련인 두 가지 일을 하십시오: LUKS 헤더를 서버 밖으로 백업하고, 두 번째 키 슬롯을 추가하는 것입니다. 그런 다음 한 번 더 의도적으로 재부팅해서, 예상치 못한 순간에도 잠금 해제 경로가 제대로 동작한다는 것을 직접 확인하십시오.

비교

세 가지 암호화 방식과 그 비용

VPS에서 실제로 쓸 수 있는 세 가지 디스크 암호화 모델을, 이들을 가르는 질문 — 다음 재부팅 때 무슨 일이 벌어지는가 — 을 기준으로 비교합니다.
모델무엇이 암호화되는가다음 재부팅 시설정 노력적합한 대상
암호화된 데이터 볼륨LUKS 컨테이너 안의 디렉터리 트리 하나서버는 정상적으로 부팅되며, 컨테이너는 직접 엽니다약 10분, 복구 모드 불필요민감한 데이터셋 하나 — 메일디렉터리, 데이터베이스, 아카이브
암호화된 루트 + SSH 원격 잠금 해제/boot를 제외한 모든 것 — 로그, 스왑, 캐시, 히스토리SSH로 접속해 패스프레이즈를 입력할 때까지 initramfs에서 부팅이 멈춤약 1시간, 복구 모드에서 설치상태 전체가 민감하며 재부팅 시 직접 대응할 수 있는 머신
암호화된 루트 + Clevis/Tang/boot를 제외한 모든 것Tang 서버에 도달할 수 있는 동안에는 스스로 잠금 해제되며, 도달할 수 없으면 그대로 멈춤약 1시간, 그리고 직접 관리하는 서버 하나 추가가용성이 마지막 한 조각의 기밀성보다 중요한 무인 머신
FAQ

자주 묻는 질문

CryptoVpsHost가 제 서버의 데이터를 읽을 수 있나요?

실행 중인 서버라면 원칙적으로는 그렇습니다 — 이는 그렇지 않다고 말하는 곳을 포함해 가상화 인프라를 제공하는 모든 업체에 해당하는 이야기입니다. 잠금 해제된 LUKS 볼륨의 마스터 키는 커널 메모리에 있으며, 그 메모리는 하이퍼바이저가 소유합니다. LUKS가 없애 주는 것은 그 나머지 전부입니다: 전원이 꺼진 볼륨, 폐기된 드라이브, 복사된 이미지, 백업 등입니다. 저희가 여러분을 대신해 디스크를 암호화하지 않는 이유는 정확히 이것입니다 — 저희가 쥐고 있는 키는 저희가 제출을 강요당할 수 있는 키이기 때문이며, 저희는 체크박스를 파는 대신 이 사실을 있는 그대로 말씀드리는 쪽을 택합니다. 위협 모델에 실행 중인 머신의 운영자가 포함된다면, 그 누구의 디스크 암호화 기능으로도 이 문제는 해결되지 않습니다.

전체 디스크 암호화를 적용하면 VPS가 느려지나요?

AES-NI가 있는 하드웨어에서는 거의 느려지지 않으며, 저희 하드웨어는 전부 여기에 해당합니다. cryptsetup benchmark를 실행해 보면 aes-xts가 코어당 초당 낮은 자릿수의 기가바이트 수준을 기록하는 것을 볼 수 있는데, 이는 NVMe 볼륨 하나가 요구하는 수준을 훨씬 웃돕니다. 실제로 측정되는 비용은 처리량이 아니라, 소규모 무작위 쓰기에서 약간 늘어나는 지연 시간과 CPU입니다. NVMe에서는 --perf-no_read_workqueue--perf-no_write_workqueue--persistent와 함께 설정하면 남은 비용의 대부분이 사라집니다.

패스프레이즈를 잃어버리면 어떻게 되나요?

데이터는 사라집니다. 복구 방법도, 에스크로에 보관된 마스터 키도 없으며, 지원 티켓을 보내도 이 사실은 바뀌지 않습니다 — 저희는 애초에 사본을 가진 적이 없습니다. 그것이 바로 여러분이 이 방식에 대해 치르는 대가이며, 이 가이드가 실제 데이터를 볼륨에 올리기 전에 LUKS 헤더를 서버 밖으로 백업하고 다른 긴 패스프레이즈로 두 번째 키 슬롯을 추가하라고 두 번이나 말하는 이유이기도 합니다. 단 한 곳에만 — 심지어 그곳이 머릿속뿐이라 해도 — 보관된 패스프레이즈는 단일 장애점입니다.

/boot도 암호화되나요?

아니요, 그리고 그것이 정상입니다. 커널과 initramfs는 패스프레이즈를 요청하기도 전에 읽을 수 있어야 하므로, 작은 평문 파티션 위에 놓입니다. GRUB는 GRUB_ENABLE_CRYPTODISK를 사용해 암호화된 /boot를 읽을 수 있지만, 이는 문제를 옮길 뿐입니다 — 그보다 앞선 부트로더 단계는 여전히 평문 상태입니다. 정직하게 말하면, LUKS는 저장 데이터의 기밀성을 제공할 뿐, 부팅 체인의 무결성을 제공하지는 않습니다. 위협 모델에 /boot에 대한 오프라인 변조가 포함된다면, 커널을 업데이트할 때마다 해시를 구해 두고 머신 밖에서 검증하십시오.

제가 아무것도 입력하지 않아도 서버가 재부팅될 수 있나요?

서버에 키를 얻을 방법을 마련해 주는 경우에만 가능하며, 이는 필연적으로 보장 수준을 낮춥니다. 깔끔한 방식은 다른 관할권에서 직접 관리하는 머신의 Tang 서버에 Clevis를 결합하는 것입니다: VPS는 Tang에 도달할 수 있는 동안에는 스스로 잠금을 해제하고, 도달할 수 없으면 그대로 멈추는데 — 이는 동시에 원격 킬 스위치 역할도 합니다. Tang에는 공개 인터넷이 아니라 WireGuard나 Tor 어니언 서비스로 접근하고, Clevis가 유일한 접근 수단이 되지 않도록 두 번째 키 슬롯에는 패스프레이즈도 남겨 두십시오.

어떤 OS 이미지에서든 가능한가요, 아니면 Debian에서만 가능한가요?

복구 모드를 제공하는 Linux 이미지라면 어디서든 동작합니다. 여기 나온 명령어는 Debian 13 기준이며 Ubuntu 24.04에도 그대로 적용됩니다. Rocky, Alma, Fedora에서는 initramfs-tools 대신 dracut이 도구로 쓰이므로, 원격 잠금 해제는 dropbear-initramfs 대신 dracut-crypt-ssh 모듈이나 네트워크가 활성화된 dracut initramfs를 사용합니다 — LUKS 쪽은 동일합니다. 복구 셸에서 직접 구축하고 싶지 않다면, 최대 4 GiB 크기의 커스텀 ISO를 업로드하여 해당 배포판의 설치 프로그램을 사용하십시오. 이 설치 프로그램은 표준 옵션으로 암호화된 LVM을 제공하며, 원격 잠금 해제는 이후에 추가하면 됩니다.

암호화를 사용해야 하나요, 아니면 다른 관할권을 선택해야 하나요?

이 둘은 서로 다른 문제를 해결하므로, 질문 자체가 잘못된 이분법입니다. 암호화는 블록을 읽을 수 있는지를 결정하고, 관할권은 누가 무엇을 얼마나 빠르게 강제할 수 있는지를 결정합니다. Paris에 있는 LUKS 볼륨과 Zürich에 있는 평문 볼륨은 완전히 다른 방식으로 실패합니다. 이 질문을 하는 대부분의 사람은 사실 두 가지 모두를 원하며, 애초에 공개할 것 자체가 없도록 노-KYC 가입까지 함께 원합니다 — 각 계층은 다른 계층이 남기는 빈틈을 메워 줍니다. 저희 관할권 안내 페이지에서 네 개 리전 각각이 실제로 무엇을 제공하는지 확인하실 수 있습니다.

Deploy your offshore server.

지역을 선택하세요. 플랜을 선택하세요. 키를 붙여넣으세요. 결제하세요. 다음 47초는 저희가 책임집니다.