Debian – How to create a Debian live USB with persistence

debianlive-usbpersistence

I would like to use Debian wherever I go by installing it on a USB flash drive, but I'm not sure how to make it save the settings and be able to install/update packages without loosing them on reboots.

So I downloaded a Hybrid ISO image from this link, and I followed the instructions in the FAQ:

dd if=image.iso of=/dev/sdb bs=4M; sync

This command copied the image to the flash drive by creating a partition which size is the same as the ISO image (1.3 GB out of 8GB), and the rest of the flash drive is unallocated.

I searched on how to do this, but every tutorial uses a different approach and some of them are outdated and talk about the old usb-hdd image.

So how should I install this hybrid image on the flash drive ?

How should I partition my flash drive to be able to install packages and save settings ? and how can I install this image without using dd ?

Best Answer

Debian live with persistence.

  1. First try with official image from www.debian.org/CD/live/

    From SE site (standard live):

    wget https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/debian-live-10.0.0-amd64-standard.iso
    

    From automatic mirror selection (mate live):

    wget http://debian-cd.debian.net/debian-cd/10.0.0-live/amd64/iso-hybrid/debian-live-10.0.0-amd64-mate.iso
    

    Then checksum you download file with https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/SHA256SUMS...

    Ok ISO filesystem is read-only, but there is a little workaround: we could replace non vital bootparam by persistence in this way.

    • Once file validated !
    • you could alter them by using sed for replacing strings in binary.

      LANG=C sed 's/splash quiet/persistence /;s/quiet splash/persistence /' \
          </tmp/debian-live-10.0.0-amd64-mate.iso \
          >/tmp/debian-live-10.0.0-amd64-mate-persist.iso
      

    This will create a modified copy of your live binary file, by strictly replacing splash quiet or quiet splash by persistence, everywhere. Ok this will work only while grub boot command do contain this two words together.

    But care to not miss the space after persistence:

    "splash quiet" -> 12 characters
    "persistence " -> 12 characters
    

    Or your binary will be broken.

  2. Install on USB key

    dd if=debian-live-10.0.0-amd64-standard-persist.iso of=/dev/sdX
    

    Then add your third partition for persistence:

    fdisk /dev/sdX
    n           # new partition
    p           # primary
    <Return>    # default: 3
    <Return>    # default: next free sector
    <Return>    # default: last addressable sector
    w           # write and quit
    

    This could be run without interaction:

    fdisk /dev/sdX <<<$'n\np\n\n\n\nw'
    

    Format and prepare persistence with union:

    mkfs.ext4 -L persistence /dev/sdX3
    mount /dev/sdX3 /mnt
    echo '/ union' >/mnt/persistence.conf
    sync
    umount /mnt
    

    Then eject and try!

    If you use official, unmodified image, for using persistence, you have to interrupt boot selection:

    Once menu screen is displayed, choose your boot option, then instead of Return, hit Tab.

    The kernel commandline will be displayed, then add persistence with a space, after last word (quiet), then hit Return.

    Unfortunately, as 1st partition is bundled with UEFI and is ISO, you can't modify the boot command.

Customized Debian live with persistence

You just have to add persistence to boot command line, but nothing else!? There is a way, using FAT and syslinux, but you have a lot of data manipulations. It's long and I find this not so well. I prefer:

  1. Build your own Debian live

    More regular, but a little longer (at least for 1st image),

    Note: All this stuff was done under root user (this must work by using fakeroot, but this is not tested there and today).

    apt install live-build
    

    ... and all recommendations.

    I wrote a little XARGS function for dropping commented lines:

    XARGS() { sed -ne '/#/d;s/ \t//g;H;${x;s/\n/ /g;s/^ //;p}'; }
    

    First setting bootparams, with localisation and arguments for persistence:

    ExtraBootParams=$(XARGS <<eobp
        boot=live
        config
        locales=ed_WT
        keyboard-layouts=ed
        keyboard-variant=wt
        persistence
    eobp
    )
    

    Now your package list:

    PackageList=$(XARGS <<-eopl
        gnome
        gnome-core
        # gnome-full
        # debian-forensics
        debian-installer-launcher
    eopl
    )
    

    Very first step of lb: create initial tree:

    lb config --architectures amd64 -d buster --debian-installer-gui \
        true --archive-areas 'main contrib non-free' \
        --bootappend-live "$ExtraBootParams" 
    

    Now, you have a small tree, you could:

    printf "%s\n" > config/package-lists/standard.list.chroot \
        $Packages $PackageList
    

    Ok, next command will take a loooong time! (Approx 1 hour on my host)

    lb build
    

    If everything's ok, you may find your own Debian live:

    ls -l *.iso
    -rw-r--r--  1 root root 1511817216 sep  7 15:32 live-image-amd64.hybrid.iso
    
  2. Install on USB key (same operation than for downloaded binaries)

    The 'iso-hybrid' image contains two partitions for UEFI and live mixed in a way both EFI and bios could boot on.

    file live-image-amd64.hybrid.iso
    live-image-amd64.hybrid.iso: DOS/MBR boot sector; partition 2 : ID
    =0xef, start-CHS (0x3ff,254,63), end-CHS (0x3ff,254,63), startsect
    or 708, 5696 sectors
    

    You could simply put to your USB Key: (Note: ensure first your USB Key is not mounted!)

    dd if=live-image-amd64.hybrid.iso of=/dev/sdX
    

    Then add your third partition for persistence:

    fdisk /dev/sdX <<<$'n\np\n\n\n\nw'
    

    Format and prepare persistence with union:

    mkfs.ext4 -L persistence /dev/sdX3
    mount /dev/sdX3 /mnt
    echo '/ union' >/mnt/persistence.conf
    sync
    umount /mnt
    

    Eject and try...

Debian live with encrypted persistence

  1. Build your own Debian live, but with encrypted persistence.

    In order to boot with rootfs / on encrypted persistence, you have to add dm-crypt module and related binaries to initrd (initial ram disk) by adding setting CRYPTSETUP=y into an /etc/initramfs-tools/hooks/...

    I wrote a little XARGS function for dropping commented lines:

    XARGS() { sed -ne '/#/d;s/ \t//g;H;${x;s/\n/ /g;s/^ //;p}'; }
    

    First setting bootparams, with localisation and arguments for persistence and cryptsetup:

    ExtraBootParams=$(XARGS <<eobp
        boot=live
        config
        locales=ed_WT
        keyboard-layouts=ed
        keyboard-variant=wt
        persistent=cryptsetup
        persistence-encryption=luks
        persistence
    eobp
    )
    

    Now your package list:

    PackageList=$(XARGS <<-eopl
        gnome
        gnome-core
        # gnome-full
        # debian-forensics
        debian-installer-launcher
    eopl
    )
    

    And your package selection:

    Packages=$(XARGS <<-eopk
        cryptsetup
        cryptsetup-initramfs
        debian-installer-launcher
        firmware-linux-nonfree
        firmware-linux-free
        less
        ssh
    #   openvpn
    #   xtightvncviewer
        gsmartcontrol
        smartmontools
        partclone
        ntfs-3g
        task-gnome-desktop
        user-setup
        sudo
        apt-utils
    eopk
    )
    

    Of course cryptsetup is required! ;-)

    Very first step of lb: create initial tree:

    lb config --architectures amd64 -d buster --debian-installer-gui \
        true --archive-areas 'main contrib non-free' \
        --bootappend-live "$ExtraBootParams" 
    

    Now, you have a small tree, you could:

    printf "%s\n" > config/package-lists/standard.list.chroot \
        $Packages $PackageList
    

    Ok, next two command will take a loooong time! (Approx 40' on my host)

    lb bootstrap ; lb chroot
    

    Now you could add your module and binaries:

    echo dm-crypt >> chroot/etc/initramfs-tools/modules
    
    sed '/CRYPTSETUP=/s/^#//;s/=.*/=y/' -i \
        chroot/etc/cryptsetup-initramfs/conf-hook 
    ln -s ../../cryptsetup-initramfs/conf-hook \
        chroot/etc/initramfs-tools/hooks/cryptsetup
    chroot chroot live-update-initramfs -u
    

    Then run final stage (will take some more lot of time ~25'):

    lb installer ; lb binary
    

    Note: If you read cryptsetup: WARNING: Couldn't determine root device, it's fine! This mean that cryptsetup is installed on your initrd.

    If everything's ok, you may find your own Debian live:

    ls -l *.iso
    -rw-r--r--  1 root root 1511817216 sep  7 15:32 live-image-amd64.hybrid.iso
    
  2. Install on USB key

    The 'iso-hybrid' umage do contain already two partitions for UEFI and live mixed in a way both EFI and BIOS could boot on.

    file live-image-amd64.hybrid.iso
    live-image-amd64.hybrid.iso: DOS/MBR boot sector; partition 2 : ID
    =0xef, start-CHS (0x3ff,254,63), end-CHS (0x3ff,254,63), startsect
    or 708, 5696 sectors
    

    You could simply put to your USB Key: (Note: ensure first your USB Key is not mounted!)

    dd if=live-image-amd64.hybrid.iso of=/dev/sdX
    

    Add new Linux partion by using free space.

    fdisk /dev/sdX <<<$'n\np\n\n\n\nw'
    

    This will create partition 3 using free space on your USB Key.

    Then prepare your crypted partition

    cryptsetup -q luksFormat /dev/sdX3
    

    Enter passphrase

    cryptsetup -q luksOpen /dev/sdX3 persist 
    

    Enter passphrase again

    mkfs.ext4 -L persistence /dev/mapper/persist
    mount /dev/mapper/persist /mnt
    echo '/ union' >/mnt/persistence.conf
    sync
    umount /mnt
    cryptsetup luksClose persist
    

That's all.

eject /dev/sdX
Related Question