メインの開発マシンには Dell XPS 13 9380 に Ubuntu 19.04 (Disco Dingo)
をインストールし Ubuntu 19.10 (Eoan Ermine) へ apt-get dist-upgrade
したものを使用していました。
1年近く使っていると不要になったパッケージや設定ファイル、キャッシュが残ったままで本来必要だったものってなんだっけ?状態になっていました。
Focal Fossa がリリースされたのもあって、これを機に Ubuntu 20.04 (Focal Fossa) を真っ更な状態からインストールします。
Disco Dingo をインストールしたときにルートパーティションとは別に /var
パーティションに 15 GB 割り当てていました。
この /var
が意外と容量を取りまして、docker image や KVM image はデフォルトで /var 内に置くようになっており、
すぐに容量いっぱいになったので一時的 image を home directory に保存するよう設定していました。
マシン依存で docker や KVM の設定を書き換えたり、細かいとこではログファイルの格納場所を変更する必要がでてくる可能性もあって、
その都度設定ファイルを書き直す必要が出てくるのではという不安がありました。
なので、今回は LVM でパーティショニングしインストール後でもパーティションサイズを変更できるようにします。
万一マシンを紛失した場合のことを考えて、LUKS でディスク暗号化もします。 どういった構成にするのか、ディスク暗号化の方法等は ArchWiki(dm-crypt/Encrypting an entire system - ArchWiki)がとても参考になりました。
この記事では Ubuntu 20.04 (Focal Fossa) を LVM on LUKS でインストールする方法を紹介します。 LVM や UEFI, LUKS とは、ということは別の記事で紹介したいと思います。
また、Ubuntu を Full Disk Encryption でインストールする方法については Ubuntu の公式 Wiki (Full_Disk_Encryption_Howto_2019 - Community Help Wiki)が参考になりました。 今回紹介する方法はこちらを基本に自分用環境に少しカスタマイズしている、という認識で読んでもらえたらと思います。
やること
- Ubuntu 20.04 (Focal Fossa) のインストール
- LVM on LUKS +
/boot
暗号化 - UEFI Boot のみで、 Legacy Boot は非対応
- GPT + EFI-SP
- KVM + libvirt 検証環境で動作確認
最終目的は XPS 13 9380 にインストールすることですが、まずは検証環境でインストールして動作確認した後に XPS 13 9380 にインストールしますので、KVM + libvirt 環境での紹介になります。
実機でも基本的なやり方は変わらずインストールできました。 LVM の構成やデバイス名、割当サイズが変わるくらいでした。
パーティション構成
+----------------------+-----------------------+-------------------------------+ | EFI System Partition | Boot Partition | Linux LUKS Partition | | (ef00) | (8300) | (8309) | | | | | | /dev/vda1 | /dev/vda2 | /dev/vda3 | | | | | | unencrypted | encrypted | encrypted | | +-------------------------------------------------------+ | | /dev/mapper/luks_boot | /dev/mapper/luks_vda3 | LUKS Mapping | +---------------------------------------+---------------+ | | | /dev/vg1/swap | /dev/vg1/root | LVM | | +-------------------------------+ | /boot/efi | /boot | swap | / | Mount Point +----------------------+-----------------------+---------------+---------------+
大きく3つのパーティションに分けます。
/dev/vda1
: UEFI boot 用のパーティション/dev/vda2
: 初期 RAM ディスクや Linux カーネルの実行ファイルを格納する boot パーティション/dev/vda3
: LVM 用で、/
や/home
をマウントポイントとするパーティション
/dev/vda2
, /dev/vda3
を暗号化し、dm-crypt でマッピングを作成します。
更にルートパーティション用のマッピング(/dev/mapper/luks_vda3
)を
LVM の PV とし、VG を作成し swap
, /
マウントポイント用の LV を作成します。
上記の構成でインストールしていきます。
ちなみに実機インストールでは swap
, /
に加えて /var
, /home
用の LV を追加しました。
ここは各々の構成に合わせて設定すれば良いと思います。
インストール方法
KVM + libvirt 検証 VM を作るところからインストールまで紹介します。
※ 既存環境を破壊するコマンドが出てきますので、各々の環境に合わせて必要なコマンドを実行してください。
前準備
Desktop installer ISO image を公式(Ubuntu 20.04 LTS (Focal Fossa))からダウンロードします。
VM を用意します。
設定例
※ UEFI Boot mode で起動させるために Customize configuration before install にチェックを入れて Overvier > Details > Firmware: UEFI x86_64... を選択する必要があります
この画面が開けたら準備完了です。
インストール
コマンドをまとめたものと実行・出力例は コマンド実行例 に記載しておきます。 どうしてもうまくインストールできない、コマンドの出力が合わない等あればこちらを参考にしてください。
パーティショニング
Installation type で Erase disk and install Ubuntu を選択することで、パーティション設定とディスク暗号化の設定をおまかせすることができます。 この GUI からのインストールだとパーティションのカスタマイズと LVM の設定はできないので、インストール前に手動でパーティション設定・ディスク暗号化の設定を行います。
Try Ubuntu ボタンをクリックしてターミナルを開きます。
root 権限が必要なコマンドばかり実行するので root になります。
sudo -i
暗号化デバイスを open するのに必要なパスフレーズとデバイス名を後で使い回せるよう環境変数に入れておきます。
変数でもいいのですが、後々 chroot
して引き継げるよう環境変数にしてます。
DEV
, DM
ではインストール先デバイスを指定します。
read -sr PASSPHRASE export PASSPHRASE export DEV="/dev/vda" export DM="vda"
パーティション全削除して新たにパーティションを切ります。 同じデバイスに他 OS がある場合は注意してください。 ここでは必要最小限だけパーティションを切ります。
sgdisk
コマンドでパーティションを作成しますが、GPT パーティションが作れればいいので
fdisk
, gparted
等でも作成できると思います。
sgdisk --zap-all "${DEV}" sgdisk --new=1:0:+100M --change-name=1:"EFI System" --typecode=1:ef00 "${DEV}" sgdisk --new=2:0:+500M --change-name=2:"Boot" --typecode=2:8300 "${DEV}" sgdisk --new=3:0:0 --change-name=3:"Linux LUKS" --typecode=3:8309 "${DEV}" sgdisk --print "${DEV}"
LUKS の初期化をして上記で作成したパーティションの暗号化をします。 luks2 は未対応です。
--key-file, -d
はファイルからパスフレーズを読み込むオプションです。
対話モードだと都度入力するのが大変なので、 -
を指定して標準入力から読み込むようにします。
--batch-mode, -q
では対話モードで確認をしないようにします。
printf %s "${PASSPHRASE}" | cryptsetup luksFormat --type=luks1 --key-file - --batch-mode "${DEV}2" printf %s "${PASSPHRASE}" | cryptsetup luksFormat --type=luks1 --key-file - --batch-mode "${DEV}3"
初期化された LUKS パーティションを open します。
LUKS デバイスとのマッピングを作成して /dev/mapper
で使えるようにします。
printf %s "${PASSPHRASE}" | cryptsetup open -d - "${DEV}2" luks_boot printf %s "${PASSPHRASE}" | cryptsetup open -d - "${DEV}3" "luks_${DM}3"
マッピングできているか確認します。
luks_boot
, luks_vda3
があれば問題なくマウントされています。
ls -l /dev/mapper/ control luks_boot luks_vda3
作成したパーティションをフォーマットします。
EFI boot パーティション(/dev/vda1
)は VFAT 32 bit でフォーマットします。
EFI boot パーティションは USB ドライブ等の removable disk からでもブートできるようにするため FAT12 または FAT16, FAT32 でフォーマットされています。
mkfs.ext4 -L boot /dev/mapper/luks_boot mkfs.vfat -F 32 -n EFI-SP "${DEV}1"
LVM の PV, VG を作成します。
pvcreate /dev/mapper/"luks_${DM}3" vgcreate vg1 /dev/mapper/"luks_${DM}3"
LVM の LV を作成します。
lvcreate -L 4G -n swap vg1 lvcreate -l 100%FREE -n root vg1
以上まで問題なければ Install Ubuntu 20.04 LTS を開いてインストールを開始します。
Ubuntu インストール
設定例
作成されたパーティションをにマウントポイントを割り当ててフォーマットします
パーティションへの設定が終わったら Device for boot loader installation
に /dev/vda
を選択して Install Now
ボタンをクリックします。
GRUB でディスク暗号化を有効
ユーザ設定後、パッケージインストールや GRUB の設定が自動で進められます。
このときに以下のコマンドを実行します。
これを実行しないと installer が grub-install
で入力を求められてインストールが失敗します。
echo "GRUB_ENABLE_CRYPTODISK=y" >> /target/etc/default/grub
Ubuntu インストール後
インストールが完了するとこのようなポップアップが表示され、テストし続けるか再起動するか選択させられます。
引き続きターミナルからディスク暗号化等の設定をする必要があるので、Continue Testing ボタンをクリックします。
パーティショニング で使用していたターミナルに戻ります。
インストールされた /
パーティションを /target
へマウントします。
もし /etc
パーティションを分けているのであればそちらもマウントする必要があります。
mount /dev/mapper/vg1-root /target
proc
, sys
, dev
と DNS 名前解決のための etc/resolv.conf
を /target
へマウントします。
--rbind
オプションではマウント元でマウントしているデバイスをマウントし直します。
for n in proc sys dev etc/resolv.conf; do mount --rbind "/$n" "/target/$n"; done
chroot
して /etc/fstab
で記載されているデバイスをマウントします。
chroot /target mount -a
この時点では LUKS の key にはパスフレーズのみ設定している状態です。
後に /etc/crypttab
で keyfile から LUKS パーティションを自動マウントできるようにするため keyfile を作成・追加します。
apt install -y cryptsetup-initramfs echo "KEYFILE_PATTERN=/etc/luks/*.keyfile" >> /etc/cryptsetup-initramfs/conf-hook echo "UMASK=0077" >> /etc/initramfs-tools/initramfs.conf mkdir /etc/luks dd if=/dev/urandom of=/etc/luks/boot_os.keyfile bs=4096 count=1 chmod u=rx,go-rwx /etc/luks chmod u=r,go-rwx /etc/luks/boot_os.keyfile printf %s "${PASSPHRASE}" | cryptsetup luksAddKey -d - "${DEV}2" /etc/luks/boot_os.keyfile printf %s "${PASSPHRASE}" | cryptsetup luksAddKey -d - "${DEV}3" /etc/luks/boot_os.keyfile
LUKS パーティションを自動マウントするよう設定します。
echo "luks_boot UUID=$(blkid -s UUID -o value ${DEV}2) /etc/luks/boot_os.keyfile luks,discard" >> /etc/crypttab echo "luks_${DM}3 UUID=$(blkid -s UUID -o value ${DEV}3) /etc/luks/boot_os.keyfile luks,discard" >> /etc/crypttab
初期 RAM ディスクを更新します。
update-initramfs -uk all
chroot
から抜けて再起動します。
exit reboot
再起動
再起動が始まると以下のような画面が表示されるので Enter キーを押します。
起動すると Enter passphrase for hd0,gpt2 (ec4555eb53fe40cb9acae3b2ff65b686):
と表示されます。
UUID の部分は環境ごとに異なります。
設定したパスフレーズを入力し、暗号化されている /boot
パーティションを使用できる状態にします。
入力しても文字は表示されないので注意してください。
この画面が表示されればインストール完了です。
はまったこと
誤って /boot
パーティションサイズを 100MiB にしていて、 update-initramfs
コマンドで初期 RAM disk 作成時に容量超過でコマンド失敗しました。
初期 RAM ディスク(initrd.img-5.4.0-28-generic
)は 80 MiB くらいあるので、複数作成しようとすると失敗します。
エラーメッセージ読んても原因がわからず辛かった…
さいごに
Ubuntu 20.04 (Focal Fossa) を LVM on LUKS でインストールする方法を紹介しました。 他の方のブログや公式サイトの情報では細かい手順まで記載してなかったり断片的だったりで一貫した情報が少なく、 本当に可能なのか不安だった中で検証環境と XPS 13 にインストールできたので安心しました。 この記事がお役に立てれば幸いです。
コマンド実行例
実行例
ubuntu@ubuntu:~$ dconf write /org/gnome/desktop/input-sources/xkb-options "['ctrl:nocaps']" ubuntu@ubuntu:~$ sudo -i root@ubuntu:~# read -sr PASSPHRASE root@ubuntu:~# echo ${PASSPHRASE} password root@ubuntu:~# export PASSPHRASE root@ubuntu:~# export DEV="/dev/vda" root@ubuntu:~# export DM="vda" root@ubuntu:~# sgdisk --zap-all "${DEV}" Creating new GPT entries in memory. GPT data structures destroyed! You may now partition the disk using fdisk or other utilities. root@ubuntu:~# sgdisk --new=1:0:+100M --change-name=1:"EFI System" --typecode=1:ef00 "${DEV}" Creating new GPT entries in memory. Setting name! partNum is 0 The operation has completed successfully. root@ubuntu:~# sgdisk --new=2:0:+500M --change-name=2:"Boot" --typecode=2:8300 "${DEV}" Setting name! partNum is 1 The operation has completed successfully. root@ubuntu:~# sgdisk --new=3:0:0 --change-name=3:"Linux LUKS" --typecode=3:8309 "${DEV}" Setting name! partNum is 2 The operation has completed successfully. root@ubuntu:~# sgdisk --print "${DEV}" Disk /dev/vda: 125829120 sectors, 60.0 GiB Sector size (logical/physical): 512/512 bytes Disk identifier (GUID): 6DDBA433-4A1E-40A7-8123-CCD4E567AF46 Partition table holds up to 128 entries Main partition table begins at sector 2 and ends at sector 33 First usable sector is 34, last usable sector is 125829086 Partitions will be aligned on 2048-sector boundaries Total free space is 2014 sectors (1007.0 KiB) Number Start (sector) End (sector) Size Code Name 1 2048 206847 100.0 MiB EF00 EFI System 2 206848 1230847 500.0 MiB 8300 Boot 3 1230848 125829086 59.4 GiB 8309 Linux LUKS root@ubuntu:~# root@ubuntu:~# printf %s "${PASSPHRASE}" | cryptsetup luksFormat --type=luks1 --key-file - --batch-mode "${DEV}2" root@ubuntu:~# printf %s "${PASSPHRASE}" | cryptsetup luksFormat --type=luks1 --key-file - --batch-mode "${DEV}3" root@ubuntu:~# root@ubuntu:~# printf %s "${PASSPHRASE}" | cryptsetup open -d - "${DEV}2" luks_boot root@ubuntu:~# printf %s "${PASSPHRASE}" | cryptsetup open -d - "${DEV}3" "luks_${DM}3" root@ubuntu:~# ls /dev/mapper/ control luks_boot luks_vda3 root@ubuntu:~# root@ubuntu:~# mkfs.ext4 -L boot /dev/mapper/luks_boot mke2fs 1.45.5 (07-Jan-2020) Creating filesystem with 127488 4k blocks and 127488 inodes Filesystem UUID: 14ec2569-976f-453d-8261-d3b3d6099140 Superblock backups stored on blocks: 32768, 98304 Allocating group tables: done Writing inode tables: done Creating journal (4096 blocks): done Writing superblocks and filesystem accounting information: done root@ubuntu:~# mkfs.vfat -F 32 -n EFI-SP "${DEV}1" mkfs.fat 4.1 (2017-01-24) root@ubuntu:~# root@ubuntu:~# pvcreate /dev/mapper/"luks_${DM}3" Physical volume "/dev/mapper/luks_vda3" successfully created. root@ubuntu:~# vgcreate vg1 /dev/mapper/"luks_${DM}3" Volume group "vg1" successfully created root@ubuntu:~# root@ubuntu:~# lvcreate -L 4G -n swap vg1 Logical volume "swap" created. root@ubuntu:~# lvcreate -l 100%FREE -n root vg1 Logical volume "root" created. root@ubuntu:~# lvs LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert root vg1 -wi-a----- <55.41g swap vg1 -wi-a----- 4.00g .. .. root@ubuntu:~# echo "GRUB_ENABLE_CRYPTODISK=y" >> /target/etc/default/grub .. .. root@ubuntu:~# mount /dev/mapper/vg1-root /target root@ubuntu:~# for n in proc sys dev etc/resolv.conf; do mount --rbind "/$n" "/target/$n"; done root@ubuntu:~# chroot /target root@ubuntu:/# mount -a root@ubuntu:/# apt install -y cryptsetup-initramfs Reading package lists... Done Building dependency tree Reading state information... Done cryptsetup-initramfs is already the newest version (2:2.2.2-3ubuntu2). 0 upgraded, 0 newly installed, 0 to remove and 29 not upgraded. root@ubuntu:/# echo "KEYFILE_PATTERN=/etc/luks/*.keyfile" >> /etc/cryptsetup-initramfs/conf-hook root@ubuntu:/# echo "UMASK=0077" >> /etc/initramfs-tools/initramfs.conf root@ubuntu:/# mkdir /etc/luks root@ubuntu:/# dd if=/dev/urandom of=/etc/luks/boot_os.keyfile bs=4096 count=1 1+0 records in 1+0 records out 4096 bytes (4.1 kB, 4.0 KiB) copied, 0.000639065 s, 6.4 MB/s root@ubuntu:/# chmod u=rx,go-rwx /etc/luks root@ubuntu:/# chmod u=r,go-rwx /etc/luks/boot_os.keyfile root@ubuntu:/# printf %s "${PASSPHRASE}" | cryptsetup luksAddKey -d - "${DEV}2" /etc/luks/boot_os.keyfile root@ubuntu:/# printf %s "${PASSPHRASE}" | cryptsetup luksAddKey -d - "${DEV}3" /etc/luks/boot_os.keyfile root@ubuntu:/# echo "luks_boot UUID=$(blkid -s UUID -o value ${DEV}2) /etc/luks/boot_os.keyfile luks,discard" >> /etc/crypttab root@ubuntu:/# echo "luks_${DM}3 UUID=$(blkid -s UUID -o value ${DEV}3) /etc/luks/boot_os.keyfile luks,discard" >> /etc/crypttab root@ubuntu:/# update-initramfs -uk all update-initramfs: Generating /boot/initrd.img-5.4.0-28-generic update-initramfs: Generating /boot/initrd.img-5.4.0-26-generic root@ubuntu:/# exit root@ubuntu:~# reboot