Results 1 to 1 of 1

Thread: Boot Kali Live from HDD with LUKS and LVM + boot kali from SD Card

  1. #1
    Join Date

    Arrow Boot Kali Live ISO from HDD with LUKS and LVM + boot kali from SD Card

    Disclaimer: this is not a definitive guide, but rather a write-up of my working solution. I'm pretty sure that there will be better and more sophisticated methods/approaches to accomplish this task, so consider this as PoC and therefore don't blame me Moreover I want to to say that I tried to report all sources from which I took useful informations, but of course I lost/forgot some of them in this long journey so I apologize in advance.

    My configuration:

    Host OS: Debian Buster
    BIOS: Legacy mode
    Bootloader: GRUB2

    The story so far...

    I want to launch Kali Live on my laptop but... Two of my 3 USB ports burned out (obviously the USB 3.0 ones) and my laptop doesn't boot from SD-Card. Thus I tried with an USB hub to launch live USB, and attach my wifi dongle(s) but I realized that performances are really bad, so I searched for other ways and I found this article [0] where it argue how to boot iso images from HDD (there is also a section concerning kali live - wow what a luck!). But i know that life is cruel [1] and the guide provided by the article refers to "plain"/simple partition scheme, while I have LUKS+LVM (legacy bios *not* UEFI) ..

    Roughly speaking, the problem is that if I would access to the ISO image that is located on this partition/disk, first I have to open the LUKS partition (and LVM volume). But wait.. Is GRUB2 able to perform this task? Luckily according to [2] it seems to be possible, and it is also possible to manage LVM volumes. So most of our work seems to be done..


    Ok, let's start and take a look to [0] and then to its proposed grub menu entry:

    menuentry 'Kali Linux Live' {
        set isofile="/live/kali-linux-2020.2-live-i386.iso"
        insmod ext2
        insmod loopback
        insmod iso9660      
        loopback loop (hd0,msdos1)$isofile      
        search --no-floppy --fs-uuid --set=root 3b87d941-8ee7-4312-98fc-1f26828d62ab                            
        linux (loop)/live/vmlinuz boot=live fromiso=/dev/sda1/$isofile noconfig=sudo username=root hostname=kalilinux
        initrd (loop)/live/initrd.img
    So following that guide, first of all we have create /live folder in our root partition (see [3] if you want to know why we put iso in /live folder)

    # mkdir /live
    next copy our kali iso to this folder (I renamed it to a simpler name to avoid stupid typo errors)

    # cp ~/Downloads/kali-linux-2020.3-live-amd64.iso /live/kali.iso
    and execute this command to prepare our grub menu entry file:

    # cp /etc/grub.d/40_custom /etc/grub.d/41_kali_live
    Now we should get the UUID of the partition where our iso is located, so i ran the blkid command and, in my case, i got the following output:

    # blkid 
    /dev/sda1: UUID="e45e8ef8-25fe-4805-a4d4-7e649c025731" TYPE="ext2" PARTUUID="96004b47-01"
    /dev/sda5: UUID="87694137-578b-46d9-9fa0-702f2adf2ae0" TYPE="crypto_LUKS" PARTUUID="96004b47-05"
    /dev/mapper/sda5_crypt: UUID="N11Wpn-ljbP-MN1E-Cnt1-syF8-Mc6B-gt01Q2" TYPE="LVM2_member"
    /dev/mapper/asd--vg-root: UUID="998da96f-87df-4a46-985e-2b2dfefae403" TYPE="ext4"

    • /dev/sda1 is my unencrypted boot partition
    • /dev/sda5 is my encrypted partition
    • /dev/mapper/sda5_crypt refers to my dm-crpyt mounted disk
    • /dev/mapper/asd--vg-root refers to my unique LVM partition inside LUKS partition (it's my configuration but can be different if you have /home, /usr etc.. mounted elsewhere)

    Now comes the tricky part Remember that our iso is located in the LUKS+LVM partition, so to mount our iso on the loopback device we first need to open our LUKS partition. According to [2] we have to load this modules in grub menu entry

    • cryptodisk
    • luks

    after loading these modules, we are able to open our crypto partition/disk, so type:

    cryptomount -u UUID_1 (UUID_1 is the UUID of crypto partition  - /dev/sda5 in my case - and has to be stripped out from dash!!!)
    next we define two variables useful to simplify the writing of our grub directives

    • isofile: define the full ISO image path on our partiton
    • vmpart: define our LVM partition where ISO image file is located (we have to adopt grub naming convention [4] to identify the device/parition, so we have lvm/PART_NAME. You can see this name by issuing these commands on grub console:

    insmod cryptodisk
    insmod luks
    insmod lvm
    cryptomount -u UUID_1
    ls <--- this will show you also the lvm partition/disk
    or in a simpler way we'll always have 'lvm/' string and the PART_NAME is the lvm parition name - see previous blkid command)

    Next we have to load other useful modules (part_msdos, ext2, lvm, loopback, iso9660) and define our root variable by executing this command:

    search -u UUID_2 --no-floppy --set=root --hint=${lvmpart} (where UUID2 is the UUID of lvm partition - here with dash..)
    Next mount our iso

    loopback loop0 $isofile
    and finally we can load our kernel and initrd image. But wait. Again. We first need to open our LUKS partition because the rootfs of the live (that is in the iso image file) is located there, so we need to tell the kernel (better, initrd) how to accomplish this task. After many days spent on searching on the internet and trying all more creative proposed solutions (obviously none of them worked ), I decided to extract initrd image and take a look to the scripts inside it (See the section below for details) and there I finally found the magical parameter to pass to the kernel that i need [5].

    So the resulting kernel line will be:

    linux (loop0)/live/vmlinuz boot=live cryptopts=target=CRYPTO_DEVICE,source=UUID=UUID_1,key=none,luks,discard live-media=LVM_PARTITION findiso=live/kali.iso
    and at the end we can load the initrd image

    initrd (loop0)/live/initrd.img
    The resulting grub menu entry file will be:

    exec tail -n +3 $0
    # This file provides an easy way to add custom menu entries.  Simply type the
    # menu entries you want to add after this comment.  Be careful not to change
    # the 'exec tail' line above.
    menuentry "Kali live" {
        insmod cryptodisk
        insmod luks
        # UUID_1 without dash!!
        cryptomount -u UUID_1
        set isofile="/live/kali.iso"
        set lvmpart='lvm/asd--vg-root'
        insmod part_msdos
        insmod ext2
        insmod lvm
        insmod loopback
        insmod iso9660
        search -u UUID_2 --no-floppy --set=root --hint=${lvmpart}
        loopback loop0 $isofile
        linux (loop0)/live/vmlinuz boot=live cryptopts=target=CRYPTO_DEVICE,source=UUID=UUID_1,key=none,luks,discard live-media=LVM_PARTITION findiso=live/kali.iso components
        initrd (loop0)/live/initrd.img
    As you can see there are some values that have to be defined and that are specific to your configuration

    • CRYPTO_DEVICE = /dev/sda5_crypt
    • UUID_1 = UUID of crypto_LUKS parition (/dev/sda5)
    • UUID_2 = UUID of LVM parition (/dev/mapper/asd--vg-root)
    • LVM_PARTITION = /dev/mapper/asd--vg-root

    The flag "components" was found in grub.cfg of live iso grub menu entry.

    Done! Now run update-grub, reboot and enjoy your kali live.

    Thanks to int80h for the review , lordzen to listen my continuous computer delusions and Crash for help and politeness in IRC channel.

    initramfs inspection

    In this section I'm going to explain how I found the cryptopts params needed to passed to kernel to open LUKS partition with initrd (I know that now all Debian/Linux/kernel developers will hate me, but try to restrain yourselves from blame me )
    As I said before i extracted the initdrd image file and inspected the scripts inside.

    First of all we need to create some temp folders to mount and unpack all our needed resources.

    # mkdir /tmp/kali-initrd # this folder will contain the kali initrd image 
    # mkdir /tmp/kali-iso # in this folder we mount the iso of kali live
    Next, we mount our iso

    # mount -o loop /live/kali.iso /tmp/kali-iso
    and copy the kali initrd image in our initrd folder and then umount our iso

    # cp /tmp/kali-iso/live/initrd.img-5.7.0-kali1-amd64 /tmp/kali-initrd
    # umount /tmp/kali-iso
    According to [6] let's check our initrd image file

    # cd /tmp/kali-initrd
    # file -L initrd.img-5.7.0-kali1-amd64
    it turns out thath it's a ASCII cpio archive (SVR4 with no CRC), so the initrd image has microcode prepended and we need to extract it

    # cpio -i < ./initrd.img-5.7.0-kali1-amd64
    5862 blocks
    As we can see from command output now we have to skip 5862 blocks from initrd image file to get our basic initrd
    # dd if=initrd.img-5.7.0-kali1-amd64 of=initrd.img bs=512 skip=5862
    Again check our (new) initrd file

    # file -L initrd.img
    initrd.img: gzip compressed data, ...
    and now we can finally extract our initrd

    # zcat initrd.img | cpio -i
    Now type 'ls' to see what we have now in our folder

    # ls
    bin  conf  cryptroot  etc  init  initrd.img  initrd.img-5.7.0-kali1-amd64  kernel  lib  lib32  lib64  libx32  run  sbin  scripts  usr  var
    As you can see there is a cryptoroot folder with a crypttab file inside (according to [7]). Let's look into this file to see its content
    # cat cryptroot/crypttab
    Obviously this file is empty and this is the reason why the initrd doesn't know how mount our "root" partition (the LUKS partition where our iso is located). So let's look inside scripts folder and we can see that there are many files/dirs. In particular let's look to 'scripts/local-top/cryptroot' file. From line 176 you can see kernel boot arguments section

    # Do we have any kernel boot arguments?
    if ! grep -qE '^(.*\s)?cryptopts=' /proc/cmdline; then
        # ensure $TABFILE exists and has a mtime greater than the boot time
        # (existing $TABFILE is preserved)
        touch -- "$TABFILE"
        # let the read builtin unescape the '\' as GRUB substitutes '\' by '\\' in the cmdline
        tr ' ' '\n' </proc/cmdline | sed -n 's/^cryptopts=//p' | while IFS= read cryptopts; do
            # skip empty values (which can be used to disable the initramfs
            # scripts for a particular boot, cf. #873840)
            [ -n "$cryptopts" ] || continue
            unset -v target source key options
            for x in $cryptopts; do
                case "$x" in
                    target=*) target="${x#target=}";;
                    source=*) source="${x#source=}";;
                    key=*) key="${x#key=}";;
                    *) options="${options+$options,}$x";;
    so according to [5] we have to pass to kernel these parameters finding the UUID of our crypto partition/disk as described in previous section and we are ready to create our custom menu entry.

    Bonus track (boot from SD CARD)

    In a very short moment of despair I gave up with open LUKS partition but I find a quick way to boot from SD Card.
    First, flash the iso to your SD Card (oh, really?).
    Next, copy vmlinuz and initrd files from your mounted live iso to your unencrypted /boot parition (they are located in "live" folder; I renamed it in vmliunz-kali and initrd-kali.img).
    Now, supposing your boot partition following grub naming convention [4] is in (hd0, msdos1), write this menu entry:
    menuentry "Kali live SD CARD" {
        insmod part_msdos
        insmod ext2
        linux (hd0,msdos1)/vmlinuz-kali boot=live live-media=/dev/mmcblk0p1 components
        initrd (hd0,msdos1)/initrd-kali.img

    [0] -
    [1] -
    [2] -
    [3] -
    [4] -
    [5] - https://cryptsetup-team.pages.debian...-boot-argument
    [6] -
    [7] -

    Other useful (for me) links:
    Last edited by BannyPepper; 2020-10-26 at 08:18.

Similar Threads

  1. Installing Kali with luks and /boot in encrypted lvm
    By skepticnerdguy in forum Installing Archive
    Replies: 2
    Last Post: 2019-06-01, 11:28
  2. Problem mounting sd card with luks-key during boot
    By hannes in forum TroubleShooting Archive
    Replies: 0
    Last Post: 2014-03-10, 13:21

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts