boot パーティションの暗号化
luks2 で ルートパーティションの暗号化ができる。
LUKSを使っても /boot
が暗号化できずに残ってしまう。これを解決したい。
ただし、これをやってしまうと、grubでluks1を使うためにリモートアンロックはできない。そして問題がある。uEFIブートの場合、 /boot/efi
は暗号化実施できずに残ってしまう。
それらをまとめて解決するにはTPMデバイスの恩恵に預かるしかないと思う。
参考サイトの流れをすこしアレンジして実施した。
順番
いきなり、全部を一気にやるのは不可能なので、順番にやっていきます。
- rootFSを暗号化
- シリアルコンソールを使う。
- rootFSをSSHでリモートアンロック
- boot にroot鍵を設置
- boot を暗号化
- boot のリモートアンロック
rootfs の暗号化
rootfs を暗号化ディスクにする。
初回インストール時に、やってしまうのが楽だ。
どうしてもインストール後のシステムを移行したときは、次のような感じで・・・
cryptsetup luksFormat /dev/sdG cruptsetup open /dev/sdG dm-0 ddrescue ddrescue /dev/sdA /dev/mappper/dm-0 mount /dev/mappper/dm-0 /mnt mount ... # pts dev など chroot /mnt update-grub update-initramfs
rootfs のリモートアンロック手段の確保
rootfs の暗号化の解除はdropbearによるSSH解除が手段がリモート経由のアンロックでとり得るベターな手段だと思う。万が一dropbearの設定に失敗を想定し、シリアルコンソールを使って解除する手段を作業時に確保していくと良い。
ssh によるリモートアンロック
以前やっている https://takuya-1st.hatenablog.jp/entry/2021/11/17/090809
シリアルコンソールを有効化
以前やっている。
https://takuya-1st.hatenablog.jp/entry/2020/01/30/013845
/etc/default/grub
GRUB_TERMINAL="serial console" GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
有効化
sudo update-grub
Raspiとつないで、シリアルコンソールをリモートから閲覧できることを確認する。
シリアルコンソールを使って総当りが可能なので、物理的にPCを強奪された場合に総当りでrootログイン試行されてしまう。作業が終わったらシリアル通信を無効にしておく。または、「一定回数の失敗でロックする」または、rootパスワードを無効化しておく。
SSHのリモートアンロック
SSHでLUKSをリモートからアンロックする。これも以前やっている。
https://takuya-1st.hatenablog.jp/entry/2021/11/17/090809
/boot に鍵を配置
rootfsの暗号化解除 initramfs で行う。initramfsが配置のは/boot。なので/bootに鍵を配置わけだ。 /boot が非暗号化だと、/bootに鍵が存在するため、ディスクを強奪・USBブートされると読み込みが可能になる。鍵の危殆化は免れない。
しかし、まずは、bootのinitramfs に鍵配置する。その後、bootを暗号化デバイスにする。
rootfsアンロック鍵を生成し登録
鍵を作成
mkdir -p -m0000 /etc/keys umask 0777 && dd if=/dev/random of=/etc/keys/root.key bs=1024 count=4 conv=fsync
鍵を登録前に、登録状況を見る。
cryptsetup luksDump /dev/nvme0xp6
鍵を登録
cryptsetup luksAddKey /dev/mapper/my-root /etc/keys/root.key
keyslot に鍵が配置されたことを確認
cryptsetup luksDump /dev/nvme0xp6
crypttabに鍵を使うように登録
/etc/crypttab
dm_crypt-0 UUID=XXXX-XXXX /etc/keys/root.key discard,luks,keyslot=0
keyslot は0,1,2,3,4,5 の順に試されるので、0 番目に配置するほうが起動が早い。
initramfsに鍵を使うように登録
登録した鍵をinitramfsが使うように登録。
/etc/cryptsetup-initramfs/conf-hook
"KEYFILE_PATTERN=\"/etc/keys/*.key\"" >> /etc/cryptsetup-initramfs/conf-hook # echo UMASK=0077 >> /etc/initramfs-tools/initramfs.conf
ここで、登録することで、initramfsを作成時にKEYFILE_PATTERNを見つけて、KEYFILE_PATTERNにマッチする鍵を収集する。収集した鍵がinitramfs生成時にフィアルに含めてくれる。
initramfs の生成
update-initramfs -u
生成されたinitamfsに鍵があることを確認
takuya:~$ sudo lsinitramfs /initrd.img | grep cryptroot cryptroot cryptroot/crypttab cryptroot/keyfiles cryptroot/keyfiles/dm_crypt-0.key
私の環境では、crypttab に記載したファイル名とDM名で鍵が登録されていた。
再起動する。
これで、再起動すると、initramfs に鍵が含まれるので、暗号化ディスクでも、そのままbootしてきます。
UEFI → /boot → cryptsetup → rootfs
boot に入れた鍵を使って rootfsは暗号化解除されます。そのため、パスフレーズを入力しなくても起動するってわけです。
このままだと、bootを見られると鍵を見つけられてしまいます。
boot を暗号化する。
boot のパーティションを暗号化します。
もし、bootパーティションを別パパーティションにしてない場合は、別パーティションを作ります。
/boot を暗号化する。
リードオンリーにしとく(トラブル回避)
mount -oremount,ro /boot
tar -C /boot --acls --xattrs --one-file-system -cf /tmp/boot.tar
/boot が別パーティションになってない場合
パーティション作成(100Mくらいで十分です)
gdisk /dev/nvmeXXX
luks にする
cryptsetup luksFormat --type luks1 /dev/nvmeXXp3
フォーマット
mkfs.ext4 /dev/nvmeXXp3
blkid を確認
sudo bllid /dev/nvmeXXp3
fstab に記載。
UUID=XXXX /boot ext4 defaults,noatime,nodiratime,discard 0 2
mountして、bootの中身を移動
mount UUID=XXXX /mnt rsync -av /boot /mnt mv /boot /boot.old mkdir /boot
/boot をマウントして確認
mount -a # fstabを反映 ## 比較 md5sum /boot/* md5sum /boot.old/*
アンマウント
sudo umount /mnt sudo umount /boot/efi sudo umount /boot
再マウント
mount UUID=XXXX /boot
grub を更新
念の為
sudo update-grub sudo update-initramfs -c -t -k all ## または # sudo update-initramfs -u
起動する
起動すると grub メニューで、パスワードを訊かれる。
ssh リモートアンロックは、initramfs のdropbearなのでできません。
シリアルコンソールには何も出力されなかった。grub だからできると思ったんですけどねぇ。
ブート時にVGAにコンソールが出るだけでした。grub のシリアルコンソールにプロンプトがなぜ出ないのかは今後調べる。
結論
boot パーティションの暗号化ロックは、とても安全になるが、リモートからアンロック手段が失わえます。なので、ノートPCなどでは良いが、常時起動したりリモートから使うことが多いデスクトップPCでは利用は難しいんではないかと思われる。bootに鍵を置くよりSSHリモートアンロックですね。