어두운 데이터센터 안, 빛을 받은 무광 검정 서버 블레이드에서 에메랄드빛 데이터 입자 리본이 흘러나와 빛나는 와이어프레임 복제본을 이루고, 그 전체가 빛나는 자물쇠로 봉인되어 있는 모습
백업 가이드

실제로 복원할 수 있는 VPS 백업하기

서버를 운영하는 사람 거의 모두가 스스로 백업이라 부르는 무언가를 갖고 있습니다. 그중 실제로 복원까지 해 본 사람은 훨씬 적으며, 이 두 문장 사이의 거리야말로 데이터가 실제로 사라지는 지점입니다. 이 글은 서버를 진짜로 파괴하는 세 가지 — 여러분 자신의 손, 침해, 그리고 더 이상 통제할 수 없게 된 계정 — 을 견뎌 내는 사본을 만드는 방법을 다루며, 그 과정에서 익명의 머신에 검증된 신원을 조용히 덧붙이는 일은 없도록 합니다.

저희는 이 네트워크를 구동하는 모든 바이트를 세 벌씩 보관하며, 평범한 화요일에 일부러 그 사본에서 복원을 실행해 본 횟수가 실제 비상 상황에서 필요했던 횟수보다 많습니다. 이는 근면함 그 자체를 위한 일이 아닙니다. 저장소 안에 있는 것이 안심되는 이름을 붙인 암호화된 잡음 폴더가 아니라 진짜 백업이라는 사실을 확인할 수 있는 유일한 방법이기 때문입니다.

아래의 조언은 의도적으로 유행과 거리가 멉니다. 대시보드와 월간 구독료, 지원 문의 대기열이 딸린 백업 제품 같은 것은 등장하지 않는데, 그런 것은 하나같이 계정이고, 계정은 곧 이름과 카드와 관할권이기 때문입니다 — 여러분이 이 서버에서 실제로 애써 멀리해 두었을 세 가지입니다. 대신 등장하는 것은 두 번째 머신 한 대, 약 마흔 줄의 셸 스크립트, 그리고 거의 아무도 지키지 않는 습관 하나뿐입니다.

하룻저녁이면 충분히 끝낼 수 있는 작업입니다. 도구는 Debian 13과 Ubuntu 24.04 기준이며, RHEL 계열에도 뻔한 치환만 거치면 그대로 옮길 수 있습니다. 서버가 새 것이라면 이 페이지보다 먼저 첫 한 시간 강화 작업을 끝내 두십시오 — 이미 남의 것이 되어 버린 머신을 백업하는 것은 그 사람의 작업물을 고이 보존해 주는 것밖에 되지 않습니다.

임대 서버에서 실제로 데이터를 파괴하는 것

누구에게 왜 백업을 하냐고 물으면 대개 “디스크가 죽을 경우를 대비해서”라는 답이 돌아옵니다. 최신 VPS에서 그것은 여러분에게 일어날 가능성이 가장 낮은 축에 속하는 일입니다. 여러분의 볼륨은 중복 구성된 NVMe 어레이 위에 있고, 하이퍼바이저는 여러분이 알아차리기도 전에 장애가 발생한 호스트에서 마이그레이션을 끝냅니다. 드라이브 고장은 제공업체의 문제이고, 이미 해결된 문제입니다. 백업 전략 전체를 여기에 맞춰 세우는 것은 홍수가 나는 집에 소화기를 사다 놓는 것과 같습니다.

실제로 사람들의 데이터를 앗아가는 것은, 대략 빈도 순으로 나열하면 다음과 같습니다. 첫 번째는, 그것도 압도적인 차이로: 바로 여러분 자신입니다. 변수가 빈 문자열로 확장되어 버린 rm -rf. 탭 두 개가 똑같아 보여서 엉뚱한 터미널에 친 DROP DATABASE. 두 번 실행된 마이그레이션 스크립트. -v가 손에 밴 습관이 되어 버린 docker compose down -v. 이런 일들은 특별한 사건이 아니라, 그냥 흔한 화요일입니다.

두 번째는 애플리케이션이 스스로 자기 데이터를 지우는 경우입니다. 파괴적인 마이그레이션을 실행하다 절반쯤에서 실패하는 업그레이드. 캐시인 줄 알았는데 아니었던 디렉터리를 비워 버리는 플러그인. 엉뚱한 경로를 대상으로 설정된 로그 로테이션. 세 번째는 침해입니다 — 이 경우 공격자는 백업이 사라지기를 바란다는 점에 주목해야 하며, 이는 아래에서 다시 다룰 설계 방식을 바꿔 놓습니다. 네 번째는 no-KYC 호스트에서 특히 잊기 쉬운 경우로, 계정을 잃어버리는 것입니다. 자리를 비운 사이 잔액이 0이 되어 버렸거나, 어디에도 적어 두지 않은 비밀번호 관리자 항목이거나, 더 이상 쓰지 않게 된 이메일 주소 같은 것들입니다. 저희는 잔액이 0이 된 지 몇 시간 안에 정지시키고 7일 뒤에는 파기하며, 이는 의도적으로 봐주는 것이 없는 방식입니다 — 바로 이 계산법 덕분에 저희는 여러분이 누구인지 물을 필요가 없어집니다. 여러분의 신원을 조회해 예외를 만들어 줄 상담원은 존재하지 않는데, 애초에 조회할 신원 자체가 없기 때문입니다.

이 마지막 범주야말로 프라이버시 우선 호스팅을 주류 호스팅과 갈라놓는 지점이며, 여러분의 계획도 이를 중심으로 짜여야 합니다. 이 서버를 여러분과 결부 짓기 어렵게 만드는 모든 통제 장치는, 동시에 저희를 포함한 그 누구도 그것을 여러분에게 돌려주기 어렵게 만듭니다. 백업은 바로 그 거래를 위험에서 선택으로 바꿔 주는 장치입니다.

스냅샷이 백업이 아닌 이유

스냅샷은 훌륭한 도구이며 반드시 활용해야 합니다. 커널 업그레이드 전에, 데이터베이스 마이그레이션 전에, 되돌릴 수 있었으면 하는 무언가를 하려 할 때마다 하나씩 찍어 두십시오. 복원은 몇 초면 끝나고, 비용은 거의 들지 않으며, 일 년에도 열두어 번은 여러분의 오후를 구해 줄 것입니다.

그럼에도 스냅샷은 백업이 아니며, 그 이유는 구조적인 세 가지로, 제공업체의 어떤 마케팅으로도 바뀌지 않습니다. 스냅샷은 같은 계정 안에 존재합니다: 여러분 패널에 로그인할 수 있는 사람이라면 누구든 지울 수 있고, 계정이 멈추면 스냅샷도 함께 사라집니다. 스냅샷은 같은 장애 도메인 안에 있습니다: 같은 제공업체, 같은 제어 평면, 흔히 같은 스토리지 클러스터를 공유하므로, 단 한 번의 나쁜 사건이 원본과 사본을 동시에 앗아갈 수 있습니다. 그리고 스냅샷은 불투명합니다: 실행 중인 머신의 스냅샷은 쓰는 도중이던 데이터베이스를 다른 모든 것과 똑같이 충실하게 그대로 포착해 버리므로, 바쁘게 돌아가던 MySQL 서버의 스냅샷을 복원하면 깨끗한 데이터베이스가 아니라 크래시 복구 시나리오를 얻게 됩니다.

오래된 3-2-1 규칙 — 세 벌의 사본을, 두 종류의 매체에, 그중 하나는 오프사이트에 — 은 흔히 가운데 조항이 임대 인프라에서는 아무 의미가 없다는 사실을 눈치채지 못한 채 그대로 읊어지곤 합니다. 여러분에게는 두 종류의 매체가 없습니다. 가상 블록 장치 하나와 또 다른 가상 블록 장치가 있을 뿐이고, 둘 다 누군가의 SAN입니다. VPS로 옮겨 놓아도 여전히 살아남는 부분은 애초부터 정말 중요했던 그 부분입니다: 최소한 사본 하나는 단 한 번의 나쁜 사건으로는 닿을 수 없는 곳에 있어야 한다는 것입니다. 다른 제공업체, 최소한 다른 리전, 다른 인증 정보, 다른 계정, 그리고 — 오프쇼어 호스팅을 택한 이유가 기술적인 것이 아니라 법적인 것이라면 — 법원 명령 하나가 두 사본에 동시에 떨어지지 않도록 다른 관할권까지 두어야 합니다.

백업 목적지도 여러분의 위협 모델입니다

이 섹션은 다른 백업 튜토리얼에는 없는 내용이며, 이 서버를 Monero로 결제했다면 가장 중요하게 챙겨야 할 부분이기도 합니다.

인터넷 어디서나 볼 수 있는 기본 조언은 백업을 오브젝트 스토어에 push하라는 것입니다: Backblaze B2, Amazon S3, Wasabi, rclone을 통한 Google Drive 같은 곳들입니다. 저렴하고, 내구성이 있고, 실제로 잘 작동합니다. 그리고 명령어 한 줄로, 여러분이 그동안 해 온 일의 상당 부분을 무너뜨리기도 합니다. 그 계정을 개설하려면 카드와 대개 신분증이 필요했을 것입니다. 첫 스냅샷이 업로드되는 순간부터, 그 제공업체는 여러분의 이름과 결제 정보여러분 서버의 IP 주소와 연결한 타임스탬프 기록을 매시간 갱신하며 영구히 보관합니다. 여러분은 저희에게 신원을 인증한 적이 없습니다. 그들에게 인증한 것이고, 그렇게 함으로써 그 둘 사이에 선을 그어 버린 것입니다.

뒷부분은 더 심각하며, 사람들이 흔히 놓치는 부분입니다. 그 업로드를 인가하는 API 키는 운영 서버 위의 파일 하나에 불과합니다. 그 박스에서 root 권한을 얻은 사람 — 또는 합법적으로 디스크를 확보한 사람 — 은 단순히 여러분의 데이터만 얻는 것이 아닙니다. API 호출 한 번으로 결제 신원까지 알아낼 수 있는 인증 정보를 함께 얻습니다. 익명이었던 서버가 여러분의 은행 계좌를 가리키는 이정표가 되어 버린 것입니다.

그렇다고 오브젝트 스토리지가 잘못됐다는 뜻은 아닙니다. 다만 그것이 기본값이 아니라 하나의 결정이 되어야 한다는 뜻입니다. 처음에 갖추고 있던 익명성을 얼마나 잘 지켜 주는지 순서대로 나열한 세 가지 대안이 있습니다:

  • 두 번째 no-KYC VPS를 두는 것으로, 이상적으로는 운영 서버와 다른 관할권에 두고 같은 크립토 잔액으로 결제합니다. 이렇게 하면 목적지가 원본의 익명성을 거스르는 대신 그대로 물려받게 됩니다. 저희가 실제로 하는 방식이며, 이 가이드의 나머지 부분도 이를 전제로 합니다.
  • 신원 확인 없이 크립토를 받는 스토리지 제공업체. 실제로 존재하며, 규모는 더 작습니다. 마케팅 문구를 곧이곧대로 믿기 전에 결제 경로가 정말로 신원과 무관한지 확인하고, 복원하다가 뒤늦게 알게 되기 전에 이그레스(egress) 요금부터 확인하십시오.
  • 여러분이 물리적으로 소유한 머신으로, 여러분 회선 뒤에서 WireGuard를 통해 pull해 오는 방식입니다. 익명성 면에서는 훌륭하지만 가용성은 떨어지며, 복원 속도가 곧 여러분 집 회선의 업로드 속도가 되어 버립니다. 세 번째 사본으로는 합리적이지만, 유일한 사본으로 쓰기에는 약합니다.

무엇을 택하든, 백업을 보관하는 계정은 운영 서버를 보관하는 계정과 인증 정보, 이메일 주소, 복구 경로를 공유해서는 안 됩니다. 핵심은 로그인 하나가 뚫리더라도 둘 다에는 닿지 못하게 하는 것입니다. 이는 다른 곳에서 신원을 분리해 두는 것과 같은 원칙을, 시스템에서 가장 화려하지 않은 구석에 적용한 것일 뿐입니다.

Push, pull, 그리고 랜섬웨어가 여러분의 백업을 찾아내는 이유

거의 모든 백업 튜토리얼은 똑같은 아키텍처를 만들어 냅니다: 운영 서버 위의 cron 작업이 원격 저장소에 인증하고 그곳에 씁니다. 단순하고 실제로 잘 작동하지만, 아무도 언급하지 않는 성질이 하나 있습니다 — 운영 서버가 저장소 전체를 삭제할 수 있는 인증 정보를 쥐고 있다는 점입니다. 오래된 스냅샷을 정리하려면 삭제 권한이 필요하므로, 매일 밤 작업을 돌리는 그 키가 곧 금고를 통째로 비울 수 있는 키이기도 합니다.

침해 상황에서 이것이 무엇을 뜻하는지 생각해 보십시오. 그 박스에서 root 권한을 얻은 공격자는 여러분의 백업을 굳이 찾을 필요조차 없습니다. 여러분이 친절하게도 작동하는 인증 정보와 저장소 이름이 적힌 설정 파일을 남겨 두었으니까요. 눈에 띄는 행동을 벌이기 전에 백업부터 찾아내 파괴하는 것은 가상의 정교한 수법이 아니라 표준 관행입니다. 사고를 협상으로 바꿔 놓는 것이 바로 그 수법이기 때문입니다. 여러분의 야간 작업이 곧 정찰이었던 셈입니다.

설계 방식은 세 가지가 있으며, 그 차이는 전적으로 어느 머신이 어떤 키를 쥐고 있느냐로 갈립니다.

단순 push는 위에서 설명한 방식입니다. 운영 서버가 읽기·쓰기·삭제 권한을 모두 갖습니다. 편리하지만, 백업이 가장 필요한 바로 그 시나리오에서 완전히 실패해 버립니다. 여러분이 진짜로 신경 쓰는 유일한 위협이 여러분 자신의 손가락뿐일 때만 쓰십시오.

Append-only push는 형태는 그대로 두되 위험한 동사만 없앱니다. 저장소는 프로토콜을 이해하고 삭제를 거부하는 무언가가 서빙합니다: restic이라면 rest-server --append-only, Borg라면 authorized_keys에서 강제한 borg serve --append-only입니다. 운영 서버는 새 스냅샷을 만들 수는 있지만 기존 것을 지울 수는 없습니다. 정리 작업은 나중에, 다른 곳에서, 다른 키로 이루어집니다. 약 20분의 작업만으로 얻는 큰 개선이며, 대부분의 사람에게는 여기서 멈추는 것이 정답입니다.

Pull은 연결 방향을 뒤집습니다. 백업 호스트가 SSH를 통해 운영 서버 안으로 들어가 필요한 것만 복사해 오고, 백업 도구는 자신의 디스크 위에서 로컬로 실행합니다. 운영 서버는 백업 인증 정보를 아예 쥐고 있지 않습니다 — 그 머신은 자기 백업이 어디에 있는지조차 모르므로, 찾아낼 것 자체가 없습니다. 가장 강력한 구성이며, 아래의 단계별 절차가 만드는 것도 바로 이 방식입니다.

pull에 드는 비용도 솔직하게 짚어야 합니다. 공짜가 아니기 때문입니다. 키를 없앤 것이 아니라 옮긴 것뿐입니다: 이제 백업 호스트가 운영 서버로 들어가는 SSH 키를 쥐고 있으므로, 백업 호스트가 침해되면 그 손길이 운영 시스템까지 뻗어 나갈 수 있습니다. 그래도 더 나은 거래이긴 합니다 — 백업 호스트는 아무것도 실행하지 않고 SSH 외에는 아무것도 노출하지 않으며, 공개된 웹 서버보다 훨씬 작은 표적이기 때문입니다 — 하지만 어쨌든 거래는 거래이며, 그 키를 파일을 읽는 것 말고는 아무것도 할 수 없도록 읽기 전용 명령으로 강제해 두면 남은 틈의 대부분을 메울 수 있습니다.

도구 고르기: restic, Borg, 아니면 그냥 rsync

사실상 모든 경우를 커버하는 도구는 세 가지뿐이며, 이 선택은 포럼 스레드들이 암시하는 것만큼 고민스러운 일이 아닙니다.

restic은 기본적으로 암호화하고, 스냅샷 간에 중복을 제거하며, SFTP, S3, REST를 비롯한 십수 가지 백엔드를 지원하고, 어디에나 던져 넣을 수 있는 단일 정적 바이너리로 배포됩니다. 저장소 포맷이 콘텐츠 주소 방식이라 스냅샷은 저렴하며, 아무리 많은 머신이 보내와도 동일한 데이터는 한 번만 저장됩니다. 비용은 실재하지만 크지 않습니다: 저장소 인덱스에 비례하는 메모리를 요구하며, 실행이 중단되면 오래된 잠금이 남아 restic unlock으로 정리하기 전까지는 다음 실행이 이를 넘어가기를 거부합니다. 이것이 기본 추천 도구이며 아래 단계에서도 사용하는 도구입니다.

Borg는 중복 제거와 압축 성능이 더 뛰어나며, 수백만 개의 작은 파일로 이루어진 저장소에서는 눈에 띄게 더 빠릅니다. 대신 결합도가 높다는 대가가 따릅니다: 양쪽 끝 모두에 Borg가 설치되어 있어야 하고 버전도 서로 가깝게 맞아야 하며, 저장소 하나는 사실상 클라이언트 하나만을 위해 설계되어 있고, 헬퍼 계층 없이는 오브젝트 스토어 백엔드를 네이티브로 지원하지 않습니다. 원본이 대용량 메일 스풀이거나 작은 파일로 가득한 파일시스템이고, 양쪽 머신을 모두 직접 통제할 수 있다면 Borg는 절반의 용량만 씁니다. --append-only 모드 역시 두 도구를 통틀어 이 개념을 가장 깔끔하게 구현한 사례입니다.

rsync는 백업 도구가 아니며, 그렇지 않은 척하다가는 손상된 디렉터리를 충실하게 그대로 미러링한 사본 하나만 손에 쥐게 됩니다. 버전 관리도, 중복 제거도, 저장 시 암호화도 없습니다. rsync --delete는 여러분의 실수를 네트워크 속도 그대로 사본에 전파해 버립니다. 그럼에도 여러분이 통제하는 두 머신 사이에서 바이트를 옮기는 용도로는 딱 맞는 도구이며, 이는 정확히 pull 설계에서 rsync가 맡는 역할입니다. 바이트가 도착하고 나면 버전 관리와 암호화는 restic이 맡습니다. 각 도구는 그것이 잘하는 일에만 쓰십시오.

하지 말아야 할 일이 하나 있습니다: tar와 날짜가 찍힌 파일명으로 직접 만든 백업 체계를 굴리지 마십시오. 넉 달 정도는 잘 굴러가다가, 아무것도 만료되지 않아 디스크가 가득 차 버리는 날이 오거나, 40 GB짜리 데이터셋을 매일 밤 통째로 복사하면 한 달에 1.2 TB — 그것도 서른 개의 거의 똑같은 사본을 위해 — 를 돈 내고 저장하고 있었다는 사실을 깨닫는 날이 옵니다.

무엇을 포함할 것인가 — 그리고 여러분의 뒤통수를 칠 데이터베이스

파일시스템 전체를 백업하고 싶은 것이 본능입니다. 참으십시오. 루트 파일시스템의 대부분은 90초면 재설치할 수 있는 배포판 패키지들이며, 이를 포함시키면 저장 공간과 전송 시간, 그리고 더 나쁘게는 주의력까지 소모됩니다 — 아무도 테스트하고 싶어 하지 않는 40 GB짜리 백업은, 분기마다 실제로 복원해 보는 900 MB짜리 백업보다 쓸모가 없습니다.

정말로 재구성할 수 없는 것은 목록이 짧습니다: /etc(여러분의 설정 전체이자, 재구축이 주말이 아니라 한 시간 만에 끝나는 이유), /home/root, /srv/var/www, /var/lib//opt/ 아래의 애플리케이션 상태, 이름 붙인 Docker 볼륨, 여러분이 직접 작성한 cron과 systemd 유닛, 그리고 데이터베이스 덤프입니다. /proc, /sys, /dev, /run, /tmp, /var/cache, 스왑 파일, 소켓, /var/lib/docker/overlay2는 건너뛰십시오 — 특히 마지막 항목은 compose 파일에서 그대로 재구축할 수 있으면서도 흔히 디스크에서 가장 큰 단일 디렉터리이기도 합니다.

이제 복원을 조용히 망쳐 놓는 부분을 봅시다. 데이터베이스가 실행 중인 상태에서 그 데이터 디렉터리를 복사하면, 십중팔구 쓸 수 없는 파일 묶음이 만들어집니다. 엔진은 상태를 메모리에 들고 있으면서, 순서가 중요한 여러 파일에 걸쳐 씁니다. 반면 여러분의 복사 작업은 몇 분에 걸쳐 그 트리를 훑으며 서로 다른 순간에 서로 다른 파일들을 붙잡습니다. InnoDB는 이로부터 크래시 복구에 성공할 때도 있고 실패할 때도 있습니다. 그리고 그 실패는 몇 달 뒤, 이미 힘든 하루를 보내고 있는 와중의 복원 작업에서야 겉으로 드러납니다.

대신 엔진을 통해 덤프한 뒤, 그 덤프 파일을 백업하십시오:

# MariaDB / MySQL — InnoDB gets a consistent snapshot from one transaction
mariadb-dump --single-transaction --quick --routines --triggers --events \
  --all-databases | zstd -T0 > /var/backups/db/all-$(date -u +%F).sql.zst

# PostgreSQL — pg_dump is consistent by design; grab roles separately
pg_dumpall --globals-only > /var/backups/db/globals.sql
pg_dump -Fc -Z6 mydb    > /var/backups/db/mydb.dump

# SQLite — never cp a live database; WAL mode makes that a torn file
sqlite3 /var/lib/app/app.db ".backup /var/backups/db/app.db"

새겨 둘 만한 각주가 두 가지 있습니다. --single-transaction은 InnoDB에 한해서만 일관성을 보장합니다 — 아직 MyISAM으로 남은 테이블이 있다면 그 트랜잭션 밖에서 복사되어 나머지와 일관성이 어긋날 수 있으므로, 그런 테이블은 변환하거나 잠가 두십시오. 그리고 덤프를 뜨기로 했다면 파일 백업 대상에서 실제 데이터 디렉터리는 제외하십시오. 둘 다 백업하면 멀쩡한 사본 옆에 커다랗게 찢긴 사본까지 함께 저장해 두는 셈이 되고, 훗날 복원할 때 후보 두 개 중 하나가 조용히 잘못된 상태로 남게 됩니다.

컨테이너를 쓴다고 원칙이 바뀌지는 않으며, 경로만 바뀔 뿐입니다: docker compose exec -T db mariadb-dump …로 덤프를 실행하고, 그 밑의 볼륨이 아니라 결과로 나온 파일을 백업하십시오.

암호화 키는 어디에 두어야 하는가

클라이언트 사이드 암호화야말로, 데이터가 원래 있던 곳이 아닌 다른 머신에 저장해도 괜찮은 이유 전부입니다. restic과 Borg 모두 원본을 떠나기 전에 암호화하므로, 백업 호스트는 암호문만 쥐고 있게 되고 신뢰할 수 없는 저장소로 취급해도 됩니다. 다만 이 성질의 가치는 딱 여러분이 키를 얼마나 잘 다루느냐만큼이며, 그 이상도 이하도 아닙니다.

실패 양상은 한숨이 나올 만큼 흔합니다. 저장소 비밀번호는 운영 서버의 /etc/restic/env에 놓여 있으며, 이는 자동화를 위해 필요하고 그 자체로는 문제없습니다. 그런데 정작 잃어버리는 것이 운영 서버라면 — 파괴되었든, 압수되었든, 계정과 함께 그냥 사라졌든 — 여러분 눈앞에는 수백 기가바이트의 암호화된 블록만 남고, 그 키의 유일한 사본이 다름 아닌 잃어버릴까 봐 스스로를 지키려던 바로 그 대상 안에 있었다는 사실을 서서히 깨닫게 됩니다.

그러니 원칙은 이렇습니다: 서버 위의 비밀번호는 어디까지나 작업용 사본일 뿐, 결코 원본 기록이 아닙니다. 원본 기록은 서버보다 오래 살아남는 곳에 두어야 합니다 — 그 자체가 다른 곳에 백업되어 있는 비밀번호 관리자의 볼트든, 서랍 속 종이에 적어 둔 것이든, 아니면 둘 다든 상관없습니다. 저장소 위치와 정확한 복원 명령도 그 옆에 함께 적어 두십시오. 맥락 없는 패스프레이즈는 18개월 뒤 스트레스 속에서 풀어야 할 퍼즐이 되어 버리기 때문입니다. 그리고 5분을 들여 직접 검증해 보십시오: 다른 머신에서, 비밀번호 관리자에 있는 것만 가지고 그 저장소에 대해 restic snapshots를 실행해 보는 것입니다. 이것이 작동한다면 여러분에게는 백업이 있는 것입니다. 운영 서버에만 존재하는 무언가가 필요하다면, 여러분에게 있는 것은 그저 매우 비싼 폴더일 뿐입니다.

두 도구 모두 하나의 저장소에 여러 개의 키를 등록할 수 있어(restic key add), 원래 패스프레이즈를 공유하지 않고도 정리 작업이나 두 번째 관리자에게 접근 권한을 깔끔하게 내줄 수 있습니다. 그리고 운영 서버의 디스크가 LUKS로 암호화되어 있다면, 두 비밀은 진짜로 분리해서 보관하십시오 — restic 패스프레이즈를 LUKS 볼륨 안에, LUKS 패스프레이즈를 restic 저장소 안에 넣어 두는 것은 양쪽 모두를 안전 실패(fail closed) 상태로 만들어 버리는 고리입니다.

보존 기간: 일주일치만 남겨 두는 함정

보존 기간은 저장 비용의 문제처럼 보이지만 실제로는 탐지 지연의 문제입니다. 중요한 숫자는 디스크를 얼마나 쓰고 싶으냐가 아니라, 문제가 여러분 시스템 안에서 얼마나 오래 눈치채이지 않은 채 남아 있을 수 있느냐입니다. 그 기간이 얼마이든, 여러분이 가진 가장 오래된 백업은 그보다 더 오래되어 있어야 합니다.

일곱 개의 일간 스냅샷은 넉넉해 보이지만 실제로는 빈약합니다. 아무도 조회하지 않는 손상된 테이블, 오작동하는 cron 작업이 천천히 진행시키는 삭제, 눈에 띄는 짓을 벌이기까지 한 달을 조용히 숨어 있던 침입 — 이런 것들은 예사로 일주일보다 오래 걸려서야 겉으로 드러나며, 여러분의 이력이 7일치밖에 없다면 여러분이 가진 스냅샷은 이미 전부 오염되어 있는 셈입니다. 실제 침입에서 체류 시간(dwell time)은 흔히 몇 주 단위로 측정됩니다. 저렴한 월간 스냅샷이 바로 이에 대한 구체적인 방어책이며, 중복 제거 덕분에 실제로도 아주 저렴합니다: 1년치 월간 스냅샷을 유지해도 전체 사본 하나의 극히 일부만 더 추가될 뿐입니다. 실제로 변경된 블록만 두 번 저장되기 때문입니다.

restic forget \
  --keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 2 \
  --prune

이 사다리꼴 구성 — 일주일치의 일간, 한 달치의 주간, 1년치의 월간, 몇 년치의 연간 — 은 대략 스물여섯 개의 스냅샷이 되며, 일반적인 데이터에서는 전체 사본 하나의 두 배에도 한참 못 미치는 용량입니다. 특별히 벗어날 이유가 없다면 저희가 권하는 기본값이 바로 이것입니다.

운영상 짚어 둘 것이 두 가지 있습니다. --prune 없이 실행한 forget은 라벨만 지울 뿐이라, prune하기 전까지는 공간이 회수되지 않습니다 — 줄어들지 않는 디스크를 지켜보던 사람들을 당황하게 만드는 지점입니다. 그리고 --prune은 저장소에 대한 삭제 권한을 필요로 하므로, append-only나 pull 설계에서는 이를 운영 서버에서 실행하지 않습니다. 백업 호스트에서, 또는 여러분의 노트북에서, 운영 서버가 한 번도 본 적 없는 키로 실행합니다. 그 분리야말로 핵심이니, 마지막 단계에서 편하자고 이를 무너뜨리지 마십시오.

조용히 실패하지 않도록 자동화하기

전형적인 백업 참사는 죽어 버리는 작업이 아닙니다. 조용히 멈춰서 아무에게도 알리지 않다가, 11개월 뒤 그것이 절실히 필요해진 누군가에 의해 발견되는 작업입니다. 아래의 요소들은 하나같이 바로 그 결말을 불가능하게 만들기 위해 존재합니다.

cron 대신 systemd 타이머를 쓰십시오. 종료 상태까지 함께 기록되는 진짜 저널 로그를 얻을 수 있고, Persistent=true 덕분에 머신이 꺼져 있는 동안 놓친 실행이 영원히 건너뛰어지는 대신 다음 부팅 때 실행되며, RandomizedDelaySec 덕분에 여러 대가 정확히 03:00에 동시에 백업 호스트로 몰려들지 않습니다. cron의 실패 알림은 로컬 메일함으로 가는 이메일인데, 요즘 서버에서는 정확히 아무 데도 도착하지 않습니다.

# /etc/systemd/system/backup.timer
[Unit]
Description=Nightly encrypted backup

[Timer]
OnCalendar=*-*-* 03:17:00
RandomizedDelaySec=1800
Persistent=true

[Install]
WantedBy=timers.target

그다음에는 데드맨 스위치(dead-man's switch)를 추가하십시오. 이 가이드 전체를 통틀어 가장 값어치가 큰 한 줄입니다. 스크립트의 맨 끝에서 — 백업이 끝나기 전이 아니라 성공적으로 끝난 후에 — 매일 소식을 기다리다가 소식이 없으면 경보를 울리는 모니터에 HTTPS 요청을 보내십시오. 이는 알림 로직을 뒤집는 방식입니다: 실패가 메시지를 만들어 내기를 기다리는 대신, 부재 그 자체가 경보가 됩니다. 그러면 사흘째 죽어 있던 작업은 위기 상황에서의 발견이 아니라 여러분 받은편지함의 메시지 하나로 바뀝니다. 또 다른 제3자 계정을 만들고 싶지 않다면 그 모니터를 백업 호스트에 셀프 호스팅하십시오. 몇 줄과 별도의 타이머 하나면 충분합니다.

마지막으로, 저희가 최소한 한 번씩은 다 겪어 본 자잘한 운영상의 위험들입니다. 중단된 실행은 잠금을 남기고, 그 뒤로 이어지는 모든 실행은 나흘째 밤부터는 더 이상 읽지 않게 되는 메시지와 함께 실패합니다 — restic unlock은 반사적으로가 아니라 의도적으로 다루십시오. 목적지 디스크가 가득 차면 누군가 들여다볼 때까지 모든 작업이 실패하므로, 작업 상태뿐 아니라 여유 공간에 대해서도 알림을 설정하십시오. 만료 기한이 있는 SSH 키, 교체된 호스트 키, 관련 없는 작업 중에 추가된 nftables 규칙 하나하나가 pull을 조용히 끊어 버릴 수 있습니다. 그리고 start만이 아니라 systemctl enable --now를 쓰십시오: 한 번도 활성화된 적 없는 타이머는 첫 재부팅 전까지는 완벽하게 작동하다가, 그 이후로는 두 번 다시 실행되지 않습니다.

복원 훈련

지금까지의 모든 것은 준비 과정일 뿐입니다. 이를 진짜 백업으로 바꿔 주는 것은 바로 이 부분이며, 거의 모든 사람이 건너뛰는 부분이기도 합니다.

분기에 한 번, 새 VPS를 배포하십시오 — $5짜리 Starter로 충분하며, 과금은 시간 단위에 초 단위로 일할 계산되므로 이 훈련 전체에 드는 비용은 몇 센트에 불과합니다. 실제 재난 상황이라면 손에 쥐고 있을 것, 오직 그것만 가지고 복원하십시오: 저장소 주소, 비밀번호 관리자에서 꺼낸 패스프레이즈, 그리고 적어 둔 절차서입니다. 운영 서버에 있는 것은 일부러 아무것도 쓰지 마십시오. 지금 연습하고 있는 시나리오에서는 운영 서버가 존재하지 않기 때문입니다. 애플리케이션을 띄우고, hosts 파일 항목을 새 IP로 돌려놓고, 이곳저곳 눌러 보십시오. 그런 다음 없애십시오.

# on a throwaway machine, with nothing but the passphrase
export RESTIC_REPOSITORY=sftp:[email protected]:/srv/restic/prod
restic snapshots                      # can you even see the history?
restic restore latest --target /restore
restic check --read-data-subset=10%   # verify stored blocks, not just metadata

이 훈련이 잡아내는 것은 언제나 예상 밖의 것입니다. include 목록이 놓친 디렉터리 안에 있던 설정 파일. 비밀번호가 바뀌었는데 스크립트가 종료 상태를 확인하지 않아서 5주째 0바이트로 남아 있던 데이터베이스 덤프. 오케스트레이터가 쥐고 있는 환경 변수 안에만 있고 파일시스템에는 애초에 존재한 적조차 없는 시크릿 때문에 시작조차 되지 않는 애플리케이션. 문서화되지 않은 DNS 레코드. 443번 포트가 응답하기 전에 다시 발급받아야 하는 인증서. 이런 것들 하나하나는 한가한 오후라면 10분짜리 수정거리지만, 새벽 3시라면 지저분한 두 시간짜리 일이 되어 버립니다.

훈련이 처음부터 끝까지 얼마나 걸렸는지 적어 두십시오. 그 숫자가 — 백업 주기가 아니라 — 여러분의 진짜 복구 시간이며, 얼마나 오래 다운될 것 같냐는 질문에 내놓을 수 있는 유일하게 정직한 답입니다. 월간 타이머에 restic check --read-data-subset=5%도 추가해 두십시오: 인덱스만이 아니라 실제로 저장된 블록 중 돌아가며 표본을 읽어 검증해 주므로, 아직 되돌아갈 만한 멀쩡한 사본이 남아 있을 때 조용한 손상을 찾아낼 수 있는 방법입니다. 언젠가 서버 전체를 새 호스트로 옮기게 된다면, 이미 연습해 둔 복원 절차가 곧 그 이전 작업의 대부분이기도 합니다.

  1. 정말로 재구축할 수 없는 것의 목록 만들기

    도구를 다루기 전에 먼저 목록부터 작성하십시오. 머신을 하나씩 둘러보며 각 디렉터리에 대해 물어보십시오: 이것이 사라진다면 패키지 관리자나 git 저장소, compose 파일에서 다시 만들어 낼 수 있는가? 그렇다면 백업 대상이 아닙니다. 남는 것은 대개 사람들의 예상보다 훨씬 작습니다 — 설정, 사용자 데이터, 애플리케이션 상태, 데이터베이스 덤프 정도입니다.

    # the fast way to find what is actually big and stateful
    du -x -h -d2 / 2>/dev/null | sort -rh | head -30
    docker volume ls    # named volumes are state; overlay2 is not

    그 결과를 /etc/restic/include.txt/etc/restic/exclude.txt, 이렇게 명시적인 파일 두 개로 정리하십시오. 명시적인 목록은 영리한 find 표현식보다 낫습니다. 검토할 수 있기 때문이며, 서버에 새 디렉터리가 생겼을 때 그것이 조용히 포함되어 버리는 대신 의도적인 결정을 거치게 만들기 때문입니다.

  2. 다른 관할권에 백업 목적지 배포하기

    운영 서버가 돌아가는 곳과는 다른 리전에 두 번째 VPS를 주문하십시오 — 운영 서버가 파리에 있다면 사본은 레이캬비크부쿠레슈티에 두십시오. 핵심은 단 하나의 법적, 물리적 사건이 두 머신 모두에 닿을 수 없게 하는 것입니다. 월 $5짜리 Starter는 80GB의 NVMe를 제공하며, 중복 제거를 거치면 일반적인 소규모 서버의 상당히 긴 이력을 담아낼 수 있습니다. 12개월 결제 주기를 택하면 그 비용은 절반이 됩니다. 목적지가 원본의 익명성을 거스르지 않고 그대로 물려받도록, 같은 크립토 잔액에서 결제하십시오.

    인증 정보를 완전히 분리하고 싶다면 운영 서버와는 별개의 계정으로 개설하십시오. 그런 다음 다른 어떤 머신과도 다를 바 없이 강화하십시오 — 키 전용 SSH, 기본 차단 방화벽 — 그리고 그 외에는 아무것도 설치하지 마십시오. 이 머신의 가치는 지루하다는 데 있습니다: 웹 서버도 없고, SSH 말고는 열린 포트도 없으며, 인터넷에서 노려 볼 만한 것이 아무것도 없습니다.

  3. 백업 호스트에서 운영 서버로 향하는 읽기 전용 문 만들기

    이것이 바로 pull 방식을 완성하는 단계입니다. 백업 호스트에서 전용 키를 하나 생성하십시오. 그런 다음 그 공개 키를 운영 서버에, 강제 명령(forced command)과 함께 설치하여 그 키가 딱 한 가지 일만 할 수 있게 만드십시오: 파일 읽기입니다. 셸을 열 수도, 포트를 포워딩할 수도, 무언가를 쓸 수도 없습니다.

    # on the backup host
    ssh-keygen -t ed25519 -a 100 -f ~/.ssh/pull_prod -C "pull@backup"
    
    # on production, in /root/.ssh/authorized_keys — one line
    command="/usr/bin/rrsync -ro /",restrict ssh-ed25519 AAAAC3Nz… pull@backup

    rrsync는 rsync와 함께 배포됩니다(Debian 13에서는 /usr/bin/rrsync, 예전 릴리스에서는 /usr/share/doc/rsync/scripts/rrsync). -ro를 붙이면 읽기 외에는 전부 거부합니다. restrict 한 단어로 포트 포워딩, 에이전트 포워딩, PTY 할당, X11을 한꺼번에 비활성화할 수 있습니다. 이 우리(cage)를 믿고 쓰기 전에 실제로 갇혀 있는지 검증하십시오 — ssh -i ~/.ssh/pull_prod root@production은 셸을 내주는 데 반드시 실패해야 합니다.

  4. 운영 서버에서 자체 일정으로 데이터베이스 덤프 뜨기

    운영 서버가 여전히 맡는 일이 하나 있습니다: pull이 가져갈 스테이징 디렉터리에 일관된 덤프를 만들어 두는 일입니다. 이 작업에는 백업 인증 정보가 전혀 필요 없으며, 바로 그 점 덕분에 이 설계가 성립합니다.

    # /usr/local/sbin/dump-db.sh   (chmod 700)
    set -euo pipefail
    D=/var/backups/db; install -d -m 700 "$D"
    mariadb-dump --single-transaction --quick --routines --triggers --events \
      --all-databases | zstd -T0 > "$D/all.sql.zst.tmp"
    mv "$D/all.sql.zst.tmp" "$D/all.sql.zst"

    임시 파일에 쓴 다음 이름을 바꾸는 방식에 주목하십시오: 어떤 타이밍이든 pull이 절반만 쓰인 덤프를 가져갈 일이 없다는 뜻입니다. set -euo pipefail은 장식이 아닙니다 — 이것이 없으면 실패한 mariadb-dump가 빈 스트림을 zstd로 흘려보내고, 그마저 그대로 성공해 버려서 아무 내용도 없는 멀쩡해 보이는 압축 파일을 얻게 됩니다. 이것이 백업이 조용히 무용지물이 되는 가장 흔한 방식입니다. pull보다 30분 앞서 실행되도록 별도의 타이머를 걸어 두십시오.

  5. 데이터를 백업 호스트로 pull해 오기

    백업 호스트에서, 운영 서버의 include 목록을 rsync로 스테이징 트리에 가져오십시오. 변경된 블록만 네트워크를 타므로, 첫 실행 이후로는 빠르고 저렴합니다.

    # /usr/local/sbin/pull.sh   (chmod 700, runs on the BACKUP host)
    set -euo pipefail
    [email protected]
    # -r is spelled out on purpose: with --files-from, -a does NOT imply
    # recursion, and without it you silently copy empty directories.
    rsync -aHAX -r --delete --numeric-ids \
      -e "ssh -i /root/.ssh/pull_prod -o BatchMode=yes" \
      --files-from=/etc/backup/include.txt \
      --exclude-from=/etc/backup/exclude.txt \
      "$SRC:/" /srv/staging/prod/

    -aHAX는 하드링크, ACL, 확장 속성을 보존하며, --numeric-ids/etc/passwd가 서로 다른 머신들 사이에서도 소유권이 의미를 유지하게 해 줍니다. 여기서 --delete가 안전한 것은 정확히 스테이징이 백업이 아니기 때문입니다 — 버전이 관리되는 이력은 다음 단계에서 만들 restic 저장소 안에 있으므로, 스테이징까지 전파된 삭제라 하더라도 어제자 스냅샷에서 여전히 복구할 수 있습니다.

  6. 저장소 초기화하고 키는 오프라인에 보관하기

    여전히 백업 호스트에서, 로컬 restic 저장소를 만들고 스테이징 트리를 그 안에 백업하십시오. 로컬이라는 것은 핫 패스에 네트워크가 끼지 않고, 훔쳐 갈 원격 인증 정보도 없으며, 복원이 디스크 속도로 실행된다는 뜻입니다.

    apt install -y restic
    install -d -m 700 /etc/backup
    openssl rand -base64 32 > /etc/backup/pass   # write this into your password manager NOW
    chmod 600 /etc/backup/pass
    
    export RESTIC_REPOSITORY=/srv/restic/prod
    export RESTIC_PASSWORD_FILE=/etc/backup/pass
    restic init

    그 패스프레이즈를 비밀번호 관리자에 옮겨 두고, 그 옆에 저장소 경로와 복원 명령도 함께 적어 두십시오. 그런 다음 증명해 보십시오: 세 번째 머신에서, 비밀번호 관리자에 있는 것만 가지고 restic -r sftp:backup@…:/srv/restic/prod snapshots를 실행하는 것입니다. 이것이 스냅샷 목록을 보여 준다면 그 키는 진짜로 복구 가능한 것입니다. 어느 한쪽 서버에만 존재하는 무언가가 필요하다면, 나중에 발견하지 말고 지금 바로 고치십시오.

  7. 일정 잡기, 그리고 침묵을 경보로 만들기

    pull, restic 실행, prune을 스크립트 하나로 묶어 systemd 타이머로 구동하십시오. 여기서는 forget --prune을 실행해도 안전한데, 백업 호스트가 그 저장소를 정당하게 소유하고 있기 때문입니다 — 운영 서버는 애초에 단 한 순간도 삭제 인증 정보를 쥔 적이 없습니다.

    # tail of /usr/local/sbin/backup.sh
    restic backup /srv/staging/prod --tag nightly
    restic forget --keep-daily 7 --keep-weekly 5 --keep-monthly 12 \
                   --keep-yearly 2 --prune
    curl -fsS -m 10 --retry 3 https://hc.example.net/ping/<uuid>  # only on success
    systemctl daemon-reload
    systemctl enable --now backup.timer
    systemctl list-timers backup.timer     # confirm the next run is where you expect

    curl은 그 앞의 모든 명령이 성공했을 때만 실행되는데, set -e 덕분입니다. 반대편의 모니터는 매일 한 번씩 ping을 기다리다가 오지 않으면 경보를 울리므로, 조용히 멈춰 버린 작업이 고고학적 발견이 아니라 이메일 한 통으로 바뀝니다. start가 아니라 enable --now를 쓰십시오 — 한 번도 활성화된 적 없는 타이머는 딱 첫 재부팅까지만 버팁니다.

  8. 복원 훈련을 실행하고, 걸린 시간을 적어 두기

    여러분이 실제로 챙겨 보는 곳 어디에든, 분기마다 한 번씩 반복 알림을 걸어 두십시오. 일회용 Starter를 배포하고, 패스프레이즈와 적어 둔 절차서만 가지고 그 위에 복원한 다음, 애플리케이션을 띄우고, 실제 데이터를 제대로 서빙하는지 확인하고, 머신을 없애십시오. 시간 단위 과금 덕분에 훈련 전체 비용은 몇 센트에 불과합니다.

    restic restore latest --target /restore
    zstd -dc /restore/var/backups/db/all.sql.zst | mariadb
    systemctl start nginx app
    curl -H 'Host: example.com' http://127.0.0.1/health

    걸린 시간과 마주친 모든 뜻밖의 일들을 기록해 두고, 그 뜻밖의 일들은 여러분의 기억이 아니라 백업 스크립트 안에서 고치십시오. 그 걸린 시간이야말로 여러분의 진짜 복구 목표이며, 한 번이라도 실측해 보기 전까지 여러분이 말하는 어떤 숫자든 그저 짐작에 불과합니다.

비교

사본을 어디에 둘 것인가

각 목적지를, 그것을 결정짓는 네 가지 질문에 비추어 봅니다: 익명성에 어떤 대가를 치르는지, 돈은 얼마나 드는지, 데이터를 얼마나 빨리 되찾을 수 있는지, 그리고 무엇으로부터 살아남는지입니다.
목적지익명성 비용비용복원 속도생존 범위
두 번째 no-KYC VPS, 다른 리전없음 — 같은 크립토 잔액에서 결제하므로 어디에도 신원이 남지 않음월 $5, 12개월 주기면 절반빠름 — 데이터센터 간 1~10Gbps계정 상실, 침해, 한 관할권, 여러분 자신의 실수까지 견딤
제공업체 스냅샷없음저렴몇 초거의 아무것도 못 견딤 — 같은 계정, 같은 장애 도메인, 둘 다와 함께 죽음
오브젝트 스토어 (B2 / S3 / Wasabi)높음 — 계정에 카드와 신분증이 남고, 서버 위의 API 키가 그것을 가리킴저장은 아주 저렴하지만 복원 시 이그레스 요금이 문제빠름, 이그레스 요금을 감수한다면침해와 계정 상실은 견디지만, 그 대가로 머신에 이름이 붙음
크립토를 받는 스토리지 제공업체낮음, 결제 경로가 정말로 신원과 무관하다면 — 짐작하지 말고 확인할 것보통천차만별 — 필요해지기 전에 이그레스 한도부터 확인대부분은 견디지만, 직접 통제하는 VPS보다 거래 상대방 위험이 큼
WireGuard로 pull하는 홈 NAS없음 — 어떤 것도 암호화되지 않거나 신원이 드러난 채로 내 네트워크를 벗어나지 않음이미 가지고 있는 하드웨어느림 — 집 업로드 속도가 상한선집을 제외한 거의 모든 것을 견딤. 유일한 사본으로는 약하지만 세 번째 사본으로는 훌륭함
아무것도 안 함 / “git에 있으니 됐다”없음무료절대 불가아무것도 못 견딤. Git은 코드는 갖고 있지만, 데이터베이스도 업로드 파일도 여러분의 /etc도 갖고 있지 않음
FAQ

자주 묻는 질문

제공업체 스냅샷도 이미 백업 아닌가요?

아닙니다. 이 구분은 말장난이 아닙니다. 스냅샷은 자신이 복사하는 서버와 같은 계정, 같은 인증 정보, 같은 장애 도메인 안에 있습니다 — 그래서 계정을 잃으면 함께 사라지고, 패널에 접근할 수 있는 사람이라면 누구나 원본과 함께 지울 수 있습니다. 게다가 실행 중인 머신에서 뜨는 것이라, 바쁘게 쓰기 작업 중이던 데이터베이스도 그 도중 상태 그대로 포착됩니다. 스냅샷은 위험한 변경 전의 되돌리기 버튼으로 쓰고, 백업으로는 오프사이트에 있는 암호화된 저장소를 쓰십시오.

restic과 Borg, 어느 쪽을 써야 하나요?

특별히 그러지 말아야 할 이유가 없다면 restic입니다. 기본적으로 암호화하고, 목적지에는 아무것도 설치할 필요가 없으며, 쓸 만한 백엔드는 전부 지원하고, 정적 바이너리 하나로 배포됩니다. Borg는 중복 제거와 압축이 더 뛰어나고 수백만 개의 작은 파일이 있는 파일시스템에서는 확연히 더 빠르지만, 양쪽 끝 모두에 설치되고 버전도 맞아야 하며 사실상 저장소 하나당 클라이언트 하나로 설계되어 있습니다. 대용량 메일 스풀이고 양쪽 머신을 모두 직접 통제한다면 Borg를, 그 외에는 전부 restic을 쓰십시오.

백업 목적지에는 디스크가 얼마나 필요한가요?

이 가이드의 보존 사다리 — 일간 7개, 주간 5개, 월간 12개, 연간 2개 — 를 적용한 중복 제거 저장소라면, 서버 전체가 아니라 실제로 백업하는 데이터 크기의 대략 두세 배 정도를 예산으로 잡으십시오. 스냅샷 스물여섯 개가 곧 사본 스물여섯 개를 뜻하는 것은 아닙니다. 변경된 블록만 다시 저장되기 때문입니다. 실제 상태가 15GB 정도인 작은 사이트라면 80GB짜리 Starter에 몇 년치 이력을 여유 있게 담고도 남습니다.

두 번째 VPS를 두면 호스팅 비용이 두 배가 되지 않나요?

백업 목적지의 사양을 운영 서버와 똑같이 맞출 때만 그렇고, 애초에 그렇게 할 필요가 없습니다. 애플리케이션을 실행하지도, 트래픽을 처리하지도 않으므로 필요한 것은 CPU가 아니라 디스크입니다. $30짜리 운영 서버 옆에 $5짜리 Starter를 두면 청구서의 6분의 1 수준이고, 12개월 주기를 택하면 거기서 다시 50%가 줄어듭니다. 모든 것을 잃는 비용과 견주면 청구서에서 가장 저렴한 항목이며, 게다가 이 목적지는 복원 훈련용 연습 머신 역할까지 겸합니다.

저장소 비밀번호는 어디에 두어야 하나요?

그 자체가 다른 곳에 백업되어 있는 비밀번호 관리자, 또는 종이, 또는 둘 다에 두십시오 — 그리고 그 옆에는 저장소 주소와 정확한 복원 명령도 함께 적어 두십시오. 서버의 /etc에 있는 사본은 자동화를 위한 작업용 사본일 뿐, 결코 원본 기록이 아닙니다. 제대로 검증하십시오: 운영 서버도 백업 호스트도 아닌 머신에서, 비밀번호 관리자에 있는 것만 가지고 restic snapshots를 실행해 보십시오. 그 밖의 무언가가 더 필요하다면, 아직 복구 가능한 백업을 갖고 있지 않은 것입니다.

백업은 얼마나 자주 실행해야 하나요?

얼마만큼의 작업을 다시 해도 괜찮은지 자문해 보십시오. 대부분의 서버에는 매일 밤이 적당합니다: 잃어도 최대 하루치이고, 하룻밤 한 번의 실행이라 이해하기도 쉽습니다. 트래픽이 많은 데이터베이스라면 더 필요합니다 — 파일 전체 백업은 매일 밤으로 두되 데이터베이스만 시간마다 덤프하는 형태가 흔한 구성입니다. 그 이상으로 빈도를 올려 봤자, 같은 노력을 더 긴 보존 기간과 실제 복원 훈련에 쏟는 것만 못합니다. 진짜 위험은 바로 거기에 있기 때문입니다.

디스크가 LUKS로 암호화된 서버도 백업할 수 있나요?

가능하며, 이 둘은 중복이 아니라 서로를 보완합니다. LUKS는 머신 전원이 꺼져 있는 동안 디스크를 지켜 주고, 백업은 삭제와 손상, 머신을 완전히 잃어버리는 상황으로부터 지켜 줍니다. 마운트된 파일시스템을 암호화되지 않은 것과 똑같은 방식으로 백업하십시오 — 나가는 길에 restic이 다시 암호화하므로 저장소는 신뢰할 수 없는 스토리지 위에서도 안전합니다. 두 비밀은 진짜로 분리된 곳에 보관하십시오: LUKS 패스프레이즈를 오직 restic 저장소 안에만, 또는 restic 패스프레이즈를 오직 LUKS 볼륨 안에만 저장해 두는 것은 양쪽 모두를 안전 실패 상태로 만들어 버리는 고리입니다.

서버가 침해당하면 백업은 안전한가요?

몇 달 전에 내린 결정 하나에 전적으로 달려 있습니다. 운영 서버가 저장소에 대한 삭제 권한이 있는 인증 정보를 쥐고 있다면 안전하지 않습니다 — 공격자는 사고를 협상으로 바꿔 놓기 위해 가장 먼저 백업부터 찾아내 파괴합니다. 저장소가 append-only이거나, 백업 호스트가 pull해 오고 운영 서버가 백업 인증 정보를 아예 쥐고 있지 않다면, 이력은 살아남고 침입 이전 스냅샷으로 복원할 수 있습니다. 이것이 pull 설계를 지지하는 논거 전부이며, 필요해지기 전에 미리 택해 두어야 하는 이유입니다.

Deploy your offshore server.

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