把 AWS EBS Snapshot 下載到本地做離線備份

AWS EBS Snapshot 雖然可靠,但有時候還是會想要一份「離線」備份 —— 擔心帳號被盜、要做第三地備援、或是準備收掉某個 AWS 帳號的時候。問題是 EBS Snapshot 不是一個可以直接下載的檔案,它存在 S3 後端、格式是 AWS 內部的增量 block 儲存,要拿到本地需要透過 API 把每個 block 抓下來重組。

這篇記錄一下最簡單的做法。

為什麼要把 Snapshot 下載到本地

幾個常見情境:

  • 擔心 AWS 帳號被盜、誤刪,或決定關閉某個 AWS 帳號
  • 做第三地備援,符合 3-2-1 備份原則
  • 需要用取證工具離線分析 disk image
  • 單純想留一份可以隨時掛起來瀏覽的映像檔

三種常見做法

方法優點缺點
coldsnap(AWS Labs 官方工具)一行指令、直接產生 raw image需要編譯 Rust
建 volume → 掛 EC2 → rsync只抓需要的檔案、省流量要多開一台 EC2
AMI → export 到 S3 → 下載可得到 VMDK / VHD / OVA步驟多、成本高

對大部分人來說 coldsnap 最簡單,直接用 EBS direct API 把整顆 disk 抓成 .img 檔。

環境準備

# macOS
brew install rust
cargo install coldsnap

# Ubuntu / Debian
sudo apt install cargo
cargo install coldsnap

編譯大概 3–5 分鐘,裝完 binary 會放在 ~/.cargo/bin/coldsnap

步驟一:找出要下載的 Snapshot

aws ec2 describe-snapshots --owner-ids self \
  --region <REGION> \
  --query 'Snapshots[*].[SnapshotId,StartTime,VolumeSize,Description]' \
  --output table

輸出大概長這樣:

+----------------+----------------------+------+--------------------+
|  snap-xxxxxxx  |  2026-0x-0xT0x:xxZ   |  10  |  server-backup-... |
+----------------+----------------------+------+--------------------+

記下 SnapshotIdVolumeSize(GB),後面會用到。

步驟二:下載

AWS_PROFILE=<profile> AWS_REGION=<region> \
  coldsnap download snap-xxxxxxxxxxxx backup.img

執行時會顯示進度條,完成後會有一個跟 snapshot 同樣大小的 .img 檔。10GB 的 snapshot 在一般家用網路大約 10–30 分鐘。

步驟三:驗證與掛載

先確認檔案大小對得上:

$ ls -lh backup.img
-rw-r--r--  1 user  staff  10G  ...  backup.img

macOS

# 看一下 partition 結構
hdiutil imageinfo backup.img

# 掛起來(read-only 比較安全)
hdiutil attach -readonly backup.img

Linux

# 看 partition 位移
fdisk -l backup.img

# 用 loop device 掛
sudo losetup -Pf backup.img
sudo mount -o ro /dev/loop0p1 /mnt/backup

如果 snapshot 是 Linux 伺服器,檔案系統通常是 ext4 / xfs,macOS 要掛要用 ext4fuse 或直接在 Linux VM 裡掛比較方便。

幾個要注意的地方

  • IAM 權限:執行 coldsnap 的帳號需要 ebs:ListSnapshotBlocksebs:GetSnapshotBlock 這兩個權限,不是一般的 ec2:*。如果只有 EC2 權限會卡在第一步。
  • 資料外流成本:從 AWS 下載資料出 region 會有 egress 費用(約 $0.09/GB),10GB 大概 $0.9。
  • 磁碟空間:本地要準備至少跟 volume 一樣大的空間,coldsnap 產生的不是稀疏檔案。
  • 加密的 snapshot:如果 snapshot 用 KMS 加密,執行帳號要有對應 KMS key 的 Decrypt 權限,否則會下載到一堆亂碼。

還原回去

要把離線 image 還原成 EBS snapshot 很簡單,反過來就好:

coldsnap upload backup.img --description "restored from local backup"

上傳完會得到一個新的 snap-id,可以直接拿來建 volume 掛到 EC2。

小結

整個流程其實就三步:裝 coldsnap → download → 掛起來驗證。適合拿來做定期離線備份、或是交接 / 關閉 AWS 帳號前的最後一份保險。

如果 snapshot 很多,可以寫一個迴圈把 describe-snapshots 的結果餵給 coldsnap download,一次把整個帳號的備份打包帶走。