summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author Eric Hameleers <alien@slackware.com>2016-01-22 15:15:17 +0100
committer Eric Hameleers <alien@slackware.com>2016-01-22 15:15:17 +0100
commitc4e4112bdc8aa5fe92d797ab77744d3bcd70caf9 (patch)
tree0ec836a54d4cf7eca147b887632e2583aad2680b
parent1f94ea9542d4c54340e8b138d32c16f5c02a764e (diff)
downloadliveslak-c4e4112bdc8aa5fe92d797ab77744d3bcd70caf9.tar.gz
liveslak-c4e4112bdc8aa5fe92d797ab77744d3bcd70caf9.tar.xz
Add support for a LUKS-encrypted /home in the USB Live version.
Using iso2usb.sh script's new '-c' parameter, you can define the size for a container file in the root of the USB stick's Linux partition. - The container file will be loop-mounted and LUKS-encrypted and the Live OS will mount the filesystem inside the container on /home/. - The LUKS passphrase will be defined when executing the 'iso2usb.sh' script. - The original /home content of the ISO will be copied into the LUKS-encrypted container during execution of the 'iso2usb.sh' script. - If for whatever reason you do not want to unlock & mount the LUKS container during boot, you must add the boot parameter " luksvol= " to the syslinux or grub commandline.
-rw-r--r--iso2usb.sh205
-rwxr-xr-xliveinit56
-rwxr-xr-xmake_slackware_live.sh9
3 files changed, 234 insertions, 36 deletions
diff --git a/iso2usb.sh b/iso2usb.sh
index 680fc29..e9c27dd 100644
--- a/iso2usb.sh
+++ b/iso2usb.sh
@@ -39,10 +39,17 @@ VERBOSE=0
# Seconds to add to the initrd as wait-for-root value:
WAIT=5
+# No LUKS encryption by default:
+DOLUKS=0
+CNTDEV=""
+CNTFILE=""
+LODEV=""
+
# Define ahead of time, so that cleanup knows about them:
IMGDIR=""
EFIMNT=""
ISOMNT=""
+LKSMNT=""
USBMNT=""
#
@@ -56,8 +63,16 @@ cleanup() {
# During cleanup, do not abort due to non-zero exit code:
set +e
sync
+ if [ $DOLUKS -eq 1 ]; then
+ if mount |grep -q ${CNTDEV} ; then
+ umount -f ${CNTDEV}
+ cryptsetup luksClose ${CNTBASE}
+ losetup -d ${LODEV}
+ fi
+ fi
[ -n "${EFIMNT}" ] && ( /sbin/umount -f ${EFIMNT} 2>/dev/null; rmdir $EFIMNT )
[ -n "${ISOMNT}" ] && ( /sbin/umount -f ${ISOMNT} 2>/dev/null; rmdir $ISOMNT )
+ [ -n "${LKSMNT}" ] && ( /sbin/umount -f ${LKSMNT} 2>/dev/null; rmdir $LKSMNT )
[ -n "${USBMNT}" ] && ( /sbin/umount -f ${USBMNT} 2>/dev/null; rmdir $USBMNT )
[ -n "${IMGDIR}" ] && ( rm -rf $IMGDIR )
set -e
@@ -75,30 +90,38 @@ cat <<EOT
# This data will be *erased* !
#
# $(basename $0) accepts the following parameters:
-# -f|--force Ignore most warnings (except the back-out)
-# -h|--help This help
-# -i|--infile <filename> Full path to the ISO image file
-# -o|--outdev <filename> The device name of your USB drive
-# -p|--persistence <dirname> Custom name of the 'persistence' directory
-# -u|--unattended Do not ask any questions
-# -v|--verbose Show verbose messages
-# -w|--wait<number> Pause boot <number> seconds to initialize USB
+# -c|--crypt size|perc Add LUKS encrypted /home ; parameter is the
+# requested size of the container in kB, MB, GB,
+# or as a percentage of free space.
+# Examples: '-c 125M', '-c 1.3G', '-c 20%'.
+# -f|--force Ignore most warnings (except the back-out).
+# -h|--help This help.
+# -i|--infile <filename> Full path to the ISO image file.
+# -o|--outdev <filename> The device name of your USB drive.
+# -p|--persistence <dirname> Custom name of the 'persistence' directory.
+# -u|--unattended Do not ask any questions.
+# -v|--verbose Show verbose messages.
+# -w|--wait<number> Add <number> seconds wait time to initialize USB.
#
-# Example:
+# Examples:
#
# $(basename $0) -i ~/download/slackware64-live-14.2.iso -o /dev/sdX
+# $(basename $0) -i slackware64-live-xfce-current.iso -o /dev/sdX -c 750M -w 15
#
EOT
}
# Add longer USB WAIT to the initrd:
update_initrd() {
- # USB boot medium needs a few seconds boot delay else the overlay will fail.
+ IMGFILE="$1"
+ # USB boot medium needs a few seconds boot delay else the overlay will fail.
# Check if we need to update the wait-for-root file in the initrd:
- OLDWAIT=$(gunzip -cd ${USBMNT}/boot/initrd.img |cpio -i --to-stdout wait-for-root 2>/dev/null)
- [ "$OLDWAIT" = "$WAIT" ] && return
+ OLDWAIT=$(gunzip -cd ${IMGFILE} |cpio -i --to-stdout wait-for-root 2>/dev/null)
+ if [ "$OLDWAIT" = "$WAIT" -a $DOLUKS -eq 0 ]; then
+ return
+ fi
if [ -z "$IMGDIR" ]; then
# Create a temporary extraction directory for the initrd:
@@ -113,17 +136,120 @@ update_initrd() {
echo "--- Extracting Slackware initrd and adding rootdelay for USB..."
cd ${IMGDIR}
- gunzip -cd ${USBMNT}/boot/initrd.img \
+ gunzip -cd ${IMGFILE} \
| cpio -i -d -H newc --no-absolute-filenames
echo "--- Updating 'waitforroot' time from '$OLDWAIT' to '$WAIT':"
echo ${WAIT} > wait-for-root
+
+ if [ $DOLUKS -eq 1 ]; then
+ if ! grep -q ${CNTFILE} luksdev ; then
+ echo "--- Adding '${CNTFILE}' as LUKS /home:"
+ echo "${CNTFILE}" >> luksdev
+ fi
+ fi
+
echo "--- Compressing the initrd image again:"
chmod 0755 ${IMGDIR}
- find . |cpio -o -H newc |gzip > ${USBMNT}/boot/initrd.img
+ find . |cpio -o -H newc |gzip > ${IMGFILE}
cd - 2>/dev/null
rm -rf $IMGDIR/*
} # End of update_initrd()
+# Create a container file in the empty space of the partition
+create_container() {
+ CNTPART=$1
+ CNTSIZE=$2
+ CNTBASE=$3
+
+ # Determine size of the target partition (in MB), and the free space:
+ PARTSIZE=$(df -P -BM ${CNTPART} |tail -1 |tr -s '\t' ' ' |cut -d' ' -f2)
+ PARTSIZE=${PARTSIZE%M}
+ PARTFREE=$(df -P -BM ${CNTPART} |tail -1 |tr -s '\t' ' ' |cut -d' ' -f4)
+ PARTFREE=${PARTFREE%M}
+
+ if [ $PARTFREE -lt 10 ]; then
+ echo "** Free space on USB partition is less than 10 MB;"
+ echo "** Not creating a container file!"
+ exit 1
+ fi
+
+ # Determine requested container size (allow for '%|k|K|m|M|g|G' suffix):
+ case "${CNTSIZE: -1}" in
+ "%") CNTSIZE="$(( $PARTFREE * ${CNTSIZE%\%} / 100 ))" ;;
+ "k") CNTSIZE="$(( ${CNTSIZE%k} / 1024 ))" ;;
+ "K") CNTSIZE="$(( ${CNTSIZE%K} / 1024 ))" ;;
+ "m") CNTSIZE="${CNTSIZE%m}" ;;
+ "M") CNTSIZE="${CNTSIZE%M}" ;;
+ "g") CNTSIZE="$(( ${CNTSIZE%g} * 1024 ))" ;;
+ "G") CNTSIZE="$(( ${CNTSIZE%G} * 1024 ))" ;;
+ *) ;;
+ esac
+
+ if [ $CNTSIZE -le 0 ]; then
+ echo "** Container size must be larger than ZERO!"
+ echo "** Check your '-c' commandline parameter."
+ exit 1
+ elif [ $CNTSIZE -ge $PARTFREE ]; then
+ echo "** Not enough free space for container file!"
+ echo "** Check your '-c' commandline parameter."
+ exit 1
+ fi
+
+ # Create an empty container file (allow for previously created ones):
+ for III in $(seq 1 9); do
+ if [ ! -f $USBMNT/${CNTBASE}0${III} ]; then
+ break
+ fi
+ done
+ if [ $III -eq 9 ]; then
+ echo "*** You already have NINE container files? Please clean up first."
+ exit 1
+ else
+ echo "--- Creating ${CNTSIZE}MB container file using 'dd if=/dev/urandom', patience please..."
+ dd if=/dev/urandom of=$USBMNT/${CNTBASE}0${III}.img bs=1M count=$CNTSIZE
+ CNTFILE="${CNTBASE}0${III}.img"
+ fi
+
+ # Setup a loopback device that we can use with cryptsetup:
+ LODEV=$(losetup -f)
+ losetup $LODEV $USBMNT/${CNTBASE}0${III}.img
+ if [ $DOLUKS -eq 1 ]; then
+ # Format the loop device with LUKS:
+ echo "--- Encrypting the container file with LUKS; enter 'YES' and a passphrase..."
+ cryptsetup -y luksFormat $LODEV
+ # Unlock the LUKS encrypted container:
+ echo "--- Unlocking the LUKS container requires your passphrase again..."
+ cryptsetup luksOpen $LODEV ${CNTBASE}
+ CNTDEV=/dev/mapper/${CNTBASE}
+ else
+ CNTDEV=$LODEV
+ fi
+ # Format the now available block device with a linux fs:
+ mkfs.ext4 ${CNTDEV}
+ # Tune the ext4 filesystem:
+ tune2fs -m 0 -c 0 -i 0 ${CNTDEV}
+ # Create a mount point for the unlocked container:
+ LKSMNT=$(mktemp -d -p /mnt -t alienlks.XXXXXX)
+ if [ ! -d $LKSMNT ]; then
+ echo "*** Failed to create a temporary mount point for the LUKS container!"
+ exit 1
+ else
+ chmod 711 $LKSMNT
+ fi
+ # Copy the original /home content into the container:
+ echo "--- Copying /home from LiveOS to LUKS container..."
+ HOMESRC=$(find ${USBMNT} -name "0099-slackware_zzzconf*" |tail -1)
+ mount ${CNTDEV} ${LKSMNT}
+ unsquashfs -n -d ${LKSMNT}/temp ${HOMESRC} /home
+ mv ${LKSMNT}/temp/home/* ${LKSMNT}/
+ rm -rf ${LKSMNT}/temp
+ # And clean up after ourselves:
+ umount ${CNTDEV}
+ cryptsetup luksClose ${CNTBASE}
+ losetup -d ${LODEV}
+
+} # End of create_container() {
+
#
# -- end of function definitions --
#
@@ -135,6 +261,11 @@ if [ -z "$1" ]; then
fi
while [ ! -z "$1" ]; do
case $1 in
+ -c|--crypt)
+ LUKSSIZE="$2"
+ DOLUKS=1
+ shift 2
+ ;;
-f|--force)
FORCE=1
shift
@@ -203,7 +334,7 @@ fi
# Are all the required not-so-common add-on tools present?
PROG_MISSING=""
-for PROGN in blkid cpio extlinux fdisk gdisk iso-info mkdosfs sgdisk ; do
+for PROGN in blkid cpio extlinux fdisk gdisk iso-info mkdosfs sgdisk unsquashfs ; do
if ! PATH="/sbin:$PATH" which $PROGN 1>/dev/null 2>/dev/null ; then
PROG_MISSING="${PROG_MISSING}-- $PROGN\n"
fi
@@ -310,27 +441,12 @@ else
chmod 711 $USBMNT
fi
-# Loop-mount the ISO (or 1st partition if this is a hybrid ISO):
-/sbin/mount -o loop ${SLISO} ${ISOMNT}
-
-if [ $EFIBOOT -eq 1 ]; then
- # Mount the EFI partition and copy /EFI as well as /boot directories into it:
- /sbin/mount -t vfat -o shortname=mixed ${TARGET}2 ${USBMNT}
- mkdir -p ${USBMNT}/EFI/BOOT
- rsync -rlptD ${ISOMNT}/EFI/BOOT/* ${USBMNT}/EFI/BOOT/
- mkdir -p ${USBMNT}/boot
- rsync -rlptD ${ISOMNT}/boot/* ${USBMNT}/boot/
- # Add more USB WAIT seconds to the initrd:
- update_initrd ${USBMNT}/boot/initrd.img
-fi
-
-# No longer needed:
-/sbin/umount ${USBMNT}
-/sbin/umount ${EFIMNT}
-
# Mount the Linux partition:
/sbin/mount -t auto ${TARGET}3 ${USBMNT}
+# Loop-mount the ISO (or 1st partition if this is a hybrid ISO):
+/sbin/mount -o loop ${SLISO} ${ISOMNT}
+
# Copy the ISO content into the USB Linux partition:
echo "--- Copying files from ISO to USB... takes some time."
rsync -a ${RVERBOSE} --exclude=EFI ${ISOMNT}/* ${USBMNT}/
@@ -341,6 +457,11 @@ if [ -n "$VERSION" ]; then
echo "$VERSION" > ${USBMNT}/.isoversion
fi
+if [ $DOLUKS -eq 1 ]; then
+ # Create LUKS container file:
+ create_container ${TARGET}3 ${LUKSSIZE} slhome
+fi
+
# Add more USB WAIT seconds to the initrd:
update_initrd ${USBMNT}/boot/initrd.img
@@ -354,6 +475,24 @@ mv ${USBMNT}/boot/extlinux/isolinux.cfg ${USBMNT}/boot/extlinux/extlinux.conf
rm ${USBMNT}/boot/extlinux/isolinux.*
/sbin/extlinux --install ${USBMNT}/boot/extlinux
+# No longer needed:
+/sbin/umount ${USBMNT}
+
+if [ $EFIBOOT -eq 1 ]; then
+ # Mount the EFI partition and copy /EFI as well as /boot directories into it:
+ /sbin/mount -t vfat -o shortname=mixed ${TARGET}2 ${USBMNT}
+ mkdir -p ${USBMNT}/EFI/BOOT
+ rsync -rlptD ${ISOMNT}/EFI/BOOT/* ${USBMNT}/EFI/BOOT/
+ mkdir -p ${USBMNT}/boot
+ rsync -rlptD ${ISOMNT}/boot/* ${USBMNT}/boot/
+ # Add more USB WAIT seconds to the initrd:
+ update_initrd ${USBMNT}/boot/initrd.img
+fi
+
+# No longer needed:
+/sbin/umount ${USBMNT}
+/sbin/umount ${EFIMNT}
+
# Unmount/remove stuff:
cleanup
diff --git a/liveinit b/liveinit
index 6912d16..935495a 100755
--- a/liveinit
+++ b/liveinit
@@ -50,6 +50,7 @@ DEBUG=0
INITRD=$(cat /initrd-name)
WAIT=$(cat /wait-for-root)
KEYMAP=$(cat /keymap)
+LUKSVOL=$(cat /luksdev)
INIT=/sbin/init
PATH="/sbin:/bin:/usr/sbin:/usr/bin"
@@ -100,6 +101,10 @@ for ARG in $(cat /proc/cmdline); do
locale=*)
LOCALE=$(echo $ARG | cut -f2 -d=)
;;
+ luksvol=*)
+ # Format: luksvol=file1[:/mountpoint1][,file1[:/mountpoint2],...]
+ LUKSVOL=$(echo $ARG | cut -f2 -d=)
+ ;;
noload=*)
NOLOAD=$(echo $ARG | cut -f2 -d=)
;;
@@ -482,6 +487,57 @@ EOPW
# Copy contents of rootcopy directory (may be empty) to overlay:
cp -af /mnt/media/${LIVEMAIN}/rootcopy/* /mnt/overlay/ 2>/dev/null
+ # Bind any LUKS container into the Live filesystem:
+ if [ ! -z "$LUKSVOL" ]; then
+ # Even without persistence, we need to be able to write to the partition:
+ mount -o remount,rw /mnt/media
+ for luksvol in $(echo $LUKSVOL |tr ',' ' '); do
+ luksfil="$(echo $luksvol |cut -d: -f1)"
+ luksmnt="$(echo $luksvol |cut -d: -f2)"
+ luksnam="$(echo $(basename $luksfil) |tr '.' '_')"
+ if [ "$luksmnt" = "$luksfil" ]; then
+ # No optional mount point specified, so we use the default: /home/
+ luksmnt="/home"
+ fi
+
+ # The losetup of busybox is different from the real losetup - watch out!
+ lodev=$(losetup -f)
+ if [ -z "$lodev" ]; then
+ # We exhausted the available loop devices, so create the block device:
+ for NOD in $(seq 0 64); do
+ if [ ! -b /dev/loop${NOD} ]; then
+ mknod -m660 /dev/loop${NOD} b 7 ${NOD}
+ break
+ fi
+ done
+ lodev=/dev/loop${NOD}
+ elif [ ! -b $lodev ]; then
+ # We exhausted the available loop devices, so create the block device:
+ mknod -m660 $lodev b 7 $(echo $lodev |sed %/dev/loop%%)
+ fi
+ losetup $lodev /mnt/media/$luksfil
+ echo "Unlocking LUKS encrypted container '$luksfil' at mount point '$luksmnt'"
+ cryptsetup luksOpen $lodev $luksnam </dev/tty0 >/dev/tty0 2>&1
+ if [ $? -ne 0 ]; then
+ echo "${INITRD}: Failed to unlock LUKS container '$luksfil'... trouble ahead."
+ fi
+
+ # Create the directory if it does not exist (unlikely):
+ mkdir -p /mnt/overlay/$luksmnt
+
+ # Let Slackware mount the unlocked container:
+ luksfs=$(blkid /dev/mapper/$luksnam |rev |cut -d'"' -f2 |rev)
+ if ! grep -q /dev/mapper/$luksnam /mnt/overlay/etc/fstab ; then
+ echo "/dev/mapper/$luksnam $luksmnt $luksfs defaults 1 1" >> /mnt/overlay/etc/fstab
+ fi
+ # On shutdown, ensure that the container gets locked again:
+ if ! grep -q "$luksnam $luksmnt" /mnt/overlay/etc/crypttab ; then
+ echo "$luksnam $luksmnt" >> /mnt/overlay/etc/crypttab
+ fi
+
+ done
+ fi
+
# --------------------------------------------------------------------- #
# SLACKWARE LIVE - !END! #
# --------------------------------------------------------------------- #
diff --git a/make_slackware_live.sh b/make_slackware_live.sh
index c83623d..0f7a577 100755
--- a/make_slackware_live.sh
+++ b/make_slackware_live.sh
@@ -31,6 +31,7 @@
# - uses overlayfs to bind multiple squashfs modules together
# - you can add your own modules into ./addons/ or ./optional subdirectories.
# - persistence is enabled when writing the ISO to USB stick using iso2usb.sh.
+# - LUKS encrypted homedirectory is optional on USB stick using iso2usb.sh.
#
# -----------------------------------------------------------------------------
@@ -155,8 +156,9 @@ SEQ_MSB="tagfile:a,ap,d,e,f,k,l,n,t,tcl,x,xap,xfce,y pkglist:slackextra,mate loc
# - each will become a squashfs module:
SEQ_CIN="tagfile:a,ap,d,e,f,k,l,n,t,tcl,x,xap,xfce,y pkglist:slackextra,cinnamon local:slackpkg+"
-# List of kernel modules required for a live medium to boot properly:
-KMODS=${KMODS:-"squashfs:overlay:loop:xhci-pci:ehci-pci:uhci_hcd:usb-storage:hid:usbhid:hid_generic:jbd:mbcache:ext3:ext4:isofs:fat:nls_cp437:nls_iso8859-1:msdos:vfat"}
+# List of kernel modules required for a live medium to boot properly;
+# Lots of HID modules added to support keyboard input for LUKS password entry:
+KMODS=${KMODS:-"squashfs:overlay:loop:xhci-pci:ohci-pci:ehci-pci:xhci-hcd:uhci-hcd:ehci-hcd:usb-storage:hid:usbhid:hid-generic:hid-cherry:hid-logitech:hid-logitech-dj:hid-logitech-hidpp:hid-lenovo:hid-microsoft:jbd:mbcache:ext3:ext4:isofs:fat:nls_cp437:nls_iso8859-1:msdos:vfat"}
# What compression to use for the squashfs modules?
# Default is xz, alternatives are gzip, lzma, lzo:
@@ -1330,13 +1332,14 @@ KVER=$(ls --indicator-style=none ${LIVE_ROOTDIR}/lib/modules/ |head -1)
# Create an initrd for the generic kernel, using a modified init script:
echo "-- Creating initrd for kernel-generic $KVER ..."
-chroot ${LIVE_ROOTDIR} /sbin/mkinitrd -c -w ${WAIT} -l us -o /boot/initrd_${KVER}.gz -k ${KVER} -m ${KMODS} 1>${DBGOUT} 2>${DBGOUT}
+chroot ${LIVE_ROOTDIR} /sbin/mkinitrd -c -w ${WAIT} -l us -o /boot/initrd_${KVER}.gz -k ${KVER} -m ${KMODS} -L -C dummy 1>${DBGOUT} 2>${DBGOUT}
cat $LIVE_TOOLDIR/liveinit | sed \
-e "s/@LIVEMAIN@/$LIVEMAIN/g" \
-e "s/@MEDIALABEL@/$MEDIALABEL/g" \
-e "s/@PERSISTENCE@/$PERSISTENCE/g" \
-e "s/@DARKSTAR@/$LIVE_HOSTNAME/g" \
> ${LIVE_ROOTDIR}/boot/initrd-tree/init
+cat /dev/null > ${LIVE_ROOTDIR}/boot/initrd-tree/luksdev
chroot ${LIVE_ROOTDIR} /sbin/mkinitrd 1>/dev/null 2>${DBGOUT}
rm -rf ${LIVE_ROOTDIR}/boot/initrd-tree