From cf50632b6ca98912fff6b67df81c6236cacb59df Mon Sep 17 00:00:00 2001
From: hygienic-books <hygienic-books@tentic.net>
Date: Fri, 27 Oct 2023 04:23:11 +0200
Subject: [PATCH 1/3] feat(iso): Allow supplementary password/settings file
 (#9)

---
 README.md | 23 +++++++++++++++++++++--
 setup.sh  | 29 +++++++++++++++++++++++++++--
 2 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 5e863d7..3dfa625 100644
--- a/README.md
+++ b/README.md
@@ -117,12 +117,31 @@ To get a zpool with unencrypted datasets export the shell variable `ARCHZBM_ZFSP
 export ARCHZBM_ZFSPROPS_NO_ENCRYPTION=yup
 ```
 
+### Passwords
+
+By default both the zpool password and the account password for `root` are literally `password`. While you can certainly change these after initial system setup you can also optionally set these passwords in a settings file named `archzbm_settings.env` that lives in your current working directory where you're about to execute the script. File format is identical to shell variable assignments of the form `VAR=value` or `VAR='value'`.
+
+If `./archzbm_settings.env` exists the script will `source` its content and `export` all variables for use in future steps. Only known variables are:
+
+```
+ARCHZBM_ZPOOL_PASSWORD='a fancy password'
+ARCHZBM_ROOT_PASSWORD='t0psecr3t!'
+```
+
+The script does create a second user named `build` but doesn't set a password on account creation. As such no password variable can be set for it in `./archzbm_settings.env`. It's intended as a helper for system setup tasks such as `sudo -u build paru -S <package>` where an account password is irrelevant since `root` can always `sudo` whatever it wants. You will not be able to log in to the `build` account yourself although you certainly could set a password for it. Instead we suggest you create a proper user account for yourself. Your newly installed Arch Linux comes with an `/etc/motd` greeting that summarizes this as:
+
+```
+useradd --create-home --shell /bin/bash --user-group --groups wheel <user>
+passwd <user>
+```
+
 # Steps
 
 The script takes the following installation steps.
 
 1. Install ZFS tools and kernel module with [github.com/eoli3n/archiso-zfs](https://github.com/eoli3n/archiso-zfs)
 1. Create one ZFS zpool on top of zpool partition, encrypted and compressed datasets, password `password`
+    1. _See paragraph [Passwords](#passwords) to predefine your own passwords in a settings file_
     1. _See paragraphs [Compression](#compression)/[Encryption](#encryption) to optionally disable properties_
 1. Create dataset for Arch Linux and `/home`
 1. Install Arch Linux into pool
@@ -156,7 +175,7 @@ After installation you're going to want to at least touch these points in your n
 - Hostname: Installation chose a pseudo-randomly generated 8-character string with `pwgen`
     - Check `hostnamectl set-hostname <hostname>`
 - Unprivileged user accounts: The OS was installed with `root` and unprivileged `build` users
-- Passwords
+- Unless you had a settings file per [Passwords](#passwords) you're going to want to change passwords now:
     - ZFS: The password for all datasets underneath `zpool` is `password`.
     - Local `root` account: The local `root` account's password is `password`.
 - Arch User Repository (AUR) helper: We installed [paru](https://github.com/Morganamilo/paru) as our AUR helper, we installed from GitHub via `makepkg -si` then replaced itself with its [paru-bin](https://aur.archlinux.org/packages/paru-bin) version from AUR.
@@ -193,7 +212,7 @@ After installation you're going to want to at least touch these points in your n
 
 # Password change
 
-After installation you're going to want to change your ZFS encryption password.
+After installation you're going to want to change your ZFS encryption password (unless you preconfigured a good zpool password in a settings file per [Passwords](#passwords)). At any rate you still want to be familiar with the process and its caveat in case you ever need a zpool password change or want to do one now.
 
 ## Steps
 
diff --git a/setup.sh b/setup.sh
index 03dde5d..3a18cfb 100644
--- a/setup.sh
+++ b/setup.sh
@@ -256,8 +256,14 @@ function no_zpool_exists () {
 }
 
 function set_zpool_password () {
+    local zpool_password
+    if [[ "${ARCHZBM_ZPOOL_PASSWORD}" ]]; then
+        zpool_password="${ARCHZBM_ZPOOL_PASSWORD}"
+    else
+        zpool_password='password'
+    fi
     # May or may not have a newline at the end, ZFS doesn't care
-    printf -- '%s' 'password' > '/etc/zfs/'"${zpool_name}"'.key'
+    printf -- '%s' "${zpool_password}" > '/etc/zfs/'"${zpool_name}"'.key'
     chmod '000' '/etc/zfs/'"${zpool_name}"'.key'
 }
 
@@ -319,6 +325,18 @@ function export_pool () {
     zpool export "${zpool_name}"
 }
 
+function load_settings_file () {
+    local working_dir settings_file settings_abs
+    working_dir="$(pwd)"
+    settings_file='archzbm_settings.env'
+    settings_abs="${working_dir}"'/'"${settings_file}"
+    if [[ -r "${settings_abs}" ]]; then
+        set -a
+        source "${settings_abs}"
+        set +a
+    fi
+}
+
 function setup_zpool () {
     #1.8
     local drive_by_id
@@ -764,7 +782,13 @@ function install_os_in_chroot () {
 
 function set_root_pw () {
     #3.2
-    printf -- '%s\n' 'root:password' | chpasswd --crypt-method 'SHA512' --root '/mnt'
+    local root_password
+    if [[ "${ARCHZBM_ROOT_PASSWORD}" ]]; then
+        root_password="${ARCHZBM_ROOT_PASSWORD}"
+    else
+        root_password='password'
+    fi
+    printf -- '%s\n' 'root:'"${root_password}" | chpasswd --crypt-method 'SHA512' --root '/mnt'
 }
 
 function configure_networking () {
@@ -893,6 +917,7 @@ function main () {
         install_pkgs 'jq'                       #1.5
         install_zfs                             #1.6
         uefi_or_bios                            #1.7
+        load_settings_file
         setup_zpool                             #1.8
         mount_system                            #1.9
         copy_zpool_cache                        #1.10
-- 
2.47.2


From 5d03799dae7e38b6b2066262c35c69f0964af8b1 Mon Sep 17 00:00:00 2001
From: hygienic-books <hygienic-books@tentic.net>
Date: Fri, 27 Oct 2023 04:24:40 +0200
Subject: [PATCH 2/3] refactor(meta): Renumber functions (#9)

---
 setup.sh | 43 ++++++++++++++++++++++---------------------
 1 file changed, 22 insertions(+), 21 deletions(-)

diff --git a/setup.sh b/setup.sh
index 3a18cfb..fb31a51 100644
--- a/setup.sh
+++ b/setup.sh
@@ -326,6 +326,7 @@ function export_pool () {
 }
 
 function load_settings_file () {
+    #1.8
     local working_dir settings_file settings_abs
     working_dir="$(pwd)"
     settings_file='archzbm_settings.env'
@@ -338,7 +339,7 @@ function load_settings_file () {
 }
 
 function setup_zpool () {
-    #1.8
+    #1.9
     local drive_by_id
     zpool_drive="$(select_part 'zfs')"
     drive_by_id="$(get_drive_id "${zpool_drive}")"
@@ -358,7 +359,7 @@ function setup_zpool () {
 }
 
 function mount_system () {
-    #1.9
+    #1.10
     zfs mount "${zpool_name}"'/root/'"${zfs_arch_dataset_name}"
     zfs mount -a
 
@@ -381,7 +382,7 @@ function mount_system () {
 }
 
 function copy_zpool_cache () {
-    #1.10
+    #1.11
     mkdir -p '/mnt/etc/zfs'
     zpool set 'cachefile=/etc/zfs/'"${zpool_name}"'.cache' "${zpool_name}"
 }
@@ -401,7 +402,7 @@ function pacman_dont_check_space () {
 }
 
 function install_archlinux () {
-    #1.11
+    #1.12
     pacman_dl_parallel
     pacman_dont_check_space
     pacstrap /mnt              \
@@ -428,7 +429,7 @@ function install_archlinux () {
 }
 
 function gen_fstab () {
-    #1.12
+    #1.13
     genfstab -U /mnt | grep -v "${zpool_name}" | tr -s '\n' | sed -r -e 's/\/mnt//' -e '/./,$!d' > '/mnt/etc/fstab'
 }
 
@@ -441,7 +442,7 @@ EOF
 }
 
 function set_hostname () {
-    #1.13
+    #1.14
     declare new_hostname
     install_pkgs 'pwgen'
     new_hostname="$(pwgen --no-numerals --no-capitalize --ambiguous 8)"
@@ -450,7 +451,7 @@ function set_hostname () {
 }
 
 function set_locale () {
-    #1.14
+    #1.15
     printf -- '%s\n' \
         'KEYMAP=de-latin1' \
         'FONT=Lat2-Terminus16' \
@@ -461,7 +462,7 @@ function set_locale () {
 }
 
 function add_zfs_hook_to_initramfs () {
-    #1.15
+    #1.16
     # Add zfs hook, remove fsck hook from initramfs.
     sed -ri \
         -e 's'$'\x1''(HOOKS=)(.*?[\(| ])(filesystems)([\)| ][^\r\n\f]*)'$'\x1''\1\2zfs \3\4'$'\x1''g' \
@@ -476,7 +477,7 @@ function add_zfs_hook_to_initramfs () {
 }
 
 function set_initramfs_build_list () {
-    #1.16
+    #1.17
     # No need to build fallback initramfs, our new fallback is ZFS snapshots
     sed -ri \
         -e '/^#/d' \
@@ -490,7 +491,7 @@ function set_initramfs_build_list () {
 }
 
 function add_zfs_files_to_new_os () {
-    #1.17
+    #1.18
     for zfs_file in '/etc/hostid' '/etc/zfs/zpool.cache' $([[ ! "${ARCHZBM_ZFSPROPS_NO_ENCRYPTION}" ]] && printf -- '%s' '/etc/zfs/'"${zpool_name}"'.key'); do
         rsync -av --itemize-changes {'','/mnt'}"${zfs_file}"
     done
@@ -917,17 +918,17 @@ function main () {
         install_pkgs 'jq'                       #1.5
         install_zfs                             #1.6
         uefi_or_bios                            #1.7
-        load_settings_file
-        setup_zpool                             #1.8
-        mount_system                            #1.9
-        copy_zpool_cache                        #1.10
-        install_archlinux                       #1.11
-        gen_fstab                               #1.12
-        set_hostname                            #1.13
-        set_locale                              #1.14
-        add_zfs_hook_to_initramfs               #1.15
-        set_initramfs_build_list                #1.16
-        add_zfs_files_to_new_os                 #1.17
+        load_settings_file                      #1.8
+        setup_zpool                             #1.9
+        mount_system                            #1.10
+        copy_zpool_cache                        #1.11
+        install_archlinux                       #1.12
+        gen_fstab                               #1.13
+        set_hostname                            #1.14
+        set_locale                              #1.15
+        add_zfs_hook_to_initramfs               #1.16
+        set_initramfs_build_list                #1.17
+        add_zfs_files_to_new_os                 #1.18
         enter_chroot                            #2.1
         # We're done in chroot
         finalize_os_setup                       #3.1
-- 
2.47.2


From d1ad95dc76782b28fb690e2750876b75d1b592c1 Mon Sep 17 00:00:00 2001
From: hygienic-books <hygienic-books@tentic.net>
Date: Fri, 27 Oct 2023 05:02:53 +0200
Subject: [PATCH 3/3] docs(meta): Explain password requirement (#5)

---
 README.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/README.md b/README.md
index 3dfa625..e5bd158 100644
--- a/README.md
+++ b/README.md
@@ -128,6 +128,8 @@ ARCHZBM_ZPOOL_PASSWORD='a fancy password'
 ARCHZBM_ROOT_PASSWORD='t0psecr3t!'
 ```
 
+> While the `root` password may be weak and `chpasswd` won't care do make sure to set a zpool password that meets ZFS' complexity rules. Per `man 7 zfsprops` section `keyformat` the only requirement is a length "between 8 and 512 bytes" (as in minimum 8 characters). If you pick a password that's too weak ZFS will reject zpool creation and very ungracefully derail the rest of this script. The script doesn't check what you're setting.
+
 The script does create a second user named `build` but doesn't set a password on account creation. As such no password variable can be set for it in `./archzbm_settings.env`. It's intended as a helper for system setup tasks such as `sudo -u build paru -S <package>` where an account password is irrelevant since `root` can always `sudo` whatever it wants. You will not be able to log in to the `build` account yourself although you certainly could set a password for it. Instead we suggest you create a proper user account for yourself. Your newly installed Arch Linux comes with an `/etc/motd` greeting that summarizes this as:
 
 ```
-- 
2.47.2