installer: disalbe FDE; notes

Add option to disalbe full-disk encryption (FDE) to de-p1st-installer and update notes.md
This commit is contained in:
Daniel Langbein 2021-11-13 13:56:47 +01:00
parent c31c4994db
commit 7c96fd96d5
6 changed files with 115 additions and 79 deletions

View File

@ -103,25 +103,18 @@ Enter a number (default=1):
## TODOs (Ordered by priority) ## TODOs (Ordered by priority)
* installer: Option to disable full disk encryption
* Install more packages with a Makefile, see [toggle-bluetooth/Makefile](pkg/toggle-bluetooth/Makefile) * Install more packages with a Makefile, see [toggle-bluetooth/Makefile](pkg/toggle-bluetooth/Makefile)
* de-p1st-cups * de-p1st-cups
* qt-installer-framework * qt-installer-framework
* see https://codeberg.org/privacy1st/qt-installer-framework and https://bbs.archlinux.org/viewtopic.php?pid=1991208 * see https://codeberg.org/privacy1st/qt-installer-framework and https://bbs.archlinux.org/viewtopic.php?pid=1991208
* split up the "base" package:
* base-headless (no fonts required)
* base-graphical (depends on base-headless)
*
* remove "de-p1st-grub" from base * remove "de-p1st-grub" from base
* just one "base" package for both: BIOS and (U)EFI installation! * just one "base" package for both: BIOS and (U)EFI installation!
* installer: support BIOS boot mode? Or drop BIOS support? * installer: support BIOS boot mode? Or drop BIOS support?
* installer: systemd-boot as alternative to GRUB? * installer: systemd-boot as alternative to GRUB?
* https://wiki.archlinux.org/title/systemd-boot * https://wiki.archlinux.org/title/systemd-boot
* AUR-API
* for each PKG: built with docker then sign wit pgp * for each PKG: built with docker then sign wit pgp
* signed package db * signed package db

View File

@ -2,9 +2,9 @@
_pkgname=installer _pkgname=installer
_reponame=arch _reponame=arch
pkgname="de-p1st-$_pkgname" pkgname="de-p1st-$_pkgname"
pkgver=0.1.24 pkgver=0.2.0
pkgrel=1 pkgrel=1
pkgdesc="Bash script to install Arch Linux" pkgdesc="Installer for Arch Linux written in Bash"
arch=('any') arch=('any')
url="https://codeberg.org/privacy1st/${_reponame}" url="https://codeberg.org/privacy1st/${_reponame}"
license=('MIT') license=('MIT')
@ -17,11 +17,11 @@ sha256sums=('SKIP')
package() { package() {
cd "${_reponame}/pkg/${pkgname}" cd "${_reponame}/pkg/${pkgname}"
install -Dm0544 de-p1st-installer.sh "$pkgdir"/usr/bin/"${pkgname}" install -Dm0544 de-p1st-installer.sh "$pkgdir"/usr/bin/"${pkgname}"
install -Dm0644 lib/block-device.sh "$pkgdir"/usr/lib/"${pkgname}"/block-device.sh install -Dm0644 lib/block-device.sh "$pkgdir"/usr/lib/"${pkgname}"/block-device.sh
install -Dm0644 lib/user-input.sh "$pkgdir"/usr/lib/"${pkgname}"/user-input.sh install -Dm0644 lib/user-input.sh "$pkgdir"/usr/lib/"${pkgname}"/user-input.sh
install -Dm0644 lib/util.sh "$pkgdir"/usr/lib/"${pkgname}"/util.sh install -Dm0644 lib/util.sh "$pkgdir"/usr/lib/"${pkgname}"/util.sh
install -Dm0644 -o0 installer.cfg "$pkgdir"/etc/"${pkgname}"/installer.cfg install -Dm0644 -o0 installer.cfg "$pkgdir"/etc/"${pkgname}"/installer.cfg
install -Dm0644 -o0 example-vbox.cfg "$pkgdir"/etc/"${pkgname}"/example-vbox.cfg install -Dm0644 -o0 example-vbox.cfg "$pkgdir"/etc/"${pkgname}"/example-vbox.cfg

View File

@ -16,8 +16,8 @@ function main() {
check_network || return $? check_network || return $?
system_time || return $? system_time || return $?
# in: BOOT_FIRMWARE, FS, HOSTNAME, USERNAME, USER_PWD, LUKS_PWD (all optional) # in: BOOT_FIRMWARE, FS, HOSTNAME, USERNAME, USER_PWD, FDE, LUKS_PWD; (all variables are optional)
# out: BOOT_FIRMWARE, FS, HOSTNAME, USERNAME, USER_PWD, LUKS_PWD # out: BOOT_FIRMWARE, FS, HOSTNAME, USERNAME, USER_PWD, FDE, LUKS_PWD (if FDE='true')
get_user_input || return $? get_user_input || return $?
# in: CPU_VENDOR (optional) # in: CPU_VENDOR (optional)
# out: CPU_VENDOR # out: CPU_VENDOR
@ -25,16 +25,16 @@ function main() {
# in: FS # in: FS
# out: FS_DEFAULT_MOUNT_OPTIONS # out: FS_DEFAULT_MOUNT_OPTIONS
get_default_mount_options || return $? get_default_mount_options || return $?
# in: FS # in: FS
# out: FS_ADDITIONAL_MOUNT_OPTIONS # out: FS_ADDITIONAL_MOUNT_OPTIONS
get_additional_mount_options || return $? get_additional_mount_options || return $?
# in: TARGET_BLOCK_DEVICE, BOOT_FIRMWARE # in: TARGET_BLOCK_DEVICE, BOOT_FIRMWARE
# out: BOOT_PART, LUKS_PART # out: BOOT_PART, LUKS_PART
partition || return $? partition || return $?
# in: BOOT_FIRMWARE, BOOT_PART, LUKS_PART, LUKS_PWD, FS # in: BOOT_FIRMWARE, BOOT_PART, LUKS_PART, FDE, LUKS_PWD, FS
# out: LUKS_PART_UUID, DATA_PART # out: LUKS_PART_UUID (if FDE='true'), DATA_PART
format || return $? format || return $?
# Combine default and additional mount options # Combine default and additional mount options
@ -47,7 +47,7 @@ function main() {
mount_partitions || return $? mount_partitions || return $?
# in: BOOT_FIRMWARE # in: BOOT_FIRMWARE, PACSTRAP_INTERACTIVE (optional)
run_pacstrap || return $? run_pacstrap || return $?
# in: FS # in: FS
run_genfstab || return $? run_genfstab || return $?
@ -58,14 +58,16 @@ function main() {
user_and_pwd || return $? user_and_pwd || return $?
sudo arch-chroot /mnt mkinitcpio -P || return $? sudo arch-chroot /mnt mkinitcpio -P || return $?
# in: TARGET_BLOCK_DEVICE, LUKS_PART_UUID # in: TARGET_BLOCK_DEVICE, FDE, LUKS_PART_UUID
bootloader || return $? bootloader || return $?
if [ "${LEAVE_MOUNTED}" -eq '1' ]; then if [ "${LEAVE_MOUNTED}" = 'true' ]; then
echo 'Leaving partitions below /mnt mounted and '"${DATA_PART}"' opened.' echo 'Leaving partitions below /mnt mounted and '"${DATA_PART}"' opened.'
else else
sudo umount -R /mnt || return $? sudo umount -R /mnt || return $?
sudo cryptsetup luksClose "$(basename "${DATA_PART}")" || return $? if [ "${FDE}" = 'true' ] ; then
sudo cryptsetup luksClose "$(basename "${DATA_PART}")" || return $?
fi
fi fi
echo 'Finished installation without errors!' echo 'Finished installation without errors!'
} }
@ -99,12 +101,13 @@ function increase_cow_space() {
function get_user_input() { function get_user_input() {
# @post # @post
# BOOT_FIRMWARE (uefi or bios) # BOOT_FIRMWARE: 'uefi' | 'bios'
# FS (BTRFS, EXT4, F2FS) # FS: 'BTRFS' | 'EXT4' | 'F2FS'
# FS_BTRFS_SUBVOL_LAYOUT (root_only, @root@home) # FS_BTRFS_SUBVOL_LAYOUT: 'root_only' | '@root@home'
# HOSTNAME # HOSTNAME
# USERNAME, USER_PWD # USERNAME, USER_PWD
# LUKS_PWD # FDE: 'true' | 'false'
# LUKS_PWD: only set if FDE='true'
get_block_devices_with_size || return $? get_block_devices_with_size || return $?
single_choice_if_empty TARGET_BLOCK_DEVICE 'Select target device for installation' BLOCK_DEVICE_SIZES || return $? single_choice_if_empty TARGET_BLOCK_DEVICE 'Select target device for installation' BLOCK_DEVICE_SIZES || return $?
@ -151,7 +154,11 @@ function get_user_input() {
exit 1; exit 1;
} }
fi fi
if [ -z "${LUKS_PWD}" ]; then
TMP1=('true' 'Yes' 'false' 'No')
single_choice_if_empty FDE 'Shall Full-Disk-Encryption be enabled?' TMP1 || return $?
if [ "${FDE}" = 'true' ] && [ -z "${LUKS_PWD}" ]; then
ask_user_if_empty LUKS_PWD 'Enter a disk encryption password:' || return $? ask_user_if_empty LUKS_PWD 'Enter a disk encryption password:' || return $?
ask_user_if_empty LUKS_PWD2 'Please enter the password again:' || return $? ask_user_if_empty LUKS_PWD2 'Please enter the password again:' || return $?
# shellcheck disable=SC2153 # shellcheck disable=SC2153
@ -277,6 +284,7 @@ function mount_partitions() {
function run_pacstrap() { function run_pacstrap() {
# @pre # @pre
# BOOT_FIRMWARE # BOOT_FIRMWARE
# PACSTRAP_INTERACTIVE: optional, 'true'
echo 'Running pacstrap ...' echo 'Running pacstrap ...'
PKGS=("${ADDITIONAL_PKGS[@]}") PKGS=("${ADDITIONAL_PKGS[@]}")
@ -315,7 +323,7 @@ function run_pacstrap() {
fi fi
local args=() local args=()
if [ "${PACSTRAP_INTERACTIVE}" = '1' ]; then if [ "${PACSTRAP_INTERACTIVE}" = 'true' ]; then
args+=('-i') # run interactively args+=('-i') # run interactively
fi fi
args+=('/mnt') args+=('/mnt')
@ -359,9 +367,9 @@ function run_genfstab() {
function config_hostname_and_hosts() { function config_hostname_and_hosts() {
# @pre # @pre
# HOSTNAME # HOSTNAME
# FQDN (optional, e.g. sub.domain.de) # FQDN: optional, e.g. sub.domain.de
# STATIC_IP (optional, e.g. 93.133.433.133) # STATIC_IP: optional, e.g. 93.133.433.133
# IPV6_CAPABLE (optional, e.g. 1) # IPV6_CAPABLE: optional, 'true'
echo 'Set hostname ...' echo 'Set hostname ...'
echo "${HOSTNAME}" | sudo tee /mnt/etc/hostname >/dev/null || return $? echo "${HOSTNAME}" | sudo tee /mnt/etc/hostname >/dev/null || return $?
@ -383,7 +391,7 @@ function config_hostname_and_hosts() {
# 127.0.1.1 is often used for the FQDN of the machine # 127.0.1.1 is often used for the FQDN of the machine
'"${STATIC_IP} ${FQDN} ${HOSTNAME}" | sudo tee /mnt/etc/hosts >/dev/null || return $? '"${STATIC_IP} ${FQDN} ${HOSTNAME}" | sudo tee /mnt/etc/hosts >/dev/null || return $?
if [ "${IPV6_CAPABLE}" = '1' ]; then if [ "${IPV6_CAPABLE}" = 'true' ]; then
echo ' echo '
# The following lines are desirable for IPv6 capable hosts # The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback ::1 localhost ip6-localhost ip6-loopback
@ -414,7 +422,8 @@ function user_and_pwd() {
function bootloader() { function bootloader() {
# @pre # @pre
# TARGET_BLOCK_DEVICE # TARGET_BLOCK_DEVICE
# LUKS_PART_UUID # FDE: 'true' | 'false'
# LUKS_PART_UUID: required if FDE='true'
echo 'Installing grub ...' echo 'Installing grub ...'
case "${BOOT_FIRMWARE}" in case "${BOOT_FIRMWARE}" in
@ -435,23 +444,35 @@ function bootloader() {
echo 'Generating /boot/grub/grub.cfg ...' echo 'Generating /boot/grub/grub.cfg ...'
{ {
# /etc/default/grub is managed by Holo. Therefore we should not manually modify it. case "${FDE}" in
# Instead, we create a holosript which writes $LUKS_PART_UUID into GRUB_CMDLINE_LINUX of /etc/default/grub true)
{ # /etc/default/grub is managed by Holo. Therefore we should not manually modify it.
# Assert # Instead, we create a holosript which writes $LUKS_PART_UUID into GRUB_CMDLINE_LINUX of /etc/default/grub
grep --quiet '^GRUB_CMDLINE_LINUX=""$' < /mnt/etc/default/grub || return {
# Assert
grep --quiet '^GRUB_CMDLINE_LINUX=""$' < /mnt/etc/default/grub || return
# Use filename .../20- for the holoscript so that it gets executed after the one from de-p1st-grub # Use filename .../20- for the holoscript so that it gets executed after the one from de-p1st-grub
local holoScriptDir=/mnt/usr/share/holo/files/20-de-p1st-installer/etc/default/ local holoScriptDir=/mnt/usr/share/holo/files/20-de-p1st-installer/etc/default/
# The holoscript shall contain one 'sed "..."' command # The holoscript shall contain one 'sed "..."' command
sudo mkdir -p "${holoScriptDir}" || return $? sudo mkdir -p "${holoScriptDir}" || return $?
sudo echo '#!/bin/sh sudo echo '#!/bin/sh
sed "s|^GRUB_CMDLINE_LINUX=\"\"\$|GRUB_CMDLINE_LINUX=\"cryptdevice=/dev/disk/by-uuid/'"${LUKS_PART_UUID}"':crypt\"|"' \ sed "s|^GRUB_CMDLINE_LINUX=\"\"\$|GRUB_CMDLINE_LINUX=\"cryptdevice=/dev/disk/by-uuid/'"${LUKS_PART_UUID}"':crypt\"|"' \
| sudo tee "${holoScriptDir}"/grub.holoscript || return $? | sudo tee "${holoScriptDir}"/grub.holoscript || return $?
sudo chmod 0544 "${holoScriptDir}"/grub.holoscript || return $? sudo chmod 0544 "${holoScriptDir}"/grub.holoscript || return $?
} }
# Then we apply the holoscript # Then we apply the holoscript
sudo arch-chroot /mnt holo apply --force file:/etc/default/grub || return $? sudo arch-chroot /mnt holo apply --force file:/etc/default/grub || return $?
;;
false)
true
;;
*)
echo 'Invalid option: '"${FDE}"
return 1
;;
esac
# And finally run grub-mkconfig # And finally run grub-mkconfig
sudo arch-chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg || return $? sudo arch-chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg || return $?
} }

View File

@ -2,7 +2,7 @@
FQDN=v2202012136854137045.happysrv.de FQDN=v2202012136854137045.happysrv.de
STATIC_IP=45.83.105.88 STATIC_IP=45.83.105.88
IPV6_CAPABLE=1 IPV6_CAPABLE=true
HOSTNAME=p1st-arch-1 HOSTNAME=p1st-arch-1
USERNAME=yoda USERNAME=yoda
@ -16,9 +16,9 @@ BOOT_FIRMWARE=uefi
# If set to "1", then the data, boot and luks partitions # If set to "1", then the data, boot and luks partitions
# will be left mounted/opened after installation # will be left mounted/opened after installation
LEAVE_MOUNTED=0 LEAVE_MOUNTED=false
PACSTRAP_INTERACTIVE=1 PACSTRAP_INTERACTIVE=true
ADDITIONAL_PKGS=() ADDITIONAL_PKGS=()
# to skip pacman selections # to skip pacman selections

View File

@ -2,35 +2,36 @@
# FQDN=domain.name.of.this.host.de # FQDN=domain.name.of.this.host.de
# STATIC_IP=123.123.123.123 # STATIC_IP=123.123.123.123
# IPV6_CAPABLE=1 # IPV6_CAPABLE=true
HOSTNAME='yodaTest' HOSTNAME=yodaTest
USERNAME='yoda' USERNAME=yoda
# One should rather enter these interactively than saving in this cfg. # One should rather enter these interactively than saving in this cfg.
USER_PWD='test' USER_PWD='test'
FDE=true # enable FULL-DISK-ENCRYPTION
LUKS_PWD='test' LUKS_PWD='test'
# If unset, then USER_PWD will be used for ROOT_PWD # If unset, then USER_PWD will be used for ROOT_PWD
# ROOT_PWD=test # ROOT_PWD=test
TARGET_BLOCK_DEVICE='/dev/sda' # /dev/vda for Virtual Machine Manager TARGET_BLOCK_DEVICE=/dev/sda # /dev/vda for Virtual Machine Manager
BOOT_PART_SIZE='500' # MiB BOOT_PART_SIZE=500 # MiB
FS='BTRFS' FS=BTRFS
FS_BTRFS_SUBVOL_LAYOUT='@root@home' # Subvolume layout that is supported by Timeshift FS_BTRFS_SUBVOL_LAYOUT='@root@home' # Subvolume layout that is supported by Timeshift
FS_ADDITIONAL_MOUNT_OPTIONS=('noatime') FS_ADDITIONAL_MOUNT_OPTIONS=('noatime')
# If not booted into the target system, these values should be set: # If not booted into the target system, these values should be set:
# CPU_VENDOR: "autodetect", "amd", "intel" or "none" # CPU_VENDOR: "autodetect", "amd", "intel" or "none"
CPU_VENDOR='autodetect' CPU_VENDOR=autodetect
# BOOT_FIRMWARE: "autodetect", "uefi" or "bios" # BOOT_FIRMWARE: "autodetect", "uefi" or "bios"
BOOT_FIRMWARE='uefi' BOOT_FIRMWARE=uefi
# If set to "1", then the data, boot and luks partitions # If set to "1", then the data, boot and luks partitions
# will be left mounted/opened for manual inspection # will be left mounted/opened for manual inspection
# after the installation # after the installation
LEAVE_MOUNTED='1' LEAVE_MOUNTED=true
PACSTRAP_INTERACTIVE='1' PACSTRAP_INTERACTIVE=true
############## ADDITIONAL_PKGS from here on ############## ############## ADDITIONAL_PKGS from here on ##############
ADDITIONAL_PKGS=() ADDITIONAL_PKGS=()

View File

@ -51,6 +51,10 @@ function get_block_devices_with_size() {
function partition() { function partition() {
# Creates two partitions:
# - BOOT_PART by default 261mb
# - LUKS_PART rest of the device for (encrypted) data
#
# @pre # @pre
# TARGET_BLOCK_DEVICE # TARGET_BLOCK_DEVICE
# BOOT_FIRMWARE # BOOT_FIRMWARE
@ -111,17 +115,23 @@ function partition() {
} }
function format() { function format() {
# Formats BOOT_PART and LUKS_PART.
# If encryption is enabled (FDE='true'), then an encrypted partition will be created at LUKS_PART
# which can be accessed under DATA_PART.
# If encryption is disabled, then DATA_PART is identical to LUKS_PART.
#
# @pre # @pre
# BOOT_FIRMWARE # BOOT_FIRMWARE
# BOOT_PART # BOOT_PART
# LUKS_PART # LUKS_PART
# LUKS_PWD # LUKS_PWD
# FDE: 'true' | 'false'
# FS # FS
# @post # @post
# LUKS_PART_UUID # LUKS_PART_UUID: only set if FDE='true'
# DATA_PART (variable set with value /dev/mapper/$(basename "${LUKS_PART}") # DATA_PART: if FDE='true', then set to /dev/mapper/$(basename "${LUKS_PART}")
# boot partition formatted # boot partition formatted
# luks partition formatted and opened at DATA_PART # luks partition formatted and accessible under DATA_PART
echo 'Wiping old signatures from partitions ...' echo 'Wiping old signatures from partitions ...'
sudo wipefs "${BOOT_PART}" || return $? sudo wipefs "${BOOT_PART}" || return $?
@ -130,22 +140,33 @@ function format() {
echo 'Formatting boot partition '"${BOOT_PART}"' ...' echo 'Formatting boot partition '"${BOOT_PART}"' ...'
sudo mkfs.fat -F32 "${BOOT_PART}" || return $? sudo mkfs.fat -F32 "${BOOT_PART}" || return $?
# Note: case "${FDE}" in
# FDE: GRUB does support LUKS2 since this commit: https://git.savannah.gnu.org/cgit/grub.git/commit/?id=365e0cc3e7e44151c14dd29514c2f870b49f9755 true)
# -> Using "--type luks1" is no longer required. # Note:
echo 'Creating encrypted luks partition '"${LUKS_PART}"' ...' # FDE: GRUB does support LUKS2 since this commit: https://git.savannah.gnu.org/cgit/grub.git/commit/?id=365e0cc3e7e44151c14dd29514c2f870b49f9755
printf '%s' "${LUKS_PWD}" | sudo cryptsetup luksFormat \ # -> Using "--type luks1" is no longer required.
--cipher aes-xts-plain64 --key-size 512 --hash sha512 \ echo 'Creating encrypted luks partition '"${LUKS_PART}"' ...'
--iter-time 10000 --use-random "${LUKS_PART}" || return $? printf '%s' "${LUKS_PWD}" | sudo cryptsetup luksFormat \
--cipher aes-xts-plain64 --key-size 512 --hash sha512 \
--iter-time 10000 --use-random "${LUKS_PART}" || return $?
get_uuid "${LUKS_PART}" LUKS_PART_UUID || return $? get_uuid "${LUKS_PART}" LUKS_PART_UUID || return $?
local luks_name local luks_name
luks_name=$(basename "${LUKS_PART}") luks_name=$(basename "${LUKS_PART}")
DATA_PART="/dev/mapper/${luks_name}" DATA_PART="/dev/mapper/${luks_name}"
# open luks partition # open luks partition
printf '%s' "${LUKS_PWD}" | sudo cryptsetup luksOpen "${LUKS_PART}" "${luks_name}" || return $? printf '%s' "${LUKS_PWD}" | sudo cryptsetup luksOpen "${LUKS_PART}" "${luks_name}" || return $?
;;
false)
DATA_PART="${LUKS_PART}"
;;
*)
echo 'Invalid option: '"${FDE}"
return 1
;;
esac
echo 'Formatting the data partition '"${DATA_PART}"' ...' echo 'Formatting the data partition '"${DATA_PART}"' ...'
case "${FS}" in case "${FS}" in