元ネタ: 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
パーティションを暗号化します。
-
/boot
を読み取り専用で再マウント# mount -oremount,ro /boot
-
/boot
の中身を別の場所へ移動# cd ~ # install -m600 /dev/null /tmp/boot.tar # tar -C /boot --acls --xattrs --one-file-system -cf /tmp/boot.tar . # umount /boot
-
必要に応じてランダムデータで上書き
# dd if=/dev/urandom of=/dev/sda1 bs=1M
dd
にstatus=progress
オプションを追加すると進捗が表示されます。 -
LUKS1でフォーマット
# cryptsetup luksFormat --type luks1 /dev/sda1
Are you sure? (Type uppercase yes):
と聞かれるので、大文字でYES
と入力します。次に、パスフレーズを入力します。 -
/boot
に/dev/sda1
を追加し、マウント# uuid="$(blkid -o value -s UUID /dev/sda1)" # echo "boot UUID=$uuid none luks" | tee -a /etc/crypttab # cryptdisks_start boot
-
ext2でフォーマット
# uuid="$(grep /boot /etc/fstab | grep UUID | awk '{print $1}' | awk -F'[=]' '{print $2}')" # mkfs.ext2 -m0 -U $uuid /dev/mapper/boot
-
/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に保持しているので脅威モデルは同じです。
-
キーファイルの作成
# 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-tools
やhaveged
をインストールすることで改善します。
キーの生成に/dev/urandom
を使用することは推奨されていません。 -
キースロットに追加
# 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にキーファイルが追加されていることが分かります。 -
/etc/crypttab
にキーファイルのパスを追加sda1
とsda2
両方設定します。root_crypt UUID=... /etc/keys/root.key luks,key-slot=1
上記のように、3行目をキーファイルのパスに、4行目にkey-slot
オプションを追加します。 LUKSはスロット0から順番に実行します。key-slot
オプションは指定したスロット以外をスキップするので、起動時間が短縮されます。 -
initramfs
の設定# echo "KEYFILE_PATTERN=\"/etc/keys/*.key\"" >> /etc/cryptsetup-initramfs/conf-hook # echo UMASK=0077 >> /etc/initramfs-tools/initramfs.conf
-
initramfs
の再構成と確認# update-initramfs -u
initramfsにキーファイルが存在するのか確認# lsinitramfs /initrd.img | grep "*.key"
これで、起動時に一度 sda1
のパスワードを入力するだけで起動するはずです。
トラブルシューティング
設定が誤っていて起動できない場合、DebianのLiveイメージなどを立ち上げてchrootすることで、GRUBやinitramfsを再構成できます。
-
/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
-
/mnt
に chroot する# chroot /mnt /bin/bash
これでupdate-grub
やupdate-initramfs -u
を実行できます。exit
で chroot から抜けられます。 -
アンマウント
# 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