Co-authored-by: Drew DeVault <sir@cmpwn.com>
---
Major changes since v7 are:
* setup_grub and setup_root: when using EFI and encryption, the boot
partition is unencrypted and mounted to /boot instead of /boot/efi
(like current behavior with syslinux); this solves two issues: setting
up GRUB with luks2 encrypted /boot is difficult, installing GRUB with
encrypted /boot needs chroot or a workaround (see v7 discussion)
* install_mounted_root: cryptroot kernel param is now set to UUID
instead of device name
* init_progs: blkid is explicitly installed, because crypt_required
needs it
I tested sys and cryptsys installation with syslinux/BIOS,
GRUB/BIOS and GRUB/EFI on x86_64.
See
https://git.sr.ht/~krystianch/alpine-conf/commit/70aaffca3d4685f3a8d78deaca7b479521b13ab8
for full diff between v7 and v8.
I'd appreciate a review / feedback.
setup-disk.in | 135 +++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 106 insertions(+), 29 deletions(-)
diff --git a/setup-disk.in b/setup-disk.in
index 656b5bc..46c8068 100644
--- a/setup-disk.in+++ b/setup-disk.in
@@ -82,6 +82,26 @@ enumerate_fstab() {
done
}
+# given an fstab on stdin, determine if any of the mountpoints are encrypted+crypt_required() {+ while read -r devname mountpoint fstype mntops freq passno; do+ if [ -z "$devname" ] || [ "${devname###}" != "$devname" ]; then+ continue+ fi+ uuid="${devname##UUID=}"+ if [ "$uuid" != "$devname" ]; then+ devname="$(blkid --uuid "$uuid")"+ fi+ mapname="${devname##/dev/mapper/}"+ if [ "$mapname" != "$devname" ]; then+ if cryptsetup status "$mapname" >&1 >/dev/null; then+ return 0+ fi+ fi+ done+ return 1+}+is_vmware() {
grep -q VMware /proc/scsi/scsi 2>/dev/null \
|| grep -q VMware /proc/ide/hd*/model 2>/dev/null
@@ -283,19 +303,23 @@ setup_grub() {
# install GRUB efi mode
if [ -n "$USE_EFI" ]; then
local target fwa
+ local efi_directory="$mnt"/boot/efi case "$ARCH" in
x86_64) target=x86_64-efi ; fwa=x64 ;;
x86) target=i386-efi ; fwa=ia32 ;;
arm*) target=arm-efi ; fwa=arm ;;
aarch64) target=arm64-efi ; fwa=aa64 ;;
esac
+ if [ -n "$USE_CRYPT" ]; then+ efi_directory="$mnt"/boot+ fi # currently disabling nvram so grub doesnt call efibootmgr
# installing to alpine directory so other distros dont overwrite it
- grub-install --target=$target --efi-directory="$mnt"/boot/efi \+ grub-install --target=$target --efi-directory="$efi_directory" \ --bootloader-id=alpine --boot-directory="$mnt"/boot --no-nvram
# fallback mode will use boot/boot${fw arch}.efi
- install -D "$mnt"/boot/efi/EFI/alpine/grub$fwa.efi \- "$mnt"/boot/efi/EFI/boot/boot$fwa.efi+ install -D "$efi_directory"/EFI/alpine/grub$fwa.efi \+ "$efi_directory"/EFI/boot/boot$fwa.efi # install GRUB for ppc64le
elif [ "$ARCH" = "ppc64le" ]; then
shift 5
@@ -427,7 +451,7 @@ setup_raspberrypi_bootloader() {
install_mounted_root() {
local mnt="$1"
shift 1
- local disks="${@}" mnt_boot= boot_fs= root_fs=+ local disks="${@}" mnt_boot= boot_fs= root_fs= use_crypt= local initfs_features="ata base ide scsi usb virtio"
local pvs= dev= rootdev= bootdev= extlinux_raidopt= root= modules=
local kernel_opts="$KERNELOPTS"
@@ -490,7 +514,6 @@ install_mounted_root() {
esac
done
- if [ -n "$VERBOSE" ]; then
echo "Root device: $rootdev"
echo "Root filesystem: $root_fs"
@@ -513,6 +536,28 @@ install_mounted_root() {
# we should not try start modloop on sys install
rm -f "$mnt"/etc/runlevels/*/modloop
+ # generate the fstab+ if [ -f "$mnt"/etc/fstab ]; then+ mv "$mnt"/etc/fstab "$mnt"/etc/fstab.old+ fi+ enumerate_fstab "$mnt" >> "$mnt"/etc/fstab+ if [ -n "$SWAP_DEVICES" ]; then+ local swap_dev+ for swap_dev in $SWAP_DEVICES; do+ echo -e "$(uuid_or_device ${swap_dev})\tswap\tswap\tdefaults\t0 0" \+ >> "$mnt"/etc/fstab+ done+ fi+ cat >>"$mnt"/etc/fstab <<-__EOF__+ /dev/cdrom /media/cdrom iso9660 noauto,ro 0 0+ /dev/usbdisk /media/usb vfat noauto 0 0+ __EOF__++ if crypt_required <"$mnt"/etc/fstab; then+ use_crypt=1+ initfs_features="$initfs_features cryptsetup"+ fi+ # generate mkinitfs.conf
mkdir -p "$mnt"/etc/mkinitfs/features.d
echo "features=\"$initfs_features\"" > "$mnt"/etc/mkinitfs/mkinitfs.conf
@@ -530,24 +575,15 @@ install_mounted_root() {
if [ -n "$(get_bootopt nomodeset)" ]; then
kernel_opts="nomodeset $kernel_opts"
fi
+ if [ "$use_crypt" ] && cryptsetup status "$rootdev" 2>&1 >/dev/null; then+ # Boot to encrypted root+ root=$(cryptsetup status "$rootdev" | awk '/device:/ { print $2 }')+ root=$(uuid_or_device $root)+ kernel_opts="cryptroot=$root cryptdm=root"+ root=/dev/mapper/root+ fi modules="sd-mod,usb-storage,${root_fs}${raidmod}"
- # generate the fstab- if [ -f "$mnt"/etc/fstab ]; then- mv "$mnt"/etc/fstab "$mnt"/etc/fstab.old- fi- enumerate_fstab "$mnt" >> "$mnt"/etc/fstab- if [ -n "$SWAP_DEVICES" ]; then- local swap_dev- for swap_dev in $SWAP_DEVICES; do- echo -e "$(uuid_or_device ${swap_dev})\tswap\tswap\tdefaults\t0 0" \- >> "$mnt"/etc/fstab- done- fi- cat >>"$mnt"/etc/fstab <<-__EOF__- /dev/cdrom /media/cdrom iso9660 noauto,ro 0 0- /dev/usbdisk /media/usb vfat noauto 0 0- __EOF__ # remove the installed db in case its there so we force re-install
rm -f "$mnt"/var/lib/apk/installed "$mnt"/lib/apk/db/installed
echo "Installing system on $rootdev:"
@@ -595,6 +631,10 @@ unmount_partitions() {
# unmount the partitions
umount $(awk '{print $2}' /proc/mounts | egrep "^$mnt(/|\$)" | sort -r)
++ if [ "$USE_CRYPT" ]; then+ cryptsetup close /dev/mapper/root+ fi}
# figure out decent default swap size in mega bytes
@@ -697,9 +737,10 @@ select_bootloader_pkg() {
# install needed programs
init_progs() {
- local raidpkg= lvmpkg= fs= fstools= grub=+ local raidpkg= lvmpkg= cryptpkg= fs= fstools= grub= [ -n "$USE_RAID" ] && raidpkg="mdadm"
[ -n "$USE_LVM" ] && lvmpkg="lvm2"
+ [ -n "$USE_CRYPT" ] && cryptpkg="cryptsetup blkid" for fs in $BOOTFS $ROOTFS $VARFS; do
# we need load btrfs module early to avoid the error message:
# 'failed to open /dev/btrfs-control'
@@ -714,7 +755,7 @@ init_progs() {
vfat) fstools="$fstools dosfstools";;
esac
done
- apk add --quiet sfdisk $lvmpkg $raidpkg $fstools $@+ apk add --quiet sfdisk $cryptpkg $lvmpkg $raidpkg $fstools $@}
show_disk_info() {
@@ -1018,11 +1059,11 @@ setup_root() {
mkfs.$ROOTFS $MKFS_OPTS_ROOT $mkfs_args "$root_dev"
mkdir -p "$SYSROOT"
mount -t $ROOTFS $root_dev "$SYSROOT" || return 1
- if [ -n "$boot_dev" ] && [ -z "$USE_EFI" ]; then+ if [ -n "$boot_dev" ] && ([ -z "$USE_EFI" ] || [ -n "$USE_CRYPT" ]); then mkdir -p "$SYSROOT"/boot
mount -t $BOOTFS $boot_dev "$SYSROOT"/boot || return 1
fi
- if [ -n "$boot_dev" ] && [ -n "$USE_EFI" ]; then+ if [ -n "$boot_dev" ] && [ -n "$USE_EFI" ] && [ -z "$USE_CRYPT" ]; then mkdir -p "$SYSROOT"/boot/efi
mount -t $BOOTFS $boot_dev "$SYSROOT"/boot/efi || return 1
fi
@@ -1082,6 +1123,18 @@ native_disk_install_lvm() {
setup_root $root_dev $BOOT_DEV
}
+setup_crypt() {+ local dev="$1" local dmname="$2"+ mkdir -p /run/cryptsetup+ echo "Preparing root partition for encryption." >&2+ echo "You will be prompted for your password at boot." >&2+ echo "If you forget your password, your data will be lost." >&2+ cryptsetup luksFormat --type luks2 "$dev" >&2+ echo "Enter password again to unlock disk for installation." >&2+ cryptsetup open "$dev" "$dmname" >&2+ echo "/dev/mapper/$dmname"+}+native_disk_install() {
local prep_part_type=$(partition_id prep)
local root_part_type=$(partition_id linux)
@@ -1156,6 +1209,10 @@ native_disk_install() {
root_dev=$(find_nth_non_boot_parts $index "$root_part_type" $@)
fi
+ if [ "$USE_CRYPT" ]; then+ root_dev=$(setup_crypt $root_dev root)+ fi+ [ $SWAP_SIZE -gt 0 ] && setup_swap_dev $swap_dev
setup_root $root_dev $BOOT_DEV $@
}
@@ -1176,7 +1233,7 @@ diskselect_help() {
diskmode_help() {
cat <<-__EOF__
- You can select between 'sys', 'data', 'lvm', 'lvmsys' or 'lvmdata'.+ You can select between 'sys', 'cryptsys', 'data', 'lvm', 'lvmsys' or 'lvmdata'. sys:
This mode is a traditional disk install. The following partitions will be
@@ -1184,6 +1241,12 @@ diskmode_help() {
This mode may be used for development boxes, desktops, virtual servers, etc.
+ cryptsys:+ This mode is equivalent to sys, except that the root filesystem will be+ encrypted with cryptsetup. You will be prompted to enter a decryption+ password, and will need to use this password to boot up the operating+ system after installation.+ data:
This mode uses your disk(s) for data storage, not for the operating system.
The system itself will run from tmpfs (RAM).
@@ -1233,7 +1296,7 @@ ask_disk() {
usage() {
cat <<-__EOF__
- usage: setup-disk [-hLqrv] [-k kernelflavor] [-m MODE] [-o apkovl] [-s SWAPSIZE]+ usage: setup-disk [-hLqrve] [-k kernelflavor] [-m MODE] [-o apkovl] [-s SWAPSIZE] [MOUNTPOINT | DISKDEV...]
Install alpine on harddisk.
@@ -1247,6 +1310,7 @@ usage() {
options:
-h Show this help
+ -e Encrypt disk -m Use disk for MODE without asking, where MODE is either 'data' or 'sys'
-o Restore system from given apkovl file
-k Use kernelflavor instead of $KERNEL_FLAVOR
@@ -1286,11 +1350,13 @@ case $kver in
*) KERNEL_FLAVOR=lts;;
esac
+USE_CRYPT=DISK_MODE=
USE_LVM=
# Parse args
-while getopts "hk:Lm:o:qrs:v" opt; do+while getopts "hek:Lm:o:qrs:v" opt; do case $opt in
+ e) USE_CRYPT=1;; m) DISK_MODE="$OPTARG";;
k) KERNEL_FLAVOR="$OPTARG";;
L) USE_LVM="_lvm";;
@@ -1319,6 +1385,12 @@ fi
reset_var
swapoff -a
+if [ $USE_CRYPT -eq 1 ] && [ -n "$USE_LVM" ]; then+ echo "cryptsys and lvm are currently mutually incompatible."+ echo "Please run $0 again with only one of these options selected."+ exit 1+fi+# stop all volume groups in use
vgchange --ignorelockingfailure -a n >/dev/null 2>&1
@@ -1381,9 +1453,14 @@ if [ -n "$diskdevs" ] && [ -z "$DISK_MODE" ]; then
echo "The following $disk_is_or_disks_are selected${USE_LVM:+ (with LVM)}:"
show_disk_info $diskdevs
_lvm=${USE_LVM:-", 'lvm'"}
- ask "How would you like to use $it_them? ('sys', 'data'${_lvm#_lvm} or '?' for help)" "?"+ ask "How would you like to use $it_them? ('sys', 'cryptsys', 'data'${_lvm#_lvm} or '?' for help)" "?" case "$resp" in
'?') diskmode_help;;
+ cryptsys)+ resp=sys+ USE_CRYPT=1+ break+ ;; sys|data) break;;
lvm) USE_LVM="_lvm" ;;
nolvm) USE_LVM="";;
--
2.32.0
Some feedback from ncopa:
From: Natanael Copa <ncopa@alpinelinux.org>
To: Krystian Chachu*a <krystian@krystianch.com>
Cc: ~alpine/devel@lists.alpinelinux.org, Drew DeVault <sir@cmpwn.com>
Subject: Re: [PATCH alpine-conf v8] Support encrypted root in setup-disk
Date: Fri, 1 Oct 2021 18:40:51 +0200
X-Mailer: Claws Mail 4.0.0 (GTK+ 3.24.30; x86_64-alpine-linux-musl)
Hi!
Thank you for working on this.
On Sat, 14 Aug 2021 21:11:42 +0200
Krystian Chachuła <krystian@krystianch.com> wrote:
> Co-authored-by: Drew DeVault <sir@cmpwn.com>> ---> Major changes since v7 are:> * setup_grub and setup_root: when using EFI and encryption, the boot> partition is unencrypted and mounted to /boot instead of /boot/efi> (like current behavior with syslinux); this solves two issues: setting> up GRUB with luks2 encrypted /boot is difficult, installing GRUB with> encrypted /boot needs chroot or a workaround (see v7 discussion)
I think it would be nice with an explanation in the commit message why
it is done this way.
> * install_mounted_root: cryptroot kernel param is now set to UUID> instead of device name> * init_progs: blkid is explicitly installed, because crypt_required> needs it> > I tested sys and cryptsys installation with syslinux/BIOS,> GRUB/BIOS and GRUB/EFI on x86_64.
great! thanks!
> > See> https://git.sr.ht/~krystianch/alpine-conf/commit/70aaffca3d4685f3a8d78deaca7b479521b13ab8> for full diff between v7 and v8.> > I'd appreciate a review / feedback.> > setup-disk.in | 135 +++++++++++++++++++++++++++++++++++++++-----------> 1 file changed, 106 insertions(+), 29 deletions(-)> > diff --git a/setup-disk.in b/setup-disk.in> index 656b5bc..46c8068 100644> --- a/setup-disk.in> +++ b/setup-disk.in> @@ -82,6 +82,26 @@ enumerate_fstab() {> done> }> > +# given an fstab on stdin, determine if any of the mountpoints are encrypted> +crypt_required() {> + while read -r devname mountpoint fstype mntops freq passno; do> + if [ -z "$devname" ] || [ "${devname###}" != "$devname" ]; then> + continue> + fi> + uuid="${devname##UUID=}"> + if [ "$uuid" != "$devname" ]; then> + devname="$(blkid --uuid "$uuid")"> + fi> + mapname="${devname##/dev/mapper/}"> + if [ "$mapname" != "$devname" ]; then> + if cryptsetup status "$mapname" >&1 >/dev/null; then> + return 0> + fi> + fi> + done> + return 1> +}> +> is_vmware() {> grep -q VMware /proc/scsi/scsi 2>/dev/null \> || grep -q VMware /proc/ide/hd*/model 2>/dev/null> @@ -283,19 +303,23 @@ setup_grub() {> # install GRUB efi mode> if [ -n "$USE_EFI" ]; then> local target fwa> + local efi_directory="$mnt"/boot/efi> case "$ARCH" in> x86_64) target=x86_64-efi ; fwa=x64 ;;> x86) target=i386-efi ; fwa=ia32 ;;> arm*) target=arm-efi ; fwa=arm ;;> aarch64) target=arm64-efi ; fwa=aa64 ;;> esac> + if [ -n "$USE_CRYPT" ]; then> + efi_directory="$mnt"/boot> + fi> # currently disabling nvram so grub doesnt call efibootmgr> # installing to alpine directory so other distros dont overwrite it> - grub-install --target=$target --efi-directory="$mnt"/boot/efi \> + grub-install --target=$target --efi-directory="$efi_directory" \> --bootloader-id=alpine --boot-directory="$mnt"/boot --no-nvram> # fallback mode will use boot/boot${fw arch}.efi> - install -D "$mnt"/boot/efi/EFI/alpine/grub$fwa.efi \> - "$mnt"/boot/efi/EFI/boot/boot$fwa.efi> + install -D "$efi_directory"/EFI/alpine/grub$fwa.efi \> + "$efi_directory"/EFI/boot/boot$fwa.efi> # install GRUB for ppc64le> elif [ "$ARCH" = "ppc64le" ]; then> shift 5> @@ -427,7 +451,7 @@ setup_raspberrypi_bootloader() {> install_mounted_root() {> local mnt="$1"> shift 1> - local disks="${@}" mnt_boot= boot_fs= root_fs=> + local disks="${@}" mnt_boot= boot_fs= root_fs= use_crypt=> local initfs_features="ata base ide scsi usb virtio"> local pvs= dev= rootdev= bootdev= extlinux_raidopt= root= modules=> local kernel_opts="$KERNELOPTS"> @@ -490,7 +514,6 @@ install_mounted_root() {> esac> done> > -> if [ -n "$VERBOSE" ]; then> echo "Root device: $rootdev"> echo "Root filesystem: $root_fs"> @@ -513,6 +536,28 @@ install_mounted_root() {> # we should not try start modloop on sys install> rm -f "$mnt"/etc/runlevels/*/modloop> > + # generate the fstab> + if [ -f "$mnt"/etc/fstab ]; then> + mv "$mnt"/etc/fstab "$mnt"/etc/fstab.old> + fi> + enumerate_fstab "$mnt" >> "$mnt"/etc/fstab> + if [ -n "$SWAP_DEVICES" ]; then> + local swap_dev> + for swap_dev in $SWAP_DEVICES; do> + echo -e "$(uuid_or_device ${swap_dev})\tswap\tswap\tdefaults\t0 0" \> + >> "$mnt"/etc/fstab> + done> + fi> + cat >>"$mnt"/etc/fstab <<-__EOF__> + /dev/cdrom /media/cdrom iso9660 noauto,ro 0 0> + /dev/usbdisk /media/usb vfat noauto 0 0> + __EOF__> +> + if crypt_required <"$mnt"/etc/fstab; then> + use_crypt=1> + initfs_features="$initfs_features cryptsetup"> + fi> +> # generate mkinitfs.conf> mkdir -p "$mnt"/etc/mkinitfs/features.d> echo "features=\"$initfs_features\"" > "$mnt"/etc/mkinitfs/mkinitfs.conf> @@ -530,24 +575,15 @@ install_mounted_root() {> if [ -n "$(get_bootopt nomodeset)" ]; then> kernel_opts="nomodeset $kernel_opts"> fi> + if [ "$use_crypt" ] && cryptsetup status "$rootdev" 2>&1 >/dev/null; then> + # Boot to encrypted root> + root=$(cryptsetup status "$rootdev" | awk '/device:/ { print $2 }')> + root=$(uuid_or_device $root)> + kernel_opts="cryptroot=$root cryptdm=root"> + root=/dev/mapper/root> + fi> modules="sd-mod,usb-storage,${root_fs}${raidmod}"> > - # generate the fstab> - if [ -f "$mnt"/etc/fstab ]; then> - mv "$mnt"/etc/fstab "$mnt"/etc/fstab.old> - fi> - enumerate_fstab "$mnt" >> "$mnt"/etc/fstab> - if [ -n "$SWAP_DEVICES" ]; then> - local swap_dev> - for swap_dev in $SWAP_DEVICES; do> - echo -e "$(uuid_or_device ${swap_dev})\tswap\tswap\tdefaults\t0 0" \ > - >> "$mnt"/etc/fstab > - done> - fi> - cat >>"$mnt"/etc/fstab <<-__EOF__> - /dev/cdrom /media/cdrom iso9660 noauto,ro 0 0> - /dev/usbdisk /media/usb vfat noauto 0 0> - __EOF__> # remove the installed db in case its there so we force re-install> rm -f "$mnt"/var/lib/apk/installed "$mnt"/lib/apk/db/installed> echo "Installing system on $rootdev:"> @@ -595,6 +631,10 @@ unmount_partitions() {> > # unmount the partitions> umount $(awk '{print $2}' /proc/mounts | egrep "^$mnt(/|\$)" | sort -r)> +> + if [ "$USE_CRYPT" ]; then> + cryptsetup close /dev/mapper/root> + fi> }> > # figure out decent default swap size in mega bytes> @@ -697,9 +737,10 @@ select_bootloader_pkg() {> > # install needed programs> init_progs() {> - local raidpkg= lvmpkg= fs= fstools= grub=> + local raidpkg= lvmpkg= cryptpkg= fs= fstools= grub=> [ -n "$USE_RAID" ] && raidpkg="mdadm"> [ -n "$USE_LVM" ] && lvmpkg="lvm2"> + [ -n "$USE_CRYPT" ] && cryptpkg="cryptsetup blkid"> for fs in $BOOTFS $ROOTFS $VARFS; do> # we need load btrfs module early to avoid the error message:> # 'failed to open /dev/btrfs-control'> @@ -714,7 +755,7 @@ init_progs() {> vfat) fstools="$fstools dosfstools";;> esac> done> - apk add --quiet sfdisk $lvmpkg $raidpkg $fstools $@> + apk add --quiet sfdisk $cryptpkg $lvmpkg $raidpkg $fstools $@> }> > show_disk_info() {> @@ -1018,11 +1059,11 @@ setup_root() {> mkfs.$ROOTFS $MKFS_OPTS_ROOT $mkfs_args "$root_dev"> mkdir -p "$SYSROOT"> mount -t $ROOTFS $root_dev "$SYSROOT" || return 1> - if [ -n "$boot_dev" ] && [ -z "$USE_EFI" ]; then> + if [ -n "$boot_dev" ] && ([ -z "$USE_EFI" ] || [ -n "$USE_CRYPT" ]); then> mkdir -p "$SYSROOT"/boot> mount -t $BOOTFS $boot_dev "$SYSROOT"/boot || return 1> fi> - if [ -n "$boot_dev" ] && [ -n "$USE_EFI" ]; then> + if [ -n "$boot_dev" ] && [ -n "$USE_EFI" ] && [ -z "$USE_CRYPT" ]; then> mkdir -p "$SYSROOT"/boot/efi> mount -t $BOOTFS $boot_dev "$SYSROOT"/boot/efi || return 1> fi> @@ -1082,6 +1123,18 @@ native_disk_install_lvm() {> setup_root $root_dev $BOOT_DEV> }> > +setup_crypt() {> + local dev="$1" local dmname="$2"> + mkdir -p /run/cryptsetup> + echo "Preparing root partition for encryption." >&2> + echo "You will be prompted for your password at boot." >&2> + echo "If you forget your password, your data will be lost." >&2> + cryptsetup luksFormat --type luks2 "$dev" >&2> + echo "Enter password again to unlock disk for installation." >&2> + cryptsetup open "$dev" "$dmname" >&2
What happens if user provides wrong password to `cryptsetup open` in
setup_crypt? Shouldn't we handle error here?
> + echo "/dev/mapper/$dmname"> +}> +> native_disk_install() {> local prep_part_type=$(partition_id prep)> local root_part_type=$(partition_id linux)> @@ -1156,6 +1209,10 @@ native_disk_install() {> root_dev=$(find_nth_non_boot_parts $index "$root_part_type" $@)> fi> > + if [ "$USE_CRYPT" ]; then> + root_dev=$(setup_crypt $root_dev root)
What should happen here if `cryptsetup open` failed?
> + fi> +> [ $SWAP_SIZE -gt 0 ] && setup_swap_dev $swap_dev> setup_root $root_dev $BOOT_DEV $@> }> @@ -1176,7 +1233,7 @@ diskselect_help() {> diskmode_help() {> cat <<-__EOF__> > - You can select between 'sys', 'data', 'lvm', 'lvmsys' or 'lvmdata'.> + You can select between 'sys', 'cryptsys', 'data', 'lvm', 'lvmsys' or 'lvmdata'.> > sys:> This mode is a traditional disk install. The following partitions will be> @@ -1184,6 +1241,12 @@ diskmode_help() {> > This mode may be used for development boxes, desktops, virtual servers, etc.> > + cryptsys:> + This mode is equivalent to sys, except that the root filesystem will be> + encrypted with cryptsetup. You will be prompted to enter a decryption> + password, and will need to use this password to boot up the operating> + system after installation.> +> data:> This mode uses your disk(s) for data storage, not for the operating system.> The system itself will run from tmpfs (RAM).> @@ -1233,7 +1296,7 @@ ask_disk() {> > usage() {> cat <<-__EOF__> - usage: setup-disk [-hLqrv] [-k kernelflavor] [-m MODE] [-o apkovl] [-s SWAPSIZE]> + usage: setup-disk [-hLqrve] [-k kernelflavor] [-m MODE] [-o apkovl] [-s SWAPSIZE]> [MOUNTPOINT | DISKDEV...]> > Install alpine on harddisk.> @@ -1247,6 +1310,7 @@ usage() {> > options:> -h Show this help> + -e Encrypt disk> -m Use disk for MODE without asking, where MODE is either 'data' or 'sys'> -o Restore system from given apkovl file> -k Use kernelflavor instead of $KERNEL_FLAVOR> @@ -1286,11 +1350,13 @@ case $kver in> *) KERNEL_FLAVOR=lts;;> esac> > +USE_CRYPT=> DISK_MODE=> USE_LVM=> # Parse args> -while getopts "hk:Lm:o:qrs:v" opt; do> +while getopts "hek:Lm:o:qrs:v" opt; do> case $opt in> + e) USE_CRYPT=1;;> m) DISK_MODE="$OPTARG";;> k) KERNEL_FLAVOR="$OPTARG";;> L) USE_LVM="_lvm";;> @@ -1319,6 +1385,12 @@ fi> reset_var> swapoff -a> > +if [ $USE_CRYPT -eq 1 ] && [ -n "$USE_LVM" ]; then> + echo "cryptsys and lvm are currently mutually incompatible."> + echo "Please run $0 again with only one of these options selected."> + exit 1> +fi> +
I wonder how much extra work it would be to add support for encrypted
disk under lvm?
> # stop all volume groups in use> vgchange --ignorelockingfailure -a n >/dev/null 2>&1> > @@ -1381,9 +1453,14 @@ if [ -n "$diskdevs" ] && [ -z "$DISK_MODE" ]; then> echo "The following $disk_is_or_disks_are selected${USE_LVM:+ (with LVM)}:"> show_disk_info $diskdevs> _lvm=${USE_LVM:-", 'lvm'"}> - ask "How would you like to use $it_them? ('sys', 'data'${_lvm#_lvm} or '?' for help)" "?"> + ask "How would you like to use $it_them? ('sys', 'cryptsys', 'data'${_lvm#_lvm} or '?' for help)" "?"> case "$resp" in> '?') diskmode_help;;> + cryptsys)> + resp=sys> + USE_CRYPT=1> + break> + ;;
What would be needed to be able to select 'crypt' and then select
either 'sys' or 'data'? similar to what we do with lvm. So we could
have data on cryptsetup as well.
> sys|data) break;;> lvm) USE_LVM="_lvm" ;;> nolvm) USE_LVM="";;
Thank you Natanael for the review.
On Fri Oct 1, 2021 at 6:40 PM CEST, Natanael Copa wrote:
> > * setup_grub and setup_root: when using EFI and encryption, the boot> > partition is unencrypted and mounted to /boot instead of /boot/efi> > (like current behavior with syslinux); this solves two issues: setting> > up GRUB with luks2 encrypted /boot is difficult, installing GRUB with> > encrypted /boot needs chroot or a workaround (see v7 discussion) >> I think it would be nice with an explanation in the commit message why> it is done this way.
Ok, I'll address it in v9.
> What happens if user provides wrong password to `cryptsetup open` in> setup_crypt? Shouldn't we handle error here?
I'd add `--tries 1` to make `cryptsetup open` exit on wrong password and prompt
user what to do:
Could not unlock disk: [REASON FROM EXIT CODE]. What would you like to do?
('retry', 'reformat', 'skip' or '?' for help)
Help would say:
You can select between 'retry', 'reformat', or 'skip'.
retry:
Try unlocking disk again.
reformat:
Discard current password and set a new one.
skip:
Continue without encrypting the root partition.
> > native_disk_install() {> > local prep_part_type=$(partition_id prep)> > local root_part_type=$(partition_id linux)> > @@ -1156,6 +1209,10 @@ native_disk_install() {> > root_dev=$(find_nth_non_boot_parts $index "$root_part_type" $@)> > fi> > > > + if [ "$USE_CRYPT" ]; then> > + root_dev=$(setup_crypt $root_dev root) >> What should happen here if `cryptsetup open` failed?
I'd make `setup_crypt` echo nothing when user skips encryption and, if it
happens, skip overwriting `root_dev` here.
> I wonder how much extra work it would be to add support for encrypted> disk under lvm?
I'd say not that much. For LVM on LUKS:
(1) `native_disk_install_lvm` would need to call `setup_crypt` to create
`/dev/mapper/cryptlvm` before `setup_lvm_volume_group` and
(2) `setup_lvm_volume_group` would need to set up LVM on `/dev/mapper/cryptlvm`.
If this looks ok I'll implement this in v9.
> What would be needed to be able to select 'crypt' and then select> either 'sys' or 'data'? similar to what we do with lvm. So we could> have data on cryptsetup as well.
I think we need an init script that runs before localmount and opens the
encrypted var partition by asking for password interactively.