aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-01-24 05:33:13 -0600
committerCraig Jennings <c@cjennings.net>2026-01-24 05:33:13 -0600
commitc55ce46084635c188abb4516ba6ee6eee38dd11d (patch)
tree638c4f4ceb62d33766908cf8600b3aca2ecef435
parente1af2bdaad875dab8661fce03dc6b5adb503d0ff (diff)
downloadarchangel-c55ce46084635c188abb4516ba6ee6eee38dd11d.tar.gz
archangel-c55ce46084635c188abb4516ba6ee6eee38dd11d.zip
Phase 2.8: Add LUKS encryption for btrfs
- Add LUKS functions to btrfs.sh (create/open/close container) - Add crypttab configuration for boot - Add encrypt hook to mkinitcpio HOOKS - Add cryptdevice parameter to GRUB cmdline - Add get_btrfs_encryption_choice and get_luks_passphrase prompts - Add LUKS_PASSPHRASE to config variables - Update show_summary and print_btrfs_summary for encryption status - Add btrfs-luks.conf test config VM test pending.
-rwxr-xr-xcustom/archangel103
-rw-r--r--custom/lib/btrfs.sh90
-rw-r--r--custom/lib/config.sh1
-rw-r--r--docs/session-context.org19
-rw-r--r--scripts/test-configs/btrfs-luks.conf15
5 files changed, 213 insertions, 15 deletions
diff --git a/custom/archangel b/custom/archangel
index c887a4d..ba0c94e 100755
--- a/custom/archangel
+++ b/custom/archangel
@@ -117,6 +117,13 @@ gather_input() {
fi
fi
+ # Btrfs-specific validation
+ if [[ "$FILESYSTEM" == "btrfs" ]]; then
+ if [[ "$NO_ENCRYPT" != "yes" && -z "$LUKS_PASSPHRASE" ]]; then
+ error "Config missing required: LUKS_PASSPHRASE (or set NO_ENCRYPT=yes)"
+ fi
+ fi
+
# Validate filesystem choice
if [[ "$FILESYSTEM" != "zfs" && "$FILESYSTEM" != "btrfs" ]]; then
error "Invalid FILESYSTEM: $FILESYSTEM (must be 'zfs' or 'btrfs')"
@@ -165,9 +172,8 @@ gather_input() {
get_encryption_choice
[[ "$NO_ENCRYPT" != "yes" ]] && get_zfs_passphrase
elif [[ "$FILESYSTEM" == "btrfs" ]]; then
- # Btrfs encryption (LUKS) not yet implemented - Phase 2.8
- info "Note: Btrfs encryption (LUKS) will be available in a future update."
- NO_ENCRYPT="yes"
+ get_btrfs_encryption_choice
+ [[ "$NO_ENCRYPT" != "yes" ]] && get_luks_passphrase
fi
get_root_password
@@ -545,6 +551,58 @@ get_wifi() {
fi
}
+get_btrfs_encryption_choice() {
+ step "Btrfs Encryption (LUKS)"
+
+ echo ""
+ echo "LUKS encryption protects your data at rest."
+ echo "You'll need to enter a passphrase at each boot."
+ echo ""
+
+ prompt "Enable LUKS encryption? [Y/n]:"
+ read -p "> " encrypt_choice
+
+ if [[ "$encrypt_choice" =~ ^[Nn]$ ]]; then
+ NO_ENCRYPT="yes"
+ warn "Encryption DISABLED - data will not be encrypted at rest"
+ else
+ NO_ENCRYPT="no"
+ info "LUKS encryption enabled - you'll set a passphrase next"
+ fi
+}
+
+get_luks_passphrase() {
+ step "LUKS Encryption Passphrase"
+
+ echo ""
+ echo "Choose a strong passphrase for disk encryption."
+ echo "You'll need this passphrase every time you boot."
+ echo ""
+ echo "IMPORTANT: If you forget this passphrase, your data is UNRECOVERABLE!"
+ echo ""
+
+ while true; do
+ prompt "Enter LUKS encryption passphrase:"
+ read -rs LUKS_PASSPHRASE
+ echo ""
+
+ prompt "Confirm passphrase:"
+ read -rs confirm
+ echo ""
+
+ if [[ "$LUKS_PASSPHRASE" == "$confirm" ]]; then
+ if [[ ${#LUKS_PASSPHRASE} -lt 8 ]]; then
+ warn "Passphrase should be at least 8 characters. Try again."
+ else
+ info "Passphrase confirmed."
+ break
+ fi
+ else
+ warn "Passphrases don't match. Try again."
+ fi
+ done
+}
+
get_encryption_choice() {
step "ZFS Encryption"
echo ""
@@ -667,6 +725,11 @@ show_summary() {
fi
echo " Boot: ZFSBootMenu on all disks (redundant)"
else
+ if [[ "$NO_ENCRYPT" == "yes" ]]; then
+ echo " Encryption: None"
+ else
+ echo " Encryption: LUKS2"
+ fi
echo " Boot: GRUB + grub-btrfs (snapshot boot)"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@@ -1452,6 +1515,11 @@ print_btrfs_summary() {
echo " Hostname: $HOSTNAME"
echo " Timezone: $TIMEZONE"
echo " Filesystem: Btrfs"
+ if [[ "$NO_ENCRYPT" == "yes" ]]; then
+ echo " Encryption: None"
+ else
+ echo " Encryption: LUKS2"
+ fi
echo ""
echo "Btrfs Snapshot Features:"
echo " - Boot from any snapshot via GRUB menu"
@@ -1531,15 +1599,25 @@ install_btrfs() {
# Get partition references
local root_part=$(get_root_partition "${SELECTED_DISKS[0]}")
local efi_part=$(get_efi_partition "${SELECTED_DISKS[0]}")
+ local btrfs_device="$root_part"
# Partition and format
partition_disk "${SELECTED_DISKS[0]}"
format_efi "$efi_part"
- create_btrfs_volume "$root_part"
+
+ # LUKS encryption (if enabled)
+ if [[ "$NO_ENCRYPT" != "yes" ]]; then
+ create_luks_container "$root_part" "$LUKS_PASSPHRASE"
+ open_luks_container "$root_part" "$LUKS_PASSPHRASE"
+ btrfs_device="/dev/mapper/$LUKS_MAPPER_NAME"
+ fi
+
+ # Create btrfs on the device (raw partition or LUKS mapper)
+ create_btrfs_volume "$btrfs_device"
# Create and mount subvolumes
- create_btrfs_subvolumes "$root_part"
- mount_btrfs_subvolumes "$root_part"
+ create_btrfs_subvolumes "$btrfs_device"
+ mount_btrfs_subvolumes "$btrfs_device"
# Mount EFI
mkdir -p /mnt/efi
@@ -1552,7 +1630,15 @@ install_btrfs() {
configure_system
configure_wifi
configure_ssh
- generate_btrfs_fstab "$root_part" "$efi_part"
+
+ # Configure encryption if enabled
+ if [[ "$NO_ENCRYPT" != "yes" ]]; then
+ configure_crypttab "$root_part"
+ configure_luks_grub "$root_part"
+ configure_luks_initramfs
+ fi
+
+ generate_btrfs_fstab "$btrfs_device" "$efi_part"
configure_btrfs_initramfs
configure_grub "$efi_part"
configure_snapper
@@ -1565,6 +1651,9 @@ install_btrfs() {
# Cleanup
btrfs_cleanup
+ if [[ "$NO_ENCRYPT" != "yes" ]]; then
+ close_luks_container
+ fi
print_btrfs_summary
}
diff --git a/custom/lib/btrfs.sh b/custom/lib/btrfs.sh
index 7da0851..47c6f42 100644
--- a/custom/lib/btrfs.sh
+++ b/custom/lib/btrfs.sh
@@ -3,9 +3,12 @@
# Source this file after common.sh, config.sh, disk.sh
#############################
-# Btrfs Constants
+# Btrfs/LUKS Constants
#############################
+# LUKS settings
+LUKS_MAPPER_NAME="cryptroot"
+
# Mount options for btrfs subvolumes
BTRFS_OPTS="noatime,compress=zstd,space_cache=v2,discard=async"
@@ -25,6 +28,91 @@ BTRFS_SUBVOLS=(
)
#############################
+# LUKS Functions
+#############################
+
+create_luks_container() {
+ local partition="$1"
+ local passphrase="$2"
+
+ step "Creating LUKS Encrypted Container"
+
+ info "Setting up LUKS encryption on $partition..."
+
+ # Create LUKS container
+ echo -n "$passphrase" | cryptsetup luksFormat --type luks2 \
+ --cipher aes-xts-plain64 --key-size 512 --hash sha512 \
+ --iter-time 2000 --pbkdf argon2id \
+ "$partition" - \
+ || error "Failed to create LUKS container"
+
+ info "LUKS container created."
+}
+
+open_luks_container() {
+ local partition="$1"
+ local passphrase="$2"
+ local name="${3:-$LUKS_MAPPER_NAME}"
+
+ info "Opening LUKS container..."
+
+ echo -n "$passphrase" | cryptsetup open "$partition" "$name" - \
+ || error "Failed to open LUKS container"
+
+ info "LUKS container opened as /dev/mapper/$name"
+}
+
+close_luks_container() {
+ local name="${1:-$LUKS_MAPPER_NAME}"
+
+ cryptsetup close "$name" 2>/dev/null || true
+}
+
+configure_crypttab() {
+ local partition="$1"
+
+ step "Configuring crypttab"
+
+ local uuid
+ uuid=$(blkid -s UUID -o value "$partition")
+
+ # Create crypttab entry
+ echo "# LUKS encrypted root" > /mnt/etc/crypttab
+ echo "$LUKS_MAPPER_NAME UUID=$uuid none luks,discard" >> /mnt/etc/crypttab
+
+ info "crypttab configured for $LUKS_MAPPER_NAME"
+}
+
+configure_luks_initramfs() {
+ step "Configuring Initramfs for LUKS"
+
+ # Backup original
+ cp /mnt/etc/mkinitcpio.conf /mnt/etc/mkinitcpio.conf.bak
+
+ # Add encrypt hook before filesystems
+ # Hooks: base udev ... keyboard keymap ... encrypt filesystems ...
+ sed -i 's/^HOOKS=.*/HOOKS=(base udev microcode modconf kms keyboard keymap consolefont block encrypt filesystems fsck)/' \
+ /mnt/etc/mkinitcpio.conf
+
+ info "Added encrypt hook to initramfs."
+}
+
+configure_luks_grub() {
+ local partition="$1"
+
+ step "Configuring GRUB for LUKS"
+
+ local uuid
+ uuid=$(blkid -s UUID -o value "$partition")
+
+ # Add cryptdevice to GRUB cmdline
+ sed -i "s|^GRUB_CMDLINE_LINUX=\"|GRUB_CMDLINE_LINUX=\"cryptdevice=UUID=$uuid:$LUKS_MAPPER_NAME:allow-discards |" \
+ /mnt/etc/default/grub
+
+ info "GRUB configured with cryptdevice parameter."
+}
+
+#############################
# Btrfs Pre-flight
#############################
diff --git a/custom/lib/config.sh b/custom/lib/config.sh
index 38811fa..358a5f4 100644
--- a/custom/lib/config.sh
+++ b/custom/lib/config.sh
@@ -21,6 +21,7 @@ WIFI_SSID=""
WIFI_PASSWORD=""
ENCRYPTION_ENABLED=false
ZFS_PASSPHRASE=""
+LUKS_PASSPHRASE=""
ROOT_PASSWORD=""
SSH_ENABLED=false
SSH_KEY=""
diff --git a/docs/session-context.org b/docs/session-context.org
index e5aea93..b193721 100644
--- a/docs/session-context.org
+++ b/docs/session-context.org
@@ -38,20 +38,25 @@
- [X] Genesis snapshot can be created
- [X] grub-btrfs detects snapshots
-**** Issues Fixed During Testing
-1. GRUB couldn't find normal.mod - added proper boot-directory config
-2. GRUB_BTRFS_GRUB_DIRNAME was wrong - removed, use default
-3. HEREDOC not working in remote execution - switched to echo
-4. Snapper needs D-Bus - firstboot service approach
-5. rootflags=subvol=@ was duplicated - grub-mkconfig adds it
+*** Phase 2.8: LUKS Encryption (IMPLEMENTED @ 05:36 CST)
+- [X] LUKS functions in btrfs.sh (create, open, close containers)
+- [X] crypttab configuration
+- [X] encrypt hook for mkinitcpio
+- [X] GRUB cryptdevice parameter
+- [X] Encryption prompts in archangel
+- [X] LUKS_PASSPHRASE config variable
+- [X] btrfs-luks.conf test config
+- [ ] VM test pending
** Commits This Session
- a49f4b1: Phase 2.1: Implement btrfs support
- 35a661c: Fix btrfs bugs from VM testing
- bd0616c: Fix btrfs GRUB boot and snapper firstboot
+- 4a7b6c3: Update session context: Phase 2.7 complete
+- (pending): Phase 2.8: Add LUKS encryption for btrfs
** Next Steps
-1. Phase 2.8: LUKS encryption for btrfs
+1. VM test LUKS btrfs installation
2. Rebuild ISO with all fixes
3. Full end-to-end automated test
4. Phase 3: Multi-disk support
diff --git a/scripts/test-configs/btrfs-luks.conf b/scripts/test-configs/btrfs-luks.conf
new file mode 100644
index 0000000..5eee46d
--- /dev/null
+++ b/scripts/test-configs/btrfs-luks.conf
@@ -0,0 +1,15 @@
+# Test config: Btrfs single disk with LUKS encryption
+
+HOSTNAME=test-btrfs-luks
+TIMEZONE=UTC
+LOCALE=en_US.UTF-8
+KEYMAP=us
+
+FILESYSTEM=btrfs
+DISKS=/dev/vda
+
+LUKS_PASSPHRASE=testpassphrase
+
+ROOT_PASSWORD=testpass
+
+ENABLE_SSH=yes