[arch-projects] [RFC 19/23] Add Arch Linux mkinitcpio hook for encrypted volumes

Matthew Monaco dgbaley27 at 0x01b.net
Fri May 18 12:22:13 EDT 2012


From: Matthew Monaco <matthew.monaco at 0x01b.net>

This should support all of the current syntax. If that sentance is
false, please let me know. This might be a good time to drop support for
root=... without a cryptdevice=...?

We'll support root, /usr, and anything tagged with %early in crypttab
---
 archlinux/encrypt_hook    |  100 +++++++++++++++++++++++++++++++++++++++++++++
 archlinux/encrypt_install |   56 +++++++++++++++++++++++++
 2 files changed, 156 insertions(+)
 create mode 100644 archlinux/encrypt_hook
 create mode 100644 archlinux/encrypt_install

diff --git a/archlinux/encrypt_hook b/archlinux/encrypt_hook
new file mode 100644
index 0000000..026c731
--- /dev/null
+++ b/archlinux/encrypt_hook
@@ -0,0 +1,100 @@
+
+encrypt_main() {
+
+	local tmp="$1" name="" dev="" key="${2:--}" opts="" log="" tab="${3:-/etc/crypttab}"
+
+	case "$tmp" in
+		*:*:*)
+			dev="${tmp%%:*}"
+			tmp="${tmp#*:}"
+			name="${tmp%%:*}"
+			opts="${tmp#*:}"
+			;;
+		*:*)
+			dev="${tmp%%:*}"
+			name="${tmp#*:}"
+			;;
+		*)
+			name="$tmp"
+			;;
+	esac
+
+	if [ "$quiet" ]; then
+		log="-q"
+	elif [ "$verbose" ]; then
+		log="-v"
+	fi
+
+	[ -e "/dev/mapper/$name" ] && return
+
+	msg "Mapping encrypted volume '$name'"
+
+	if [ "$dev" ]; then
+		cryptmount $log -O "$opts" -M "$name" "$dev" "$key"
+	else
+		cryptmount -c "$tab" $log -M "$name" 
+	fi
+}
+
+run_hook() {
+
+	local vol vols
+
+	if [ -z "$cryptdevice" ]; then
+		printf "The syntax 'root=%s' where '%s' is an encrypted volume is deprecated" \
+		       "Use 'cryptdevice=%s:root root=/dev/mapper/root instead." \
+		       "$root" "$root" "$root"
+		cryptdevice="$root:root"
+		root="/dev/mapper/root"
+	fi
+
+	encrypt_main "$cryptdevice" "$cryptkey"
+}
+
+run_latehook() {
+
+	if [ "$cryptusr" ]; then
+		encrypt_main "$cryptusr" "$cryptusrkey" "/new_root/etc/crypttab"
+	fi
+	
+	if vols="$(cryptmount -c "/new_root/etc/fstab" -Lq -O "%early")" && [ "$vols" ]; then
+		for vol in $vols; do
+			[ -e "/dev/mapper/$vol" ] && continue
+			msg "Mapping encrypted volume '$vol'"
+			cryptmount -c "/new_root/etc/crypttab" -qM "$vol"
+		done
+	fi
+
+	if [ -z "$cryptusr" ]; then
+		cryptusr="$(encrypt_from_mp "/usr")" || return
+		[ -e "/dev/mapper/$cryptusr" ] && return
+		msg "Detected /usr as '$cryptusr'"
+		encrypt_main "$cryptusr"
+	fi
+}
+
+encrypt_from_mp() {
+	
+	local fstab="/new_root/etc/fstab" ctab="/new_root/etc/crypttab"
+	local line="" mp="$1" dev=""
+
+	[ -f "$fstab" -a -r "$fstab" ] || return 1
+	[ -f "$ctab"  -a -r "$ctab"  ] || return 1
+	[ "$mp" ] || return 1
+
+	if ! dev="$(findmnt -sF "$fstab" -cfno SOURCE -T "$mp")"; then
+		return 1
+	fi
+
+	case "$dev" in
+		/dev/mapper/*)
+			printf "%s" "$(basename "$dev")"
+			return
+			;;
+		*)
+			return 1
+			;;
+	esac
+}
+
+# vim: set ft=sh ts=4 sw=4 noet :
diff --git a/archlinux/encrypt_install b/archlinux/encrypt_install
new file mode 100644
index 0000000..f0faf05
--- /dev/null
+++ b/archlinux/encrypt_install
@@ -0,0 +1,56 @@
+build()
+{
+	add_module dm-crypt
+	if [ $CRYPTO_MODULES ]; then
+		add_all_modules $CRYPTO_MODULES
+	else
+		add_all_modules "/crypto/"
+	fi
+
+	add_runscript
+
+	add_binary "cryptmount"
+	add_binary "cryptsetup"
+	add_binary "dmsetup"
+	add_binary "findmnt"
+
+	add_file "/etc/crypttab"
+
+	add_file "/usr/lib/udev/rules.d/10-dm.rules"
+	add_file "/usr/lib/udev/rules.d/13-dm-disk.rules"
+	add_file "/usr/lib/udev/rules.d/95-dm-notify.rules"
+	add_file "/usr/lib/initcpio/udev/11-dm-initramfs.rules" "/lib/udev/rules.d/11-dm-initramfs.rules"
+}
+
+help()
+{
+cat <<_EOF_
+  This hook will _always_ attempt to map an encrypted root device. It will also
+  map an encrypted /usr device and attempt to automatically detect one if not
+  explicitly defined. Finally, it will map all devices in /etc/crypttab that have
+  the "%early" tag. (The %early tag is not necessary for root and /usr).
+
+  The root device is defined with the 'cryptdevice' and 'cryptkey' options. If
+  they are defined as
+
+    cryptdevice=<device>:<name>[:opt1,opt2,...]
+    cryptkey=<device>[[:<fstype>]:<path>]
+
+  then no crypttab is needed and cryptkey has the exact same format and semantics
+  as the key field in crypttab(5). Otherwise, root may be defined as
+
+    cryptdevice=<name>
+
+  where <name> is used to find the volume definition in the crypttab ***which
+  was copied to your initrd during mkinitcpio(8)***. The cryptkey option is
+  ignored.
+
+  For /usr, similar rules apply, using the 'cryptusr' and 'cryptkey' options. If
+  cryptusr is not defined, this hook will attempt to discover the correct volume
+  by looking in fstab (your /usr definition must be for /dev/mapper/<name> for
+  this to work).
+
+_EOF_
+}
+
+# vim: set ft=sh noet :
-- 
1.7.10.2



More information about the arch-projects mailing list