LUKSで暗号化した外部メディアを秘密鍵バックアップに使う

LUKSで暗号化した外部メディアを秘密鍵バックアップに使う

秘密鍵の backup は、単に別 directory へ copy しても十分ではない。

同じ workstation 上に平文 copy を増やすと、disk 故障や誤削除には少し効くが、侵害時の影響範囲はあまり変わらない。普段は unplug しておく外部メディアを暗号化し、必要な時だけ mount する方が扱いやすい。

ここでは Linux で USB メモリや SD カードを LUKS2 化し、小さい秘密ファイルを保存する手順を整理する。

方針

  • media 全体を LUKS2 にする
  • backup 対象は暗号化済み filesystem を mount してから copy する
  • plain filesystem へ一時 copy してから暗号化しない
  • backup 後は fingerprint や hash で内容を確認する
  • mount 解除後に LUKS mapper も close する
  • media の label、serial、保管場所、passphrase は公開メモに書かない

対象デバイスの確認

cryptsetup luksFormatmkfswipefs は破壊的である。まず read-only な確認だけを行う。

lsblk -o NAME,PATH,TRAN,MODEL,SIZE,FSTYPE,LABEL,UUID,MOUNTPOINTS
udevadm info --query=property --name=/dev/sdX | grep -E '^(ID_BUS=|ID_MODEL=|ID_SERIAL=|ID_FS_TYPE=|ID_FS_LABEL=)'

見る点:

  • 対象が本当に USB / SD などの外部メディアか
  • size と model が想定通りか
  • 既存 filesystem や ISO image が残っていないか
  • mount されていないか
  • /dev/sdX が接続し直しで変わる可能性を織り込んでいるか

既存の ISO image、partition、writable 領域がある場合、LUKS 化で消える。必要なら先に別媒体へ退避する。

LUKS2で初期化する

以下は media 全体を LUKS container にする例である。partition を切らず、/dev/sdX 全体を使う。

device=/dev/sdX
mapper=secret-backup
mount_root=/mnt/secret-backup

lsblk -o NAME,PATH,TRAN,MODEL,SIZE,FSTYPE,LABEL,UUID,MOUNTPOINTS "$device"

対象を確認してから初期化する。

sudo cryptsetup luksFormat --type luks2 "$device"
sudo cryptsetup open "$device" "$mapper"
sudo mkfs.ext4 -F "/dev/mapper/$mapper"
sudo install -d -m 0700 "$mount_root"
sudo mount "/dev/mapper/$mapper" "$mount_root"
sudo chmod 0700 "$mount_root"

passphrase は shell history やログに残さない。初期化時は cryptsetup の対話入力に任せるのが単純である。

backupする

例として、秘密鍵と公開鍵を保存し、秘密鍵から公開鍵を導出して fingerprint を確認する。

backup_dir="$mount_root/ssh-ca-backup-$(date -u +%Y%m%d)"
install -d -m 0700 "$backup_dir"

install -m 0600 ~/.ssh/example_ca_ed25519 "$backup_dir/example_ca_ed25519"
install -m 0644 ~/.ssh/example_ca_ed25519.pub "$backup_dir/example_ca_ed25519.pub"

ssh-keygen -y -f "$backup_dir/example_ca_ed25519" > "$backup_dir/example_ca_ed25519.derived.pub"
ssh-keygen -lf "$backup_dir/example_ca_ed25519.derived.pub"
ssh-keygen -lf ~/.ssh/example_ca_ed25519.pub

期待する fingerprint と一致することを確認する。鍵に passphrase がある場合は ssh-keygen -y の時点で入力が必要になる。

普通のファイルなら sha256sum を使う。

sha256sum "$backup_dir/important-file"
sha256sum /path/to/source/important-file

closeする

copy と確認が終わったら、filesystem と LUKS mapper の両方を閉じる。

sync
sudo umount "$mount_root"
sudo cryptsetup luksClose "$mapper"

閉じたことを確認する。

lsblk -o NAME,PATH,TRAN,MODEL,SIZE,FSTYPE,LABEL,UUID,MOUNTPOINTS "$device"
sudo cryptsetup status "$mapper" || true

/dev/mapper/<mapper> が inactive ならよい。

復号できることを確認する

backup 直後に passphrase test だけ通しておく。

sudo cryptsetup open --test-passphrase "$device"

実際に中身まで読む確認をする場合:

sudo cryptsetup open "$device" "$mapper"
sudo mount "/dev/mapper/$mapper" "$mount_root"
find "$mount_root" -maxdepth 2 -type f -print
sudo umount "$mount_root"
sudo cryptsetup luksClose "$mapper"

年 1 回程度は、別の Linux 環境でも unlock できるか確認しておくとよい。backup だけ作って復元確認をしないと、passphrase、keyboard layout、必要 command、媒体劣化のどれで詰まるか分からない。

注意点

LUKS media は、開いて mount している間は通常の filesystem と同じである。backup 後は unplug / unmount して offline にする。

password manager は passphrase の保管には使えるが、秘密鍵本体の primary backup 先にするかは別に判断する。復号できる主体を増やすほど attack surface は広がる。

SOPS や age を使う場合も同じで、recipient を増やすと復号できる主体が増える。自動化用 recipient を入れると、自動化からも復号可能になる。小さい秘密鍵を offline backup するだけなら、暗号化外部メディアの方が単純なことがある。