rootfs全体をLUKSで暗号化し、起動時に手動 / 自動でロック解除する方法について記載する。
自動でロック解除する場合は鍵ファイルを使用し、鍵ファイルはbootfsのinitramfsに平文で埋め込む。
■参考資料
- cryptsetup - GitLab
- Debian Cryptsetup Initramfs integration - Debian Cryptsetup docs
- dm-crypt/システム設定 - ArchWiki
- dm-crypt/システム全体の暗号化 - ArchWiki
■作業環境
- Raspberry Pi 5
- Raspberry Pi OS Lite(64bit)
- Ubuntu 24.04(VirtualBox)
■cryptsetupのインストール(ラズパイ)
Raspberry Pi Imagerでイメージを書き込んだmicroSDカードをラズパイに挿入し、cryptsetupをインストールする。暗号化したrootfsで起動するのに必要なinitramfs-tools, busyboxは最初からラズパイにインストール済。
$ sudo apt update
$ sudo apt install -y cryptsetup-initramfs
■rootfsを暗号化する(Ubuntu)
microSDカードをラズパイから抜去し、Ubuntu側のUSBカードリーダーに挿入する。
- SDカードのデバイス名は都度変わるため、確認し読み替える(sda, sdbなど)
- 暗号化するrootfsのPARTUUIDは後で必要になるためメモしておく
$ lsblk
sdb 8:16 1 14.4G 0 disk
├─sdb1 8:17 1 512M 0 part /media/【ユーザー名】/bootfs
└─sdb2 8:18 1 13.9G 0 part /media/【ユーザー名】/rootfs
$ sudo blkid
/dev/sdb2: LABEL="rootfs" ... TYPE="ext4" PARTUUID="e44a4b6b-02"
暗号化する前にrootfsの中身を退避する。
$ sudo mkdir /mnt/orig
$ sudo rsync -AHXaxvc --delete /media/【ユーザー名】/rootfs/ /mnt/orig/
$ umount /dev/sdb2
暗号化する領域に残っている古いデータを消去する。
# ファイルシステムを素早く消去できるが、データは削除されない(開発時用)
$ sudo wipefs -af /dev/sdb2
# 古いデータが全削除されるが時間がかかる
$ sudo shred -n 1 -v /dev/sdb2
rootfsをLUKSで暗号化する。
$ sudo cryptsetup luksFormat --type luks2 /dev/sdb2
WARNING!
========
This will overwrite data on /dev/sdb2 irrevocably.
Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for /dev/sdb2: (パスフレーズを入力)
パスフレーズを確認: (パスフレーズを再入力)
暗号化したデバイスを /dev/mapper/cryptroot にマップし、ファイルシステムを作成する。
$ sudo cryptsetup luksOpen /dev/sdb2 cryptroot
Enter passphrase for /dev/sdb2: (パスフレーズを入力)
$ sudo mke2fs -t ext4 /dev/mapper/cryptroot
mke2fs 1.47.0 (5-Feb-2023)
Creating filesystem with 3645440 4k blocks and 912128 inodes
Filesystem UUID: 7dc57e20-6732-425c-b6e4-91242f0a5a10
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208
Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done
/mnt/cryptroot/にマウントし、退避したrootfsのファイルを書き込む。
$ sudo mkdir /mnt/cryptroot
$ sudo mount /dev/mapper/cryptroot /mnt/cryptroot/
$ sudo rsync -AHXaxv /mnt/orig/ /mnt/cryptroot/
ラズパイ起動時に暗号化したrootfsを開くため、fstab, crypttab, cmdline.txtを編集する。
$ sudo nano /mnt/cryptroot/etc/fstab
proc /proc proc defaults 0 0
PARTUUID=b2c70024-01 /boot/firmware vfat defaults 0 2
#下記を変更する
#PARTUUID=b2c70024-02 / ext4 defaults,noatime 0 1 # コメントアウト
/dev/mapper/cryptroot / ext4 defaults,noatime 0 1 # 追加
$ sudo nano /mnt/cryptroot/etc/crypttab
# 下記を追加
# <target name> <source device> <key file> <options>
cryptroot PARTUUID=e44a4b6b-02 none luks
$ nano /media/【ユーザー名】/bootfs/cmdline.txt
#変更前
#console=serial0,115200 console=tty1 root=PARTUUID=b2c70024-02 rootfstype=ext4 fsck.repair=yes rootwait cfg80211.ieee80211_regdom=JP
#変更後(root=を変更)
console=serial0,115200 console=tty1 root=/dev/mapper/cryptroot rootfstype=ext4 fsck.repair=yes rootwait cfg80211.ieee80211_regdom=JP
■initramfsを更新する(ラズパイ)
raspberrypi - LUKS Disk Encryption on Raspberry Pi 4 and Ubuntu Desktop 20.10 - Ask Ubuntu
microSDをUSBカードリーダーから抜去し、ラズパイに挿入する。
この時点ではinitramfsが更新されていないため、電源投入しても暗号化したパーティションのロックが解除されず、Raspberry Pi OSが起動しない。
そのため、Raspberry Pi OSの起動する前のinitramfsでロックを手動解除する。
(initramfs) cryptsetup luksOpen /dev/mmcblk0p2 cryptroot
パスフレーズを入力
(initramfs) exit
Raspberry Pi OSの起動後、initramfsを更新する。
$ sudo update-initramfs -u
update-initramfs: Generating /boot/initrd.img-6.6.20+rpt-rpi-v8
'/boot/initrd.img-6.6.20+rpt-rpi-v8' -> '/boot/firmware/initramfs8'
update-initramfs: Generating /boot/initrd.img-6.6.20+rpt-rpi-2712
'/boot/initrd.img-6.6.20+rpt-rpi-2712' -> '/boot/firmware/initramfs_2712'
起動時にパスフレーズを要求されたらOK。
$ sudo reboot
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
mmcblk0 179:0 0 14.4G 0 disk
├─mmcblk0p1 179:1 0 512M 0 part /boot/firmware
└─mmcblk0p2 179:2 0 13.9G 0 part
└─cryptroot 254:0 0 13.9G 0 crypt /
■キーファイルを埋め込む場合(ラズパイ)
起動時に暗号化されたパーティションのロックを自動で解除する場合は以下を実施する。
下記を参考にしました。
$ sudo nano /etc/crypttab
# noneを変更し、鍵ファイルを指定する
cryptroot PARTUUID=e44a4b6b-02 /etc/keys/mmcblk0p2-crypt.key luks
$ sudo mkdir /etc/keys
$ sudo chmod go-rwx /etc/keys/
$ sudo dd if=/dev/random of=/etc/keys/mmcblk0p2-crypt.key bs=1k count=4
$ sudo chmod go-rw /etc/keys/mmcblk0p2-crypt.key
$ sudo cryptsetup luksAddKey /dev/mmcblk0p2 /etc/keys/mmcblk0p2-crypt.key
Enter any existing passphrase:(パスフレーズを入力)
$ sudo nano /etc/cryptsetup-initramfs/conf-hook
KEYFILE_PATTERN="/etc/keys/*.key"
$ sudo nano /etc/initramfs-tools/initramfs.conf
UMASK=0077
$ sudo update-initramfs -u
update-initramfs: Generating /boot/initrd.img-6.6.20+rpt-rpi-v8
'/boot/initrd.img-6.6.20+rpt-rpi-v8' -> '/boot/firmware/initramfs8'
update-initramfs: Generating /boot/initrd.img-6.6.20+rpt-rpi-2712
'/boot/initrd.img-6.6.20+rpt-rpi-2712' -> '/boot/firmware/initramfs_2712'
再起動時に、パスフレーズを要求されずOSが立ち上がればOK。