kazeno memo

メモとか

Debian Busterで(/bootを含んだ)フルディスク暗号化

元ネタ: Full disk encryption, including /boot: Unlocking LUKS devices from GRUB

Debianなど多くのLinuxディストリビューションでは、LVM on LUKS構成でインストールしても /boot パーティションは暗号化されません。

一方、GRUB2は暗号化されたLUKSパーティションのロックを解除できます。(ただし、LUKSバージョン1のみ)

インストール

インストーラを用いて、以下の構成でインストールします。

# lsblk -o NAME,FSTYPE,MOUNTPOINT /dev/sda
NAME                    FSTYPE      MOUNTPOINT
sda
├─sda1                  ext2        /boot
└─sda2                  crypto_LUKS
  └─root_crypt          LVM2_member
    ├─root_crypt--root  ext4        /
    └─root_crypt--swap  swap        [SWAP]

こちらの記事を参考にインストールしました。

Full disk encryption (including /boot) on Ubuntu

/boot パーティションの暗号化

/boot パーティションを暗号化する方法は2つあります。

後者はパーティションを1つにまとめることが出来るというメリットはありますが、ルートパーティションでLUKS2の機能を使うことはできません。

ここでは前者の方法で /boot パーティションを暗号化します。

  1. /boot を読み取り専用で再マウント
    # mount -oremount,ro /boot
  2. /boot の中身を別の場所へ移動
    # cd ~
    # install -m600 /dev/null /tmp/boot.tar
    # tar -C /boot --acls --xattrs --one-file-system -cf /tmp/boot.tar .
    # umount /boot
  3. 必要に応じてランダムデータで上書き
    # dd if=/dev/urandom of=/dev/sda1 bs=1M
    ddstatus=progress オプションを追加すると進捗が表示されます。
  4. LUKS1でフォーマット
    # cryptsetup luksFormat --type luks1 /dev/sda1
    Are you sure? (Type uppercase yes): と聞かれるので、大文字で YES と入力します。次に、パスフレーズを入力します。
  5. /boot/dev/sda1 を追加し、マウント
    # uuid="$(blkid -o value -s UUID /dev/sda1)"
    # echo "boot UUID=$uuid none luks" | tee -a /etc/crypttab
    # cryptdisks_start boot
  6. ext2でフォーマット
    # uuid="$(grep /boot /etc/fstab | grep UUID | awk '{print $1}' | awk -F'[=]' '{print $2}')"
    # mkfs.ext2 -m0 -U $uuid /dev/mapper/boot
  7. /boot をマウントして、中身を戻す
    # mount -v /boot
    # tar -C /boot --acls --xattrs -xf /tmp/boot.tar

GRUBの設定

# echo "GRUB_ENABLE_CRYPTODISK=y" >> /etc/default/grub
# update-grub
# grub-install /dev/sda

パスワード入力を省略

GRUBによって sda1 のロックが解除されますが、initramfs ステージで sda2(ルートデバイス) のパスワードを入力する必要があります。その後 sda1 のパスワードをもう一度入力する必要があります。

これは面倒なので、LUKSパーティションにキーファイルを追加して、パスワード入力をスキップします。

キーファイルは initramfs にコピーすることになります。 initramfs は起動時、RAMに平文でキーファイルを展開します。セキュリティ上の問題があるように思うかもしれませんが、LUKSもボリュームキーをRAMに保持しているので脅威モデルは同じです。

  1. キーファイルの作成
    # mkdir -p -m0000 /etc/keys
    # ( umask 0777 && dd if=/dev/random of=/etc/keys/boot.key bs=1024 count=4 conv=fsync)
    # ( umask 0777 && dd if=/dev/random of=/etc/keys/root.key bs=1024 count=4 conv=fsync)
    キーの生成が進まない場合、エントロピーが枯渇している場合があります。 その場合、 rng-toolshaveged をインストールすることで改善します。
    キーの生成に /dev/urandom を使用することは推奨されていません。
  2. キースロットに追加
    # cryptsetup luksAddKey /dev/sda1 /etc/keys/boot.key
    # cryptsetup luksAddKey /dev/sda2 /etc/keys/root.key
    キースロットに追加されていることを確認する
    # cryptsetup luksDump /dev/sda1 | grep "^Key Slot"
    Key Slot 0: ENABLED
    Key Slot 1: ENABLED
    Key Slot 2: DISABLED
    Key Slot 3: DISABLED
    Key Slot 4: DISABLED
    Key Slot 5: DISABLED
    Key Slot 6: DISABLED
    Key Slot 7: DISABLED
    スロット1にキーファイルが追加されていることが分かります。
  3. /etc/crypttab にキーファイルのパスを追加 sda1sda2 両方設定します。
    root_crypt UUID=... /etc/keys/root.key luks,key-slot=1
    上記のように、3行目をキーファイルのパスに、4行目に key-slot オプションを追加します。 LUKSはスロット0から順番に実行します。 key-slot オプションは指定したスロット以外をスキップするので、起動時間が短縮されます。
  4. initramfs の設定
    # echo "KEYFILE_PATTERN=\"/etc/keys/*.key\"" >> /etc/cryptsetup-initramfs/conf-hook
    # echo UMASK=0077 >> /etc/initramfs-tools/initramfs.conf
  5. initramfs の再構成と確認
    # update-initramfs -u
    initramfsにキーファイルが存在するのか確認
    # lsinitramfs /initrd.img | grep "*.key"

これで、起動時に一度 sda1 のパスワードを入力するだけで起動するはずです。

トラブルシューティング

設定が誤っていて起動できない場合、DebianのLiveイメージなどを立ち上げてchrootすることで、GRUBやinitramfsを再構成できます。

  1. /mnt にマウント
    # cryptsetup open /dev/sda1 boot
    # cryptsetup open /dev/sda2 root_crypt
    # lvchange -ay root_crypt
    # mount /dev/root_crypt/root /mnt
    # mount /dev/mapper/boot /mnt/boot
    # mount --rbind /dev /mnt/dev
    # mount --rbind /sys /mnt/sys
    # mount -t proc /proc /mnt/proc
  2. /mntchroot する
    # chroot /mnt /bin/bash
    これで update-grubupdate-initramfs -u を実行できます。 exitchroot から抜けられます。
  3. アンマウント
    # umount -R /mnt
    # lvchange -an root_crypt
    # cryptsetup close root_crypt
    # cryptsetup close boot

Links

Full disk encryption, including /boot: Unlocking LUKS devices from GRUB

Full disk encryption (including /boot) on Ubuntu

Real full disk encryption using GRUB on Debian GNU/Linux for BIOS